首页 > 编程语言 >【Java日志系列】Log4j2日志框架

【Java日志系列】Log4j2日志框架

时间:2024-08-23 10:56:38浏览次数:13  
标签:异步 Java Logback log4j 日志 Log4j2 Log4j

目录

前言

一、Log4j2简介与特征

二、快速入门

 三、SLF4j + Log4j2组合

四、配置文件

五、异步日志

1. AsyncAppender方式

2. AsyncLogger方式

总结


前言

  在当今的软件开发领域中,日志记录是调试、监控和审计应用程序不可或缺的一部分。高效的日志记录不仅能帮助开发者理解程序的运行流程,还能在运行时出现问题时提供重要的线索。Apache Log4j 2 是一款广受欢迎的日志框架,它在 Log4j 1.x 的基础上进行了重大改进,并且相较于其他流行的框架如 Logback 也提供了更多的优化。本文旨在介绍 Log4j 2 的主要特点和如何使用它来增强应用程序的日志能力。

一、Log4j2简介与特征

  Apache Log4j 2 是对Log4j的升级,它比其前身Log4j 1.x 提供了重大改进,并提供了Logback中可用的许多改进,同时秀修复了Logback架构中的一些问题。Log4j2包含如下特征:

  • 性能提升:Log4j2包含基于LMAX Disruptor库的下一代异步记录器。在多线程场景中,异步记录器的吞吐量比Log4j 1.x 和Logback高18倍,延迟低。
  • 自动重新加载配置:与Logback一样,Log4j2可以在修改时自动重新加载其配置。与Logback不同,它会在重新配置发生时不会丢失日志事件。
  • 高级过滤:与Logback一样,Log4j2支持基于Log事件中的上下文数据,标记,正则表达式和其他组件进行过滤。此外,过滤器还可以与记录器进行关联。与Logback不同,Log4j2可以在任何这些情况下使用通用的Filter类。
  • 插件架构:Log4j2使用插件模式配置组件。因此,无需编写代码来创建和配置Appender,Layout,Pattern Converter等。在配置了的情况下,Log4j自动识别插件并使用它们。
  • 无垃圾机制:在稳态日志记录期间,Log4j2在独立应用程序中是无垃圾的,在Web应用程序中是低垃圾。这减少了垃圾收集器的压力,并且可以提供过更好的相应性能。

二、快速入门

  首先,我们需要导入Log4j2的依赖

<!-- log4j2日志门面 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.23.1</version>
</dependency>
<!-- log4j2日志实现 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.23.1</version>
</dependency>

  Log4j2和Log4j提供了相同的日志级别输出,默认为Error级别的打印。快速入门的示例代码打印结果如下图所示:

 三、SLF4j + Log4j2组合

  为了实现SLF4j + Log4j2的组合,我们需要导入SLF4J日志门面的核心依赖以及桥接器,具体如下:

        <!-- slf4j日志门面核心依赖 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- 适配器 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.1</version>
        </dependency>

  在这里,使用适配器后,slf4j门面调用的实际上是log4j2的门面,再由log4j2门面调用log4j2的实现。 测试用例的打印效果如下图所示:

四、配置文件

  Log4j2是参考Logback创作出来的,所以配置文件也是使用xml,Log4j2同样也是加载类路径(resources)下的log4j2.xml文件中的配置。下面是一个简单的控制台输出配置:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
   <Appenders>
       <Console name="consoleAppender" target="SYSTEM_ERR">

       </Console>
   </Appenders>

    <Loggers>
        <Root level="trace">
            <AppenderRef ref="consoleAppender" />
        </Root>
    </Loggers>
</Configuration>

  根标签,所有日志相关信息,都是在根标签中进行配置,<Configuration> status="debug" ></Configuration>。在根标签中,可以加属性status="debug",表示日志框架本身的日志输出级别。monitorInterval="数值"表示自动加载配置文件的间隔时间。

  此外,我们可能需要将日志输出到文件中,或者是根据文件的时间或者大小进行一个滚动,下面是对文件输出的相关配置示例:

 <properties>
       <property name="logDir">log</property>
</properties>

<Appenders>     

       <!-- 配置文件输出 -->
       <File name="fileAppender" fileName="${logDir}/log4j2.log">
           <PatternLayout pattern="%m%n"/>
       </File>

        <!--
        $${date:yyyy-MM-dd}:根据日期当天,创建一个文件夹
        rolling-%d{yyyy-MM-dd}-%i.log:%i表示序号,从0开始,目的是为了让每一份文件名不会重复
        -->
       <RollingFile name="rollingFile" fileName="${logDir}/rolling.log"
        filePattern="${logDir}/$${date:yyyy-MM-dd}/rolling-%d{yyyy-MM-dd}-%i.log">
           <PatternLayout pattern="%m%n"/>
           <Policies>
               <!-- 在系统启动时,触发拆分规则,产生一个日志文件 -->
               <OnStartupTriggeringPolicy />
               <!-- 按照文件的大小进行拆分 -->
               <SizeBasedTriggeringPolicy size="10KB" />
               <!-- 按时间节点进行拆分,拆分规则就是filePattern -->
               <TimeBasedTriggeringPolicy />
           </Policies>
           <!-- 在同一目录下,文件的个数限制,如果超出了设置的数值,则根据时间进行覆盖,新的覆盖旧的规则 -->
           <DefaultRolloverStrategy max="30" />
       </RollingFile>

 </Appenders>

有关文件输出等相关配置,更多的信息可以参考下面这篇博客:

一文搞定Log4j2日志配置文件_log4j2配置文件-CSDN博客 

五、异步日志

  异步日志是Log4j2最大的特色,其性能的提升主要也是从异步日志中受益。Log4j2提供了两种是心啊异步日志的方式,一个是通过AsyncAppender,一个是通过AsyncLogger,分别对应前面我们说的Appender组件和Logger组件。注意这是两种不同的实现方式,在设计和源码上都是不同的体现。

1. AsyncAppender方式

  是通过引用别的Appender来是实现的,当有日志事件到达时,会开启另外一个线程来处理它们,需要注意的是,如果在Appender的时候出现异常,对应用来说是无法感知的。AsyncAppender应该在它引用的Appender之后配置,默认使用java.util.concurrent.ArrayBlockQueue实现而不需要其他外部的类库。当使用此Appender的时候,在多线程的环境下需要注意,阻塞队列容易受到锁争用的影响,这可能会对性能产生影响。这时候,我们应该考虑使用无锁的异步记录器(AsyncLogger)。

  在使用AsyncAppender的时候,我们首先,需要导入异步日志的依赖:

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>4.0.0</version>
</dependency>

  接下来,在我们的Appender标签中,对我们的异步进行一个配置,下面是一个配置的示例:

<Appenders>
    <!-- 配置控制台输出 -->
    <Console name="consoleAppender" target="SYSTEM_ERR">

    </Console>

    <!-- 配置异步日志 -->
    <Async name="myAsync">
        <!-- 将控制台的输出做异步的操作 -->
        <AppenderRef ref="consoleAppender" />
    </Async>

</Appenders>

<Loggers>
    <Root level="trace">
       <AppenderRef ref="myAsync" />
     </Root>
</Loggers>

2. AsyncLogger方式

  AsyncLogger才是Log4j2实现异步最重要的功能体现,也是官方推荐的异步方式。它可以使用调用Logger.log返回的更快。你可以有两种选择:全局异步和混合异步。

  全局异步:所有的日志都异步的记录,在配置文件上不用做任何改动,只需要在resources目录下添加log4j2.component.properties文件,配置如下一行参数即可。

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

  混合异步:你可以在应用中同时使用同步日志和异步日志,这使得日志的配置方式更加灵活。虽然Log4j2提供以一套异常处理机制,可以覆盖大部分的状态,但是还有一小部分的特殊情况是无法完全处理的,比如我们如果是记录审计日志(特殊情况之一),那么官方就推荐使用同步日志的方式,而对于其他的一些仅仅是记录一个程序日志的地方,使用异步日志将大幅提升性能,减少对应用本身的影响。混合异步的方式需要通过修改配置文件来实现,使用AsyncLogger标记配置。混合异步的配置示例:

<Loggers>

   <!--
       includeLocation="false"
       表示去除日志记录中的行号信息,这个行号信息非常的影响日志记录的效率,
       严重的时候可能记录的比同步的日志效率还要低。

       additivity="false"
       表示不继承rootLogger
   -->
        
   <!-- 自定义Logger,让自定义的Logger为异步Logger -->
   <AsyncLogger name="cn.sumou" level="trace"
           includeLocation="false" additivity="false">
         <AppenderRef ref="consoleAppender" />
   </AsyncLogger>

   <Root level="trace">
        <AppenderRef ref="consoleAppender" />
   </Root>
</Loggers>

有关不同的异步日志的性能分析,可以参考这篇博客:log4j2性能分析+原理_log4j2异步日志原理-CSDN博客

总结

  我们展示了如何快速开始使用 Log4j 2,以及如何与 SLF4J 结合使用以实现更灵活的日志管理。此外,文章说明了如何配置日志输出至文件及实现日志滚动。最后,我们探讨了 Log4j 2 中异步日志的不同实现方式,包括 AsyncAppenderAsyncLogger。总之,Apache Log4j 2 是一个强大且高效的日志框架,适合不同规模的应用程序。

标签:异步,Java,Logback,log4j,日志,Log4j2,Log4j
From: https://blog.csdn.net/2301_76244254/article/details/141423410

相关文章

  • Java语法-注释 如何创建与配置空项目
    Java语法注释注释是给人看的,与代码执行无关单行注释//单行注释多行注释/*多行注释*/文档注释(JavaDoc:)/***//***@DscriptionHelloWorld*//****ii.;9ABH,*SA39......
  • OceanBase -clog、日志-查看unit迁移过程中副本数变化
    查看unit迁移过程中副本数变化----------------------------------------------------------------------------------------------------------------------------第一:在副本迁移时候,可以查询以下SQL进行观察(适用2.X/3.X)查看副本数selectcount(*)from__all_virtual_m......
  • Java数据类型转换
    自动类型转化(隐式转换):容量小的数据类型可以自动转换为容量大的数据类型。由低字节向高字节的转换byte->short->char–>int->long->float->double1.整行隐式类型转换:bytenum1=10;intnum2=num1;//byte转换为intshortnum3=1000;intnum4=num3;//short转换......
  • 并发编程[3]_java线程的六种状态
    java线程状态1.操作系统进程的五种状态网上找了一张图:2.java线程的六种状态Thread类中getState()方法可以获取线程的状态,返回值是Thread类中的enum类型,取值有NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED六种状态。java的线程状态将阻塞状态细分为BLOCKED,WAITING......
  • Java查看对象头大小
    添加依赖<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.17</version></dependency>查看对象头大小@Testvoidhe......
  • SpringBoot 用的 spring-jcl 打印日志,与 LoggingSystem 有鸡毛关系?
    开心一刻现实中,我有一个异性游戏好友,昨天我心情不好,找她聊天我:我们两个都好久没有坐下来好好聊天了她:你不是有女朋友吗我:人家不需要我这种穷人啊她:难道我需要吗前情回顾从源码分析SpringBoot的LoggingSystem→它是如何绑定日志组件的从源码的角度讲述了SpringBoot......
  • 第一个Java程序HelloWorld
    编写第一个程序HelloWorld在任意文件夹中创建java文件例如新建一个文本文件(.txt),然后修改文件名和文件扩展名记得打开显示文件扩展名!!!在Notpad++或记事本中打开刚刚创建的java文件(hello.world)编写publicclasshello{ publicstaticvoidmain(String[]args){ System.ou......
  • Java学习笔记8-数据类型
    Java中主要有八种基本数据类型:byte、short、int、long、float、double、boolean、char。各种数据类型作用:1、byte:8位、有符号的以二进制补码表示的整数。min:-128(-2^7)。max:127(2^7-1)。default:0。对应包装类:Byte。2、short:16位、有符号的以二进制补码表示的整......
  • 浅谈Java MyBatis
    一、MyBatis的基本介绍  MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,由谷歌托管,并且改名为MyBatis。2013年11月迁移到Github。    MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。......
  • java+vue计算机毕设美食(风情)展示系统【源码+开题+论文】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着全球化和互联网的飞速发展,人们对美食的追求已不再局限于地域限制,而是跨越国界,渴望体验不同文化背景下的风味佳肴。美食不仅是味蕾的享受,更是文化......