java.util.logging-如何强制所有Logger从应用程序的运行时中遵循给定格式? (HSQLDB)

时间:2018-10-02 20:47:13

标签: java logging formatting hsqldb java.util.logging

在我的应用中,我想要某种格式。 为此,我写了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进行格式化?

-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

3 个答案:

答案 0 :(得分:1)

  

在我的应用中,我想要某种格式。为此,我编写了> SingleLineFormatter扩展Formatter

自JDK 7起java.util.logging.SimpleFormatter supports a one line format

  

这将读取配置,并将其应用于找到的所有处理程序。

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。所以问题是-如果是这样,我该如何配置其他框架?

您将必须确定框架是否相互路由。您只需要更改将记录发布到输出源的框架的格式。

答案 1 :(得分:0)

为了符合lib希望我使用的日志记录,我切换到SLF4J和Logback。没有帮助。

所以我查看了导致日志记录问题的特定库-HSQLDB。

问题在于它做了一些尝试来掌握所有通用框架,而绕开了我在外部进行配置的尝试。这是一个示例:FrameworkLogger

然后我在HSQLDB manual中找到了

  

HyperSQL还支持log4J和JDK日志记录。传递给内部日志的事件信息也传递给外部日志框架。这些框架通常是在HyperSQL外部配置的。日志消息包含字符串“ hsqldb.db”。然后是生成消息的数据库的唯一ID(16个字符串),因此可以在多数据库服务器上下文中对其进行标识。

     

由于默认的JDK日志记录框架有几个缺点,因此HyperSQL配置此日志记录框架以获得更好的操作。如果您不希望HyperSQL配置JDK日志记录框架,则应在您的环境中包括系统级属性hsqldb.reconfig_logging = false。

我尝试设置hsqldb.db.记录器,但这没用。

所以我想我会坚持使用JUL,然后关闭hsqldb.reconfig_logging=false

顺便说一下,here is a good review of JUL config

答案 2 :(得分:0)

一种方法是跨应用程序(例如,

)使用静态字符串
private static Logger logger = Logger.getLogger("some_value");