簡體   English   中英

java.util.logging-如何強制所有Logger從應用程序的運行時中遵循給定格式? (HSQLDB)

[英]java.util.logging - How to force all Loggers to obey given format from within the app's runtime? (HSQLDB)

在我的應用程序中,我想要一些格式化方法。 為此,我編寫了SingleLineFormatter extends Formatter

現在,我試圖將所有Logger設置為使用它,但無法弄清楚。

        LogManager.getLogManager().readConfiguration((InputStream) configIS);

        Collections.list(LogManager.getLogManager().getLoggerNames()).forEach(
            loggerName -> {
                List<Handler> handlers = Arrays.asList(Logger.getLogger(loggerName).getHandlers());
                System.out.println(" * Logger " + loggerName + ": " + handlers.size());
                handlers.forEach(handler -> System.out.println("   HF: " + handler.getFormatter()));
                //handlers.forEach(handler -> handler.setFormatter(new SingleLineFormatter()));
            }
        );/**/
        log.info("Logging test");

這將讀取配置,並將其應用於找到的所有處理程序。

Oct 02, 2018 10:42:10 PM cz.dynawest.logging.LoggingUtils initLogging
INFO: Log config file not found: #/logging.properties  Using LoggingUtils' default.
 * Logger cz.dynawest.csvcruncher.App: 0
 * Logger global: 0
 * Logger cz.dynawest.logging.LoggingUtils: 0
2018-10-02 22:42:10 INFO cz.dynawest.logging.LoggingUtils initLogging:   Logging test
 * Logger : 2
   HF: cz.dynawest.logging.SingleLineFormatter@34c45dca
   HF: cz.dynawest.logging.SingleLineFormatter@52cc8049

但是,其余的Logger仍然使用配置了它們的任何東西。 可能只是JUL的默認設置。

Oct 02, 2018 10:42:10 PM org.hsqldb.persist.Logger logInfoEvent
INFO: checkpointClose start

我知道我可以在JVM中通過JUL的logging.properties進行管理。
但是我想分發該應用程序,並希望所有日志消息都采用相同的格式。

如何強制所有要發送到JUL的消息使用我的Formatter程序進行Formatter

-Djava.util.logging.config.file=/path/to/app.properties ,但是對於我的特殊情況,這超出了范圍。 (並且無論如何都無法工作。)

更新:似乎第三方日志未通過JUL。 所以問題是-如果是這樣,我該如何配置其他框架?

這是正在加載到LogManager的文件。 有相當多的實驗,所以並非每一個都是正確的。

# Handlers
handlers = java.util.logging.ConsoleHandler java.util.logging.FileHandler

# Console
# The logging of the app actually reacts to this line.
java.util.logging.ConsoleHandler.formatter = cz.dynawest.logging.SingleLineFormatter
#java.util.logging.ConsoleHandler.formatter = cz.dynawest.logging.SimplestFormatter
java.util.logging.ConsoleHandler.level = ALL

# File
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.pattern = app.log
java.util.logging.FileHandler.formatter = cz.dynawest.logging.SingleLineFormatter
java.util.logging.FileHandler.limit = 0
java.util.logging.FileHandler.append = true


# Default global logging level.
.formatter = cz.dynawest.logging.SimplestFormatter
.level = INFO

#global.formatter = cz.dynawest.logging.SimplestFormatter
#root.formatter = cz.dynawest.logging.SimplestFormatter
#cz.dynawest.csvcruncher.App.formatter = cz.dynawest.logging.SimplestFormatter
#cz.dynawest.csvcruncher.App.handlers = java.util.logging.ConsoleHandler
#.useParentHandlers = false

# Various customizations.

org.apache.commons.beanutils.converters.level=INFO

在我的應用程序中,我想要一些格式化方法。 為此,我編寫了> SingleLineFormatter擴展Formatter

從JDK 7開始, java.util.logging.SimpleFormatter支持單行格式

這將讀取配置,並將其應用於找到的所有處理程序。

JUL僅在代碼要求記錄器時才加載處理程序。 因此可能會錯過處理程序,因為尚未創建記錄器。

如何強制使用格式化程序格式化所有發送到JUL的消息?

有-Djava.util.logging.config.file = / path / to / app.properties,但是對於我的特殊情況,這超出了范圍。 (並且無論如何都無法工作。)

您已經在訪問LogManager,因此可以通過Java設置屬性,如下所示:

 private static void loadProperties() {
    Properties props = new Properties();
    props.put("java.util.logging.ConsoleHandler.formatter", "cz.dynawest.logging.SingleLineFormatter");
    props.put("org.apache.commons.beanutils.converters.level", "INFO");

    try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
        props.store(out, "");
        LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray()));
    } catch (IOException ioe) {
        throw new AssertionError(ioe);
    }
}

如果運行的是JDK 9或更高版本,則應改用LogManager.updateConfiguration(java.util.function.Function)

看來第三方日志記錄沒有通過JUL。 所以問題是-如果是這樣,我該如何配置其他框架?

您必須確定這些框架是否相互路由。 您只需要更改將記錄發布到輸出源的框架的格式。

為了嘗試符合lib希望我用於記錄的內容,我切換到SLF4J和Logback。 沒幫助

因此,我研究了導致記錄問題的特定庫-HSQLDB。

問題在於它做了一些嘗試來掌握所有通用框架,而繞開了我在外部對其進行配置的嘗試。 這是一個示例: FrameworkLogger

然后我在HSQLDB手冊中找到了:

HyperSQL還支持log4J和JDK日志記錄。 傳遞給內部日志的事件信息也傳遞給外部日志框架。 這些框架通常是在HyperSQL外部配置的。 日志消息包含字符串“ hsqldb.db”。 后跟生成消息的數據庫的唯一ID(16個字符串),因此可以在多數據庫服務器上下文中標識它們。

由於默認的JDK日志記錄框架有幾個缺點,因此HyperSQL配置此日志記錄框架以實現更好的操作。 如果您不希望HyperSQL配置JDK日志記錄框架,則應在您的環境中包括系統級屬性hsqldb.reconfig_logging = false。

我嘗試設置hsqldb.db. 記錄儀,但是沒有用。

所以我想我會堅持使用JUL,然后關閉hsqldb.reconfig_logging=false

順便說一下, 這里是對JUL config的一個很好的回顧

一種方法是跨應用程序使用靜態字符串,例如

private static Logger logger = Logger.getLogger("some_value");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM