Log配置教程及框架性能比较-高性能日志记录工具Log4j2-《Java笔记》

admin 2025-10-19 03:31:28 编程 来源:ZONE.CI 全球网 0 阅读模式

日志 Log4j 2Log4j 2,顾名思义,它就是 Log4j 的升级版。Log4j、SLF4J、Logback 都出自——Ceki Gulcu,但 Log4j 2 却是例外,它是 Apache 基金会的产品。SLF4J 和 Logback 作为 Log4j 的替代品,在很多方面都做了必要的改进。

1、Log4j 2 的优势

1)在多线程场景下,Log4j 2 的吞吐量比 Logback 高出了 10 倍,延迟降低了几个数量级。来着Log4j 2 官方声明。Log4j 2 的异步 Logger 使用的是无锁数据结构,而 Logback 和 Log4j 的异步 Logger 使用的是 ArrayBlockingQueue。对于阻塞队列,多线程应用程序在尝试使日志事件入队时通常会遇到锁争用。下图说明了多线程方案中无锁数据结构对吞吐量的影响。Log4j 2 随着线程数量的扩展而更好地扩展:具有更多线程的应用程序可以记录更多的日志。其他日志记录库由于存在锁竞争的关系,在记录更多线程时,总吞吐量保持恒定或下降。这意味着使用其他日志记录库,每个单独的线程将能够减少日志记录。高性能日志记录工具 Log4j 2 - 图1性能方面是 Log4j 2 的最大亮点,至于其他方面的一些优势,比如说下面这些,可以忽略不计,文字有多短就代表它有多不重要。2)Log4j 2 可以减少垃圾收集器的压力。3)支持 Lambda 表达式。4)支持自动重载配置。

2、Log4j 2 使用示例

第一步,在 pom.xml 文件中添加 Log4j 2 的依赖:

  1. <dependency>
  2. <groupId>org.apache.logging.log4j</groupId>
  3. <artifactId>log4j-api</artifactId>
  4. <version>2.5</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.logging.log4j</groupId>
  8. <artifactId>log4j-core</artifactId>
  9. <version>2.5</version>
  10. </dependency>

(这个 artifactId 还是 log4j,没有体现出来 2,而在 version 中体现)第二步,最简单的测试用例:

  1. import org.apache.logging.log4j.LogManager;
  2. import org.apache.logging.log4j.Logger;
  3. public class Demo {
  4. private static final Logger logger = LogManager.getLogger(Demo.class);
  5. public static void main(String[] args) {
  6. logger.debug("log4j2");
  7. }
  8. }

运行 Demo 类,可以在控制台看到以下信息:

  1. ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

Log4j 2 没有在控制台打印“ log4j2”,提示没有为它指定配置文件。这对于新手来说,很不友好,因为新手在遇到这种情况的时候,往往不知所措。日志里面虽然体现了 ERROR,但代码并没有编译出错或者运行出错。通过源码,可以看得到,Log4j 2 会去寻找 4 种类型的配置文件,后缀分别是 properties、yaml、json 和 xml。前缀是 log4j2-test 或者 log4j2。得到这个提示后,就可以进行第三步了。第三步,在 resource 目录下增加 log4j2-test.xml 文件(方便和 Logback 做对比),内容如下所示:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Configuration>
  3. <Appenders>
  4. <Console name="Console" target="SYSTEM_OUT">
  5. <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
  6. </Console>
  7. </Appenders>
  8. <Loggers>
  9. <Root level="DEBUG">
  10. <AppenderRef ref="Console"/>
  11. </Root>
  12. </Loggers>
  13. </Configuration>

Log4j 2 的配置文件格式和 Logback 有点相似,基本的结构为 < Configuration> 元素,包含 0 或多个 < Appenders> 元素,其后跟 0 或多个 < Loggers> 元素,里面再跟最多只能存在一个的 < Root> 元素。

1)配置 appender

配置 appender也就是配置日志的输出目的地。有 Console,典型的控制台配置信息上面也看到了,简单解释一下里面 pattern 的格式:

  • %d{HH:mm:ss.SSS} 表示输出到毫秒的时间
  • %t 输出当前线程名称
  • %-5level 输出日志级别,-5 表示左对齐并且固定输出 5 个字符,如果不足在右边补空格
  • %logger 输出 logger 名称,最多 36 个字符
  • %msg 日志文本
  • %n 换行

顺带补充一下其他常用的占位符:

  • %F 输出所在的类文件名,如 Demo.java
  • %L 输出行号
  • %M 输出所在方法名
  • %l 输出语句所在的行数, 包括类名、方法名、文件名、行数
  • %p 输出日志级别
  • %c 输出包名,如果后面跟有 {length.} 参数,比如说 %c{1.},它将输出报名的第一个字符,如 com.itwanger 的实际报名将只输出 c.i

再次运行 Demo 类,就可以在控制台看到打印的日志信息了:

  1. 10:14:04.657 [main] DEBUG com.itwanger.Demo - log4j2

2)配置 Loggers

指定 Root 的日志级别,并且指定具体启用哪一个 Appenders。

3)自动重载配置

Logback 支持自动重载配置,Log4j 2 也支持,那想要启用这个功能也非常简单,只需要在 Configuration 元素上添加 monitorInterval 属性即可。

  1. <Configuration monitorInterval="30">
  2. ...
  3. </Configuration>

注意值要设置成非零,上例中的意思是至少 30 秒后检查配置文件中的更改。最小间隔为 5 秒。

3、Async 示例

除了 Console,还有 Async,可以配合文件的方式来异步写入,典型的配置信息如下所示:

  1. <Configuration>
  2. <Appenders>
  3. <File name="DebugFile" fileName="debug.log">
  4. <PatternLayout>
  5. <Pattern>%d %p %c [%t] %m%n</Pattern>
  6. </PatternLayout>
  7. </File>
  8. <Async name="Async">
  9. <AppenderRef ref="DebugFile"/>
  10. </Async>
  11. </Appenders>
  12. <Loggers>
  13. <Root level="debug">
  14. <AppenderRef ref="Async"/>
  15. </Root>
  16. </Loggers>
  17. </Configuration>

对比 Logback 的配置文件来看,Log4j 2 真的复杂了一些,不太好用,把这个 Async 加入到 Appenders:

  1. <Configuration>
  2. <Appenders>
  3. <Console name="Console" target="SYSTEM_OUT">
  4. <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
  5. </Console>
  6. <File name="DebugFile" fileName="debug.log">
  7. <PatternLayout>
  8. <Pattern>%d %p %c [%t] %m%n</Pattern>
  9. </PatternLayout>
  10. </File>
  11. <Async name="Async">
  12. <AppenderRef ref="DebugFile"/>
  13. </Async>
  14. </Appenders>
  15. <Loggers>
  16. <Root level="DEBUG">
  17. <AppenderRef ref="Console"/>
  18. <AppenderRef ref="Async"/>
  19. </Root>
  20. </Loggers>
  21. </Configuration>

再次运行 Demo 类,可以在项目根路径下看到一个 debug.log 文件,内容如下所示:

  1. 2020-10-30 09:35:49,705 DEBUG com.itwanger.Demo [main] log4j2

4、RollingFile 示例

RollingFile 会根据 Triggering(触发)策略和 Rollover(过渡)策略来进行日志文件滚动。如果没有配置 Rollover,则使用 DefaultRolloverStrategy 来作为 RollingFile 的默认配置。触发策略包含有,基于 cron 表达式(源于希腊语,时间的意思,用来配置定期执行任务的时间格式)的 CronTriggeringPolicy;基于文件大小的 SizeBasedTriggeringPolicy;基于时间的 TimeBasedTriggeringPolicy。过渡策略包含有,默认的过渡策略 DefaultRolloverStrategy,直接写入的 DirectWriteRolloverStrategy。一般情况下,采用默认的过渡策略即可,它已经足够强大。第一个基于 SizeBasedTriggeringPolicy 和 TimeBasedTriggeringPolicy 策略,以及缺省 DefaultRolloverStrategy 策略的配置示例:

  1. <Configuration>
  2. <Appenders>
  3. <RollingFile name="RollingFile" fileName="rolling.log"
  4. filePattern="rolling-%d{yyyy-MM-dd}-%i.log">
  5. <PatternLayout>
  6. <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
  7. </PatternLayout>
  8. <Policies>
  9. <SizeBasedTriggeringPolicy size="1 KB"/>
  10. </Policies>
  11. </RollingFile>
  12. </Appenders>
  13. <Loggers>
  14. <Root level="debug">
  15. <AppenderRef ref="RollingFile"/>
  16. </Root>
  17. </Loggers>
  18. </Configuration>

为了验证文件的滚动策略,调整一下 Demo 类,让它多打印点日志:

  1. for (int i = 1;i < 20; i++) {
  2. logger.debug("Hello World");
  3. }

再次运行 Demo 类,可以看到根目录下多了 3 个日志文件:结合日志文件名,再来看%20RollingFile%20的配置,就很容易理解了。1)fileName%20用来指定文件名。2)filePattern%20用来指定文件名的模式,它取决于过渡策略。由于配置文件中没有显式指定过渡策略,因此%20RollingFile%20会启用默认的%20DefaultRolloverStrategy。先来看一下%20DefaultRolloverStrategy%20的属性:再来看 filePattern 的值 rolling-%d{yyyy-MM-dd}-%i.log,其中 %d{yyyy-MM-dd} 很好理解,就是年月日;其中 %i 是什么意思呢?第一个日志文件名为 rolling.log(最近的日志放在这个里面),第二个文件名除去日期为 rolling-1.log,第二个文件名除去日期为 rolling-2.log,根据这些信息,就能猜到其中的规律。其实和 DefaultRolloverStrategy 中的 max 属性有关,目前使用的默认值,也就是 7,那就当 rolling-8.log 要生成的时候,删除 rolling-1.log。可以调整 Demo 中的日志输出量来进行验证。3)SizeBasedTriggeringPolicy,基于日志文件大小的时间策略,大小以字节为单位,后缀可以是 KB,MB 或 GB,例如 20 MB。再来看一个日志文件压缩的示例,来看配置:

  1. <RollingFile name="RollingFileGZ" fileName="gz/rolling.log"
  2. filePattern="gz/%d{yyyy-MM-dd-HH}-%i.rolling.gz">
  3. <PatternLayout>
  4. <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
  5. </PatternLayout>
  6. <Policies>
  7. <SizeBasedTriggeringPolicy size="1 KB"/>
  8. </Policies>
  9. </RollingFile>
  • fileName 的属性值中包含了一个目录 gz,也就是说日志文件都将放在这个目录下。
  • filePattern 的属性值中增加了一个 gz 的后缀,这就表明日志文件要进行压缩了,还可以是 zip 格式。

运行 Demo 后,可以在 gz 目录下看到以下文件:高性能日志记录工具 Log4j 2 - 图4

以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  11