zoukankan      html  css  js  c++  java
  • 【从零单排】详解 Log4j + Slf4j 等日志框架(番外)

    日志框架的上,下两篇把大部分的内容都涵盖了,有些额外的小知识点(但是同样十分重要),放到这里来说。

    知识点1:Log4j Properties File 配置详解

    关于Logger

    一般来说,一定(最好)要配一个 rootLogger ,告诉 log4j 默认情况下的 logger 的配置情况。

    # 第一个参数是日志级别,后面可以跟多个 logger
    log4j.rootLogger = INFO, stdout, testlog1, testlog2
    

    另外,还可以在 package / class 级别,设置 logger 。

    # 设置一个名为 testlog 的 logger ,只输出 com.my.app 下的内容
    log4j.logger.com.my.app = INFO, testlog
    # 设置该 logger 不再输出到 root logger 中
    log4j.additivity.com.my.app = false
    
    # 设置 rootLogger/logger 的日志级别,且只针对 com.my.app 下的内容
    log4j.logger.com.my.app = INFO
    

    这两招配合使用,可以控制日志灵活地输出。

    举个例子,我改了某个类,新加了很多 DEBUG log,跑 Integration Test 的时候会输出大量 DEBUG 用于分析。但是我不想污染主 log 文件。咋办?

    改动如下:main 是原来的配置,不去动它,新增 temp 部分,这样,所有 com.my.app.Log4jApp 的 DEBUG log 会单独输出到一个文件,不会污染主 log 文件。(测完了把新增部分删除即可)

    # main
    log = D:/codebase/LogTestSystem/logdir
    log4j.rootLogger = INFO, testlog
    log4j.appender.testlog=org.apache.log4j.FileAppender
    log4j.appender.testlog.File=${log}/log.out
    log4j.appender.testlog.layout=org.apache.log4j.PatternLayout
    log4j.appender.testlog.layout.conversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] - [%c] %m%n
    
    # temp
    log4j.logger.com.my.app.Log4jApp = Debug, testlogNew
    log4j.additivity.com.my.app.Log4jApp = false
    log4j.appender.testlogNew=org.apache.log4j.FileAppender
    log4j.appender.testlogNew.File=${log}/log3.out
    log4j.appender.testlogNew.layout=org.apache.log4j.PatternLayout
    log4j.appender.testlogNew.layout.conversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] - [%c] %m%n
    

    关于Layout

    格式如下:

    %c 输出日志信息所属的类的全名
    %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
    %l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
    %m 输出代码中指定的信息,如log(message)中的message
    %n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
    %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推
    %r 输出自应用启动到输出该日志信息所耗费的毫秒数
    %t 输出产生该日志事件的线程名
    

    一个常见的配置如下:

    log4j.appender.testlog.layout.conversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] - [%c] %m%n
    

    输出如下:

    2021-04-24 15:16:21 [ main:0 ] - [ INFO ] - [Log4jModule2] hello world
    

    (详细见参考1,参考3)

    知识点2:对 Log4j Properties File 文件重命名

    实际使用中,为了区分不同环境,可能的 log4j.properties 文件集合如下:

    log4j_alice_personal.properties
    log4j_stg.properties
    log4j_uat.properties
    log4j_prd.properties
    

    那么怎么使之生效呢?可以在启动参数中做如下配置:

    java -Dlog4j.configuration=file:/some_path/log4j_stg.properties MyApp
    

    (详细见参考4)

    知识点3:Apache Commons Logging 的兼容性问题

    如果项目中或依赖的包中使用了JCL,那么需要注意兼容性。
    一般最容易报的错是 JCL 无法正确地根据配置文件创建对应的 Logger 。

    99%的情况,这是由于pom.xmlxxx.properties/xxx.xml冲突导致的。

    所以,我们需要理解 JCL 是如何创建 Logger 的,我简单总结如下:

    1. 优先选用环境变量 org.apache.commons.logging.Log / org.apache.commons.logging.LogFactory 指定的 Logger
    2. 其次是 Log4j
    3. 然后是 JDK Logging
    4. 最后是 Simple Log

    第一步中,这个环境变量,一种方式是通过 commons-logging.properties 配置,如下:

    org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
    org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
    org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
    

    另外,也有可能,在某些 jar 包中,会自己设置。比如,log4j-jcl:2.11.1中,显示地设置了

    org.apache.common.logging.LogFactory = org.apache.logging.log4j.jcl.LogFactoryImpl
    

    LOG

    这就导致了,只要我引用了log4j-jcl:2.11.1这个包,JCL 一定会初始化一个 Log4j2 的 Logger !如果找不到就报错。(如果你问我是咋知道的?踩坑踩出来的呗...)

    (详细见参考2)

    参考

  • 相关阅读:
    python把汉字转换成拼音实现程序
    C#第三方zip解压压缩工具,带事例源码
    实现在线压缩文件的实现程序代码
    如何处理JSON中的特殊字符
    《汉字简体、繁体相互转换》 查看源代码
    中文字符转拼音源码
    upper_bound()函数使用方法
    CodeFroces New Assignment 二分图匹配
    选拔赛 hash 字符串匹配 哈希算法(白书p374)
    lower_bound()函数使用
  • 原文地址:https://www.cnblogs.com/maxstack/p/14698475.html
Copyright © 2011-2022 走看看