Java 日志处理框架

日志生态

在 Java 生态体系中。关于日志输出,主 要有两类工具。

  • 一类是日志框架,主要用来进行日志的输出的,比如输出到哪个文件,日志格式 如何等。
  • 另外一类是日志门面,主要一套通用的 API,用来屏蔽各个日志框架之间的 差异的。

image.png

用途

  • 线上问题追踪,
  • 错误排查,
  • 基于 日志的业务逻辑统计分析等都离不日志

    日志规约

    日志API的使用

    【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架(SLF4J、JCL—Jakarta Commons Logging)中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

说明:日志框架(SLF4J、JCL—Jakarta Commons Logging)的使用方式(推荐使用 SLF4J)
使用 SLF4J:

所以,对于 Java 工程师来说,关于日志工具的使用,最佳实践就是在应用中使 用如 Log4j + SLF4J 这样的组合来进行日志输出。
这样做的最大好处,就是业务层的开发不需要关心底层日志框架的实现及细节, 在编码的时候也不需要考虑日后更换框架所带来的成本。这也是门面模式所带来的 好处。
综上,请不要在你的 Java 代码中出现任何 Log4j 等日志框架的 API 的使用,而 是应该直接使用 SLF4J 这种日志门面。

  1. import org.slf4j.Logger;
  2. import org.slf4j.LoggerFactory;
  3. private static final Logger logger = LoggerFactory.getLogger(Test.class);
  4. 使用 JCL
  5. import org.apache.commons.logging.Log;
  6. import org.apache.commons.logging.LogFactory;
  7. private static final Log log = LogFactory.getLog(Test.class);

其他注意事项

项目上线之前需要把所有I/O操作(输出语句、日志输出、e.printstacktrace)关闭

Log4j日志框架

Log4j 的日志级别

在 Log4j 中建议只使用 DEBUG、INFO、WARN、ERROR 四个日志级别。

  • DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打 印一些运行信息。
  • INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重 要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避 免打印过多的日志。
  • WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一 些提示。
  • ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息, 如果不想输出太多的日志,可以使用这个级别。

    Log4j2使用

    引入依赖

    1. <!-- 实现对 SLF4J + Log4j2 的依赖的引入 -->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-log4j2</artifactId>
    5. </dependency>
    (最美天气)引入依赖
    1. <!-- log4j 新版本依赖 start-->
    2. <dependency>
    3. <groupId>org.apache.logging.log4j</groupId>
    4. <artifactId>log4j-api</artifactId>
    5. <version>2.17.0</version>
    6. </dependency>
    7. <dependency>
    8. <groupId>org.apache.logging.log4j</groupId>
    9. <artifactId>log4j-core</artifactId>
    10. <version>2.17.0</version>
    11. </dependency>
    12. <!--不加下面这个依赖mybatis sql日志打印有问题-->
    13. <dependency>
    14. <groupId>org.apache.logging.log4j</groupId>
    15. <artifactId>log4j-slf4j-impl</artifactId>
    16. <version>2.17.0</version>
    17. <scope>compile</scope>
    18. </dependency>
    19. <!-- 去除 SpringBoot自带Log -->
    20. <dependency>
    21. <groupId>org.springframework.boot</groupId>
    22. <artifactId>spring-boot-starter</artifactId>
    23. <exclusions>
    24. <exclusion>
    25. <groupId>org.springframework.boot</groupId>
    26. <artifactId>spring-boot-starter-logging</artifactId>
    27. </exclusion>
    28. </exclusions>
    29. </dependency>
    30. <!-- log4j 新版本依赖 end-->

    resoutces目录下新建log4j2.xml文件

    官方配置文档
    配置文件节点解析 
    比较完整的log4j2.xml ```xml <?xml version=”1.0” encoding=”UTF-8”?>
  1. <!--先定义所有的appender-->
  2. <appenders>
  3. <!--console节点:输出控制台的配置,
  4. name:指定appender节点名称
  5. target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.
  6. PatternLayout:输出格式,不设置默认为:%m%n.-->
  7. <console name="Console" target="SYSTEM_OUT">
  8. <!--输出日志的格式-->
  9. <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
  10. </console>
  11. <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
  12. <!--File节点用来定义输出到指定位置的文件的Appender.

        name:指定Appender的名字.         fileName:指定输出日志的目的文件带全路径的文件名.         PatternLayout:输出格式,不设置默认为:%m%n.—>

  1. <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
  2. <!--RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender.

        name:指定Appender的名字.         fileName:指定输出日志的目的文件带全路径的文件名.         PatternLayout:输出格式,不设置默认为:%m%n.         filePattern:指定新建日志文件的名称格式.         Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.         TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am…而不是7am.         SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.         DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。—>

  1. <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
  2. filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
  3. <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
  4. <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
  5. <Policies>
  6. <TimeBasedTriggeringPolicy/>
  7. <SizeBasedTriggeringPolicy size="100 MB"/>
  8. </Policies>
  9. <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
  10. <DefaultRolloverStrategy max="20"/>
  11. </RollingFile>
  12. <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
  13. filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
  14. <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
  15. <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
  16. <Policies>
  17. <TimeBasedTriggeringPolicy/>
  18. <SizeBasedTriggeringPolicy size="100 MB"/>
  19. </Policies>
  20. </RollingFile>
  21. </appenders>
  22. <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
  23. <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

         level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.          name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.          AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity=”false”只在自定义的Appender中进行输出。—>
</configuration

  1. `zmCacheManager:log4j2.xml`配置
  2. ```xml
  3. <?xml version="1.0" encoding="UTF-8"?>
  4. <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
  5. <!-- status log4j2内部日志级别 -->
  6. <configuration status="INFO" monitorInterval="30">
  7. <!-- 全局参数 -->
  8. <Properties>
  9. <Property name="pattern">%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p %c{1}:%L -%m%n</Property>
  10. <Property name="displayName" >zmCacheManager</Property>
  11. </Properties>
  12. <Appenders>
  13. <Console name="console" target="SYSTEM_OUT" follow="true">
  14. <PatternLayout>
  15. <pattern>${pattern}</pattern>
  16. </PatternLayout>
  17. </Console>
  18. <!-- 文件 每次运行程序会自动清空,由append属性决定 -->
  19. <RollingFile name="error" fileName="logs/${displayName}_error.log"
  20. filePattern="logs/${displayName}_error.log.%i">
  21. <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
  22. <Filters>
  23. <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
  24. </Filters>
  25. <PatternLayout>
  26. <pattern>%d %p %c{1} %m%n</pattern>
  27. </PatternLayout>
  28. <Policies>
  29. <OnStartupTriggeringPolicy/>
  30. <SizeBasedTriggeringPolicy size="100 MB"/>
  31. </Policies>
  32. <DefaultRolloverStrategy max="3"/>
  33. </RollingFile>
  34. <!--${sys:catalina.home} 指向tomcat安装目录-->
  35. <!--输出到文件 用来定义超过指定大小自动删除旧的创建新的的Appender.-->
  36. <RollingFile name="RollingInfoFile" fileName="logs/${displayName}_info.log"
  37. filePattern="logs/${displayName}_info.log.%i">
  38. <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
  39. <Filters>
  40. <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
  41. <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
  42. </Filters>
  43. <PatternLayout>
  44. <pattern>%d %p %c{1} %m%n</pattern>
  45. </PatternLayout>
  46. <Policies>
  47. <OnStartupTriggeringPolicy/>
  48. <SizeBasedTriggeringPolicy size="100 MB"/>
  49. </Policies>
  50. <DefaultRolloverStrategy max="3"/>
  51. </RollingFile>
  52. ${sys:catalina.home} 指向tomcat安装目录
  53. 输出到文件 用来定义超过指定大小自动删除旧的创建新的的Appender.
  54. <RollingFile name="debug" fileName="logs/${displayName}_debug.log"
  55. filePattern="logs/${displayName}_debug.log.%i">
  56. <Filters>
  57. <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
  58. </Filters>
  59. <PatternLayout>
  60. <pattern>%d %p %c{1} %m%n</pattern>
  61. </PatternLayout>
  62. <Policies>
  63. <OnStartupTriggeringPolicy/>
  64. <SizeBasedTriggeringPolicy size="=100 MB"/>
  65. </Policies>
  66. <DefaultRolloverStrategy max="3"/>
  67. </RollingFile>
  68. </Appenders>
  69. <Loggers>
  70. <Logger name="org.springframework" level="INFO" />
  71. <Logger name="RollingInfoFile" level="INFO" additivity="false" />
  72. <Logger name="debug" level="DEBUG" additivity="false" />
  73. <Root level="DEBUG">
  74. <AppenderRef ref="console"/>
  75. <AppenderRef ref="error"/>
  76. <AppenderRef ref="RollingInfoFile"/>
  77. <AppenderRef ref="debug"/>
  78. </Root>
  79. </Loggers>
  80. </configuration>