百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

你用了这么久的Log4j2日志框架,真的对它有自己的理解吗?

lipiwang 2024-10-27 13:31 9 浏览 0 评论

作者:蜗牛大师

来源:cnblogs.com/wuqinglong/p/9516529.html

1.日志框架

日志接口(slf4j)

slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback)

日志实现(log4j、logback、log4j2)

  • log4j是apache实现的一个开源日志组件
  • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现
  • log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活。

2.为什么需要日志接口,直接使用具体的实现不就行了吗?

接口用于定制规范,可以有多个实现,使用时是面向接口的(导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用实现,所以可以任意的更换实现而不用更改代码中的日志相关代码。

比如:slf4j定义了一套日志接口,项目中使用的日志框架是logback,开发中调用的所有接口都是slf4j的,不直接使用logback,调用是 自己的工程调用slf4j的接口,slf4j的接口去调用logback的实现,可以看到整个过程应用程序并没有直接使用logback,当项目需要更换更加优秀的日志框架时(如log4j2)只需要引入Log4j2的jar和Log4j2对应的配置文件即可,完全不用更改Java代码中的日志相关的代码logger.info(“xxx”),也不用修改日志相关的类的导入的包(import org.slf4j.Logger; import org.slf4j.LoggerFactory;)

使用日志接口便于更换为其他日志框架

log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用。

本文使用Log4j2作为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.11.0</version>
</dependency>
<dependency>
????<groupId>org.apache.logging.log4j</groupId>
????<artifactId>log4j-core</artifactId>
????<version>2.11.0</version>
</dependency>
<dependency>
????<groupId>org.apache.logging.log4j</groupId>
????<artifactId>log4j-api</artifactId>
????<version>2.11.0</version>
</dependency>

3.log4j2日志级别

从大到小依次是: off, fatal, error, warn, info, debug, trace, all

由于我们使用的是slf4j接口包,该接口包中只提供了未标有删除线的日志级别的输出。

4.log4j2配置文件的优先级

Log4j will inspect the log4j.configurationFile system property and, if set, will attempt to load the configuration using the ConfigurationFactory that matches the file extension.

If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.

If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.

If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.

If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.

If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.

If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the classpath.

If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.

If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.

If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.

5.对于log4j2配置文件的理解

配置文件结构:


6.对于Appender的理解

简单说Appender就是一个管道,定义了日志内容的去向(保存位置)。

配置一个或者多个Filter,Filter的过滤机制和Servlet的Filter有些差别,下文会进行说明。

  • 配置Layout来控制日志信息的输出格式。
  • 配置Policies以控制日志何时(When)进行滚动。
  • 配置Strategy以控制日志如何(How)进行滚动。

7.对于Logger的理解

简单说Logger就是一个路由器,指定类、包中的日志信息流向哪个管道,以及控制他们的流量(日志级别)

8.log4j2配置文件框架

配置文件格式

<?xml?version="1.0"?encoding="UTF-8"?>

<Configuration>

????<Appenders>

????????<Appender>
????????????<Filters>
????????????????<LevelRangeFilter?minLevel="..."?maxLevel="..."?onMatch="..."?onMismatch="..."/>
????????????</Filters>

????????????<PatternLayout?pattern="..."?charset="..."/>

????????????<Policies>
????????????????<CronTriggeringPolicy?schedule="..."/>
????????????????<SizeBasedTriggeringPolicy?size="..."/>
????????????????<TimeBasedTriggeringPolicy?/>
????????????</Policies>
????????</Appender>

????????<Appender>
????????????//?...
????????</Appender>

????</Appenders>

????<Loggers>

????????<Logger>
????????????<AppenderRef?ref="...">
????????</Logger>

????????<Root>
????????????<AppenderRef?ref="...">
????????</Root>

????</Loggers>

</Configuration>

9.Appender标签的实现类

其实这些标签都是类名或者类名去掉后缀。

Appender的常用的实现类有:

  • ConsoleAppender(Console)
  • FileAppender(File)、RandomAccessFileAppender(RandomAccessFile)
  • RollingFileAppender(RollingFile)、RollingRandomAccessFileAppender(RollingRandomAccessFile)

打开这些实现类的源码,你一定会恍然大明白,括号中的是实现类在log4j2.xml配置文件中的标签名。

10.ConsoleAppender(Console)

该实现类会把日志输出到控制台中。

它有两种输出方式:

  • SYSTEM_OUT(System.out)
  • SYSTEM_ERR(System.err)

如果不配置,默认使用SYSTEM_OUT进行输出。括号中是调用的方法。

简单示例:


其它属性可以参见官方文档:

http://logging.apache.org/log4j/2.x/manual/appenders.html#ConsoleAppender

10-1.FileAppender(File)、RandomAccessFileAppender(RandomAccessFile)

相同点:写入日志信息到文件

不同点:使用的I/O实现类不同,前者使用FileOutputStream,后者使用RandomAccessFile。

官方文档说是在bufferedIO=true(默认是true)的情况下后者比前者性能提升20% ~ 200%,不明觉厉,就用后者吧。

简单示例:

常用属性:

  • fileName:来指定文件位置,文件或目录不存在则会自动创建。
  • immediateFlush:是否每次写入都要立刻刷新到硬盘中。默认true,如果使用默认值可能会影响性能。

其它属性可以参见官方文档:

http://logging.apache.org/log4j/2.x/manual/appenders.html#RandomAccessFileAppender

10-2.RollingFileAppender(RollingFile)、RollingRandomAccessFileAppender(RollingRandomAccessFile)

这一对之间的区别与上一对之间的区别是一样的。

上一对的实现类不能进行日志滚动,所谓日志滚动就是当达到设定的条件后,日志文件进行切分。

比如:工程师想让系统中的日志按日进行切分,并且按月归档。

这时候这一对的作用就体现出来了。

简单示例:

1.filePattern:指定了日志滚动之后的文件命名格式,至于其中的{date:hh-mm}表达式下文介绍。

2.DefaultRolloverStrategy:指定了如何(How)进行翻滚,并且指定了最大翻滚次数(影响%i参数值),超过次数之后会按照相应的规则删除旧日志。

3.Policies: 这里就是规定了何时进行滚动(When),可以有多个Policy。

  • CronTriggeringPolicy设置了每 5s 进行一次翻滚
  • SizeBasedTriggeringPolicy设置了的话,如果当前文件超过了10MB,但是文件的名字还没有进行翻滚(建立新文件),那么就会用%i的方式进行翻滚。

10-3.翻滚示例

app.log

第一次翻滚:app.log app.1.log // app.log -> app.1.log
第二次翻滚:app.log app.1.log app.2.lop // app.log -> app.2.log
第三次翻滚:app.log app.1.log app.2.lop app.3.lop // app.log -> app.3.log
第四次翻滚:app.log app.1.log app.2.lop app.3.lop app.4.lop // app.log -> app.4.log

一直到设定的翻滚次数10之后,会把旧的日志内容覆盖。

app.2.lop?->?app.1.lop
app.3.lop?->?app.2.lop
...
app.10.lop?->?app.9.lop
app.log?->?app.10.lop

一直这样循环下去,直到创建新文件。

11.Filters

Filters决定日志事件能否被输出。过滤条件有三个值:ACCEPT(接受),DENY(拒绝),NEUTRAL(中立)。

11-1.常用的Filter实现类有

  • LevelRangeFilter
  • TimeFilter
  • ThresholdFilter

11-2.上文中提到log4j2中的Filter与Servlet中的有差别。那么有什么差别呢?

简单说就是log4j2中的过滤器ACCEPT和DENY之后,后续的过滤器就不会执行了,只有在NEUTRAL的时候才会执行后续的过滤器。

11-3.简单示例

测试代码:

public?class?LogMain?{

????private?static?Logger?logger?=?LoggerFactory.getLogger(LogMain.class);

????public?static?void?main(String[]?args)?throws?Exception?{

????????logger.trace("trace?Msg.");
????????logger.debug("debug?Msg.");
????????logger.info("info?Msg.");
????????logger.warn("warn?Msg.");
????????logger.error("error?Msg.");

????}

}

配置文件:


输出结果:

17:51:53.546?[main]?INFO??me.master.snail.log.LogMain?-?info?Msg.
17:51:53.548?[main]?WARN??me.master.snail.log.LogMain?-?warn?Msg.
17:51:53.548?[main]?ERROR?me.master.snail.log.LogMain?-?error?Msg.

如果当前时间不是 8点~8点半 之间,那么没有日志会输出。

这里的info Msg.、warn Msg.和error Msg.为什么会输出呢?

是因为LevelRangeFilter对它们进行了ACCEPT,而剩下的trace Msg.和debug Msg.则会经过下一个过滤器,然后依次类推。

12.PatternLayout

这是常用的日志格式化类,其它日志格式化类很少用。

关于其它日志类,可以打开PatternLayout类,找到其父类AbstractStringLayout, 看父类的实现类有哪些。

简单示例:

<PatternLayout?pattern="%d{HH:mm:ss.SSS}?[%t]?%-5level?%logger{36}?-?%msg%n"?charset="UTF-8"/>

授人以鱼不如授人以渔。关于pattern的格式点击

http://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout

具体的其它属性可以看源码也可以参考官方文档。

13.Policy & Strategy

上文也说了,Policy是用来控制日志文件何时(When)进行滚动的;Strategy是用来控制日志文件如何(How)进行滚动的。

如果配置的是RollingFile或RollingRandomAccessFile,则必须配置一个Policy。

如果想按月归档,按日切分日志,然后

13-1.Policy常用的实现类:

  • SizeBasedTriggeringPolicy
  • CronTriggeringPolicy
  • TimeBasedTriggeringPolicy

13-1-1.SizeBasedTriggeringPolicy

根据日志文件的大小进行滚动。

<SizeBasedTriggeringPolicy?size="10MB"/>

单位有:KB,MB,GB

13-1-2.CronTriggeringPolicy

使用Cron表达式进行日志滚动,很灵活。

<CronTriggeringPolicy?schedule="0/5?*?*?*?*??"?/>

13-1-3.TimeBasedTriggeringPolicy

这个滚动策略依赖于filePattern中配置的最具体的时间单位,根据最具体的时间单位进行滚动。

这种方式比较简洁。CronTriggeringPolicy策略更强大。

简单示例:


13-2.Strategy常用的实现类

  • DefaultRolloverStrategy
  • DirectWriteRolloverStrategy

这两个Strategy都是控制如何进行日志滚动的,至于他们的区别我还是不太明白,大佬解释一下吧。

平时大部分用DefaultRolloverStrategy就可以了。

14.Logger

Logger部分就比较简单了,分为两个Logger:

  • Root(必须配置)
  • Logger

简单示例:

注意:Logger中也可以加过滤器的哟~

14-1.比较重要的问题: 日志重复打印

如果Root中的日志包含了Logger中的日志信息,并且AppenderRef是一样的配置,则日志会打印两次。

注意:有两个条件

  • Root中的日志包含了Logger中的日志信息
  • 且AppenderRef是一样的配置

这时候我们需要使用一个Logger的属性来解决,那就是additivity,其默认值为true,需要配置为false。

15.Lookups

这个组件类似于JSTL的EL表达式,或者类似于Spring的SpEL表达式。

具体的语法很简单,这里就不粘贴复制了,查看官方文档:

http://logging.apache.org/log4j/2.x/manual/lookups.html

相信你用半个小时就学会了。

16.示例

为了大家快速开发(方便懒惰的同学),写一些示例。

16-1.输出到控制台


16-2.输出到单个文件

<?xml?version="1.0"?encoding="UTF-8"?>
<Configuration?name="baseConf"?status="warn"?monitorInterval="30">

????<Appenders>

????????<RandomAccessFile?name="File"?fileName="logs/app.log"?immediateFlush="false">
????????????<PatternLayout?pattern="%d{HH:mm:ss.SSS}?[%t]?%-5level?%logger{36}?-?%msg%n"?charset="UTF-8"/>
????????</RandomAccessFile>

????</Appenders>

????<Loggers>

????????<Root?level="info">
????????????<AppenderRef?ref="File"/>
????????</Root>

????</Loggers>

</Configuration>

16-3.按月归档日志,按日进行切分,限制单文件大小为 500MB, 一天最多生成20个文件,也就是(20 * 500)MB大小的日志


16-4.限制Spring框架日志的输出级别

<?xml?version="1.0"?encoding="UTF-8"?>
<Configuration?name="baseConf"?status="warn"?monitorInterval="30">

????<Appenders>

????????<RollingRandomAccessFile?name="File"?fileName="logs/app.log"
?????????????????????????????????filePattern="logs/${date:yyyy-MM}/%d{yyyy-MM-dd}.app.%i.log"?>
????????????<PatternLayout?pattern="%d{HH:mm:ss.SSS}?[%t]?%-5level?%logger{36}?-?%msg%n"?charset="UTF-8"/>

????????????<Policies>
????????????????<TimeBasedTriggeringPolicy?interval="1"?modulate="false"/>
????????????????<SizeBasedTriggeringPolicy?size="500MB"/>
????????????</Policies>

????????????<DefaultRolloverStrategy?max="20"?/>
????????</RollingRandomAccessFile>

????</Appenders>

????<Loggers>

????????<!--
????????????限制Spring框架日志的输出级别,其它框架类似配置
????????????或者使用?AppenderRef?标签,将其输出到指定文件中,记得加上?additivity="false"
????????-->
????????<logger?name="org.springframework"?level="INFO"/>

????????<Root?level="info">
????????????<AppenderRef?ref="File"/>
????????</Root>

????</Loggers>

</Configuration>

学会以上这些理解和方法,相信就可以熟练使用了,加油!

相关推荐

《每日电讯报》研发数字工具,教你更有效率地报道新闻

为鼓励新闻编辑部持续创新,《每日电讯报》正在尝试有战略地研发数字工具。网站的数字媒体主任马尔科姆o科尔斯(MalcolmColes)表示,《每日电讯报》正试图去“创建一些可持续资产”,以便于让记者们...

html5学得好不好,看掌握多少标签

html5你了解了多少?如果你还是入门阶段的话,或者还是一知半解的话,那么我们专门为你们收集的html5常用的标签大全对你就很有帮助了,你需要了解了html5有哪些标签你才能够更好的。驾驭html5...

前端分享-少年了解过iframe么(我想了解少年)

iframe就像是HTML的「内嵌画布」,允许在页面中加载独立网页,如同在画布上叠加另一幅动态画卷。核心特性包括:独立上下文:每个iframe都拥有独立的DOM/CSS/JS环境(类似浏...

做SEO要知道什么是AJAX(人能看到但搜索引擎看不到的内容)

一个明显的,人能看到但搜索引擎不能看到的内容是AJAX。那么什么是AJAX呢?其实,了解过的基本上也都清楚,AJAX不是新的编程语言,而是一种使用现有标准的新方法。AJAX最大的优点是在不重新加...

介绍最前沿的人工智能创新,‘无反向传播’神经网络训练方法?

图像由GoogleImageFX生成前言:本文整理自NoProp原始论文与实践代码,并结合多个公开实现细节进行了全流程复现。对神经网络训练机制的探索仍在不断演进,如果你也在研究反向传播之...

说说我们对HTML6的期许(对html的看法)

HTML5概述HTML5是HTML语言最受欢迎的版本之一,它支持音频和视频、离线存储、移动端、和标签属性等等。还提供了article,section,header这样的标签来帮助开发者更好...

浏览器中在线预览pdf文件,pdf.mjs插件实现web预览pdf

背景:本来只是淘宝上卖卖袜子,想着扩展一下业务,准备做同名“来家居”海外袜子馆外贸项目,碰到pdf在线预览的需求,就找了pdf.js插件进行实践后把此方法记录下来,可以通过多种方法来实现,每种方法都有...

SVG 在前端的7种使用方法,你还知道哪几种?

本文简介点赞+关注+收藏=学会了技术一直在演变,在网页中使用SVG的方法也层出不穷。每个时期都有对应的最优解。所以我打算把我知道的7种SVG的使用方法列举出来,有备无患~如果你还...

HTML5常用标签大全(html5em标签)

HTML前端开发最终取决于掌握标签的多少HTML大概有七八百个标签楼主这里给大家总结了下HTML常用标签标签描述<!--...-->定义注释。<!DOCTYPE>定义文档类型...

&quot;伪君子Snoop Dogg!&quot;... WHAT?| MetroDaily 24/7

TUE.01-新作品-虽说年纪大了会有点糊涂,但是最近SnoopDogg的这波操作实在是让粉丝们有点迷,甚至有人表示没想到他是这样的"伪君子"......而这一切都源于他近日在IG上Po出的一...

史努比snoopy卡通手机壁纸屏保(史努比壁纸无水印)

...

莎夏·班克斯盼望表哥Snoop Dogg为其作出场曲

NXT女子冠军莎夏·班克斯(SashaBanks)近日接受了迈阿密先驱报采访,访谈纪要如下:关于她出众的形象:“我一向喜欢与众不同。为了能让人眼前一亮,我的装束总是非常前卫、非常抢眼,这样才能让观众...

喜欢Snoop!全球第一间「史努比博物馆」海外分馆在东京!

1950年起,由美國漫畫家CharlesM.Schulz創作的作品《Snoopy》史努比,其鮮明的可愛角色與幽默的劇情內容,至今仍成為許多大朋友與小朋友心中的最愛。為了紀念作者所設立的全球首...

Vetements 推出 Snoop Dogg 肖像「天价」T-Shirt

Vetements的CEOGuramGvasalia早前才透露品牌经营策略的秘密–Vetements如何成为人人热议的话题品牌。但似乎他仍有更多需要解释的东西–这个法国奢侈品牌最新...

狗爷Snoop Dogg的《I Wanna Thank Me》巡回演唱会旧金山站

西海岸匪帮说唱歌手SnoopDogg在《IWannaThankMe》巡回演唱会旧金山站表演(图片来自ICphoto)西海岸匪帮说唱歌手SnoopDogg(图片来自ICphoto)西海...

取消回复欢迎 发表评论: