• log4j2的使用


    Apache Log4j 2是对Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有:

    • 异常处理,在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
    • 性能提升, log4j2相较于log4j 和logback都具有很明显的性能提升,后面会有官方测试的数据。
    • 自动重载配置,参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用。
    • 无垃圾机制,log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集导致的jvm gc。

    官网: https://logging.apache.org/log4j/2.x/

    1、Log4j2入门

            目前市面上最主流的日志门面就是SLF4J,虽然Log4j2也是日志门面,但是因为它的日志实现功能非常强大,性能优越。所以大家一般还是将Log4j2看作是日志的实现,Slf4j + Log4j2应该是未来的大势所趋。

    • 添加依赖
      1. <dependency>
      2. <groupId>org.apache.logging.log4jgroupId>
      3. <artifactId>log4j-apiartifactId>
      4. <version>2.11.1version>
      5. dependency>
      6. <dependency>
      7. <groupId>org.apache.logging.log4jgroupId>
      8. <artifactId>log4j-coreartifactId>
      9. <version>2.11.1version>
      10. dependency>
    • JAVA代码 
      1. public class log4j2Test {
      2. // 定义日志记录器对象
      3. public static final Logger LOGGER = LogManager.getLogger(log4j2Test.class);
      4. // 快速入门
      5. @Test
      6. public void test() throws Exception {
      7. // 日志消息的输出
      8. LOGGER.fatal("fatal");
      9. LOGGER.error("error");
      10. LOGGER.warn("warn");
      11. LOGGER.info("info");
      12. LOGGER.debug("debug");
      13. LOGGER.trace("trace");
      14. }
      15. }
    • 使用slf4j作为日志的门面,使用log4j2作为日志的实现 
      1. <dependency>
      2. <groupId>org.apache.logging.log4jgroupId>
      3. <artifactId>log4j-apiartifactId>
      4. <version>2.11.1version>
      5. dependency>
      6. <dependency>
      7. <groupId>org.apache.logging.log4jgroupId>
      8. <artifactId>log4j-coreartifactId>
      9. <version>2.11.1version>
      10. dependency>
      11. <dependency>
      12. <groupId>org.slf4jgroupId>
      13. <artifactId>slf4j-apiartifactId>
      14. <version>1.7.25version>
      15. dependency>
      16. <dependency>
      17. <groupId>org.apache.logging.log4jgroupId>
      18. <artifactId>log4j-slf4j-implartifactId>
      19. <version>2.10.0version>
      20. dependency>
    • Java代码
      1. public class Slf4jTest {
      2. public static final Logger LOGGER = LoggerFactory.getLogger(Slf4jTest.class);
      3. // 快速入门
      4. @Test
      5. public void test01()throws Exception{
      6. // 日志输出
      7. LOGGER.error("error");
      8. LOGGER.warn("wring");
      9. LOGGER.info("info");
      10. LOGGER.debug("debug");
      11. LOGGER.trace("trace");
      12. }
      13. }

    2、Log4j2配置

    log4j2默认加载classpath下的 log4j2.xml 文件中的配置。

    1. <Configuration status="debug" monitorInterval="5">
    2. <properties>
    3. <property name="LOG_HOME">src/main/resources/logsproperty>
    4. properties>
    5. <Appenders>
    6. <Console name="Console" target="SYSTEM_OUT">
    7. <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n"/>
    8. Console>
    9. <File name="file" fileName="${LOG_HOME}/myfile.log">
    10. <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l%c{36} - %m%n"/>
    11. File>
    12. <ASync name="Async">
    13. <AppenderRef ref="file"/>
    14. ASync>
    15. <RandomAccessFile name="accessFile" fileName="${LOG_HOME}/myAcclog.log">
    16. <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l%c{36} - %m%n"/>
    17. RandomAccessFile>
    18. <RollingFile name="rollingFile" fileName="${LOG_HOME}/myrollog.log"
    19. filePattern="D:/logs/$${date:yyyy-MM-dd}/myrollog-%d{yyyy-MM-dd-HH-mm}-%i.log">
    20. <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
    21. <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l%c{36} - %msg%n"/>
    22. <Policies>
    23. <OnStartupTriggeringPolicy/>
    24. <SizeBasedTriggeringPolicy size="10 MB"/>
    25. <TimeBasedTriggeringPolicy/>
    26. Policies>
    27. <DefaultRolloverStrategy max="30"/>
    28. RollingFile>
    29. Appenders>
    30. <Loggers>
    31. <AsyncLogger name="com.itheima" level="trace" includeLocation="false" additivity="false">
    32. <AppenderRef ref="Console"/>
    33. AsyncLogger>
    34. <Root level="trace">
    35. <AppenderRef ref="Console"/>
    36. <AppenderRef ref="Async"/>
    37. Root>
    38. Loggers>
    39. Configuration>

    注:这是全部配置方式,可根据自己项目的需要,选择合适的log输出方式。

    3、Log4j2异步日志

    异步日志

            log4j2最大的特点就是异步日志,其性能的提升主要也是从异步日志中受益,我们来看看如何使用log4j2的异步日志。

    同步日志

    异步日志 

    Log4j2提供了两种实现日志的方式,一个是通过AsyncAppender,一个是通过AsyncLogger,分别对应前面我们说的Appender组件和Logger组件。 

    注意:配置异步日志需要添加依赖

    1. <dependency>
    2. <groupId>com.lmaxgroupId>
    3. <artifactId>disruptorartifactId>
    4. <version>3.3.4version>
    5. dependency>

    AsyncAppender方式

    1. <Configuration status="warn">
    2. <properties>
    3. <property name="LOG_HOME">D:/logsproperty>
    4. properties>
    5. <Appenders>
    6. <File name="file" fileName="${LOG_HOME}/myfile.log">
    7. <PatternLayout>
    8. <Pattern>%d %p %c{1.} [%t] %m%nPattern>
    9. PatternLayout>
    10. File>
    11. <Async name="Async">
    12. <AppenderRef ref="file"/>
    13. Async>
    14. Appenders>
    15. <Loggers>
    16. <Root level="error">
    17. <AppenderRef ref="Async"/>
    18. Root>
    19. Loggers>

    AsyncLogger方式 

            AsyncLogger才是log4j2 的重头戏,也是官方推荐的异步方式。它可以使得调用Logger.log返回的更快。你可以有两种选择:全局异步和混合异步。

    • 全局异步就是,所有的日志都异步的记录,在配置文件上不用做任何改动,只需要添加一个log4j2.component.properties 配置;
      Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
    • 混合异步就是,你可以在应用中同时使用同步日志和异步日志,这使得日志的配置方式更加灵活。
      1. <Configuration status="WARN">
      2. <properties>
      3. <property name="LOG_HOME">D:/logsproperty>
      4. properties>
      5. <Appenders>
      6. <File name="file" fileName="${LOG_HOME}/myfile.log">
      7. <PatternLayout>
      8. <Pattern>%d %p %c{1.} [%t] %m%nPattern>
      9. PatternLayout>
      10. File>
      11. Appenders>
      12. <Loggers>
      13. <AsyncLogger name="com.itheima" level="trace" includeLocation="false" additivity="false">
      14. <AppenderRef ref="file"/>
      15. AsyncLogger>
      16. <Root level="info" includeLocation="true">
      17. <AppenderRef ref="file"/>
      18. Root>
      19. Loggers>
      20. Configuration>

      如上配置: com.itheima 日志是异步的,root日志是同步的。

    使用异步日志需要注意的问题

    1. 如果使用异步日志,AsyncAppender、AsyncLogger和全局日志,不要同时出现。性能会和AsyncAppender一致,降至最低。
    2. 设置includeLocation=false ,打印位置信息会急剧降低异步日志的性能,比同步日志还要慢。

    4、Log4j2的性能

            Log4j2最牛的地方在于异步输出日志时的性能表现,Log4j2在多线程的环境下吞吐量与Log4j和Logback的比较如下图。下图比较中Log4j2有三种模式:1)全局使用异步模式;2)部分Logger采用异步模式;3)异步Appender。可以看出在前两种模式下,Log4j2的性能较之Log4j和Logback有很大的优势。 

    无垃圾记录 

            垃圾收集暂停是延迟峰值的常见原因,并且对于许多系统而言,花费大量精力来控制这些暂停。许多日志库(包括以前版本的Log4j)在稳态日志记录期间分配临时对象,如日志事件对象,字符串,字符数组,字节数组等。这会对垃圾收集器造成压力并增加GC暂停发生的频率。

            从版本2.6开始,默认情况下Log4j以“无垃圾”模式运行,其中重用对象和缓冲区,并且尽可能不分配临时对象。还有一个“低垃圾”模式,它不是完全无垃圾,但不使用ThreadLocal字段。Log4j 2.6中的无垃圾日志记录部分通过重用ThreadLocal字段中的对象来实现,部分通过在将文本转换为字节时重用缓冲区来实现。

    使用Log4j 2.5:内存分配速率809 MB /秒,141个无效集合。

    Log4j 2.6没有分配临时对象:0(零)垃圾回收。 

    有两个单独的系统属性可用于手动控制Log4j用于避免创建临时对象的机制: 

    • log4j2.enableThreadlocals - 如果“true”(非Web应用程序的默认值)对象存储在ThreadLocal字段中并重新使用,否则将为每个日志事件创建新对象。
    • log4j2.enableDirectEncoders - 如果将“true”(默认)日志事件转换为文本,则将此文本转换为字节而不创建临时对象。注意: 由于共享缓冲区上的同步,在此模式下多线程应用程序的同步日志记录性能可能更差。如果您的应用程序是多线程的并且日志记录性能很重要,请考虑使用异步记录器。
  • 相关阅读:
    牛客网刷题记录 || 链表
    Codeforces Round #835 (Div. 4)
    NFS:使用 Ansible 自动化配置 NFS 客户端服务端
    力扣第 365 场周赛虚拟参赛
    【CSS】基础使用,层级关系,选择器
    Python调用域控
    [附源码]Java计算机毕业设计SSM动漫下载网站
    webpack proxy如何解决跨域?
    微信小程序 java家庭个人收支理财记账本springboot
    SAP MRP中的滚动提前期简介(MRP自动删除已固定计划订单)
  • 原文地址:https://blog.csdn.net/weixin_52851967/article/details/126081589