代码之家  ›  专栏  ›  技术社区  ›  Ondra Žižka David Lilljegren

JAVAutil。日志记录——如何在应用程序运行时强制所有日志记录者遵守给定的格式?(HSQLDB)

  •  1
  • Ondra Žižka David Lilljegren  · 技术社区  · 7 年前

    在我的应用程序中,我想要一些格式化的方法。 为此,我写了一篇文章 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
    

    然而,其余的 记录器 s仍然使用他们配置的任何东西。可能只是JUL的违约。

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

    我知道我能从JUL那里搞定 logging.properties 在我的JVM中。
    但我想发布应用程序,并希望所有日志消息的格式相同。

    我怎样才能强制所有将于7月发送的邮件都使用我的 Formatter ?

    -Djava.util.logging.config.file=/path/to/app.properties 但这超出了我的特殊情况。(而且根本不起作用。)

    更新: 看起来第三方日志记录没有经过7月。所以问题是——如果是这样,我该如何配置其他框架?

    这是要加载到的文件 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
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Community Mohan Dere    6 年前

    在我的应用程序中,我想要一些格式化的方法。为此,我写了一个>SingleLineFormatter扩展了Formatter

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

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

    JUL将仅在代码要求记录器时加载处理程序。因此,可能会错过处理程序,因为记录器本身尚未创建。

    我如何强制所有将于7月发送的邮件使用我的格式化程序进行格式化?

    有-贾瓦。util。登录中。配置。file=/path/to/app。属性,但这超出了我的特殊情况的范围。(而且根本不起作用。)

    您已经在访问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) 相反

    看起来第三方日志记录没有经过7月。所以问题是——如果是这样,我该如何配置其他框架?

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

        2
  •  0
  •   Community Mohan Dere    6 年前

    为了符合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 .

        3
  •  0
  •   double-beep hudson solomon    6 年前

    一种方法是在应用程序中创建一个静态字符串,例如

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