java日志框架详解总结(含配置)
程序员文章站
2022-05-24 15:30:13
...
该篇是集合了百度众多的日志框架详解,java日志框架分析的总结篇。
具体网址:
https://blog.csdn.net/foreverling/article/details/51385128
https://blog.csdn.net/chszs/article/details/8653460
http://baijiahao.baidu.com/s?id=1585361583532845302&wfr=spider&for=pc
http://www.importnew.com/28541.html
https://blog.csdn.net/victor_cindy1/article/details/78716917
https://zhuanlan.zhihu.com/p/24275518
https://my.oschina.net/aiguozhe/blog/87981
http://www.importnew.com/28541.html
https://blog.csdn.net/xktxoo/article/details/76359299
主要的就是这些了。
java里常见的日志库有java.util.logging(JDKlog)、Apache log4j、log4j2、logback、slf4j等等。
这么多的日志框架里如何选择。
首先需要梳理的是日志接口,以及日志接口对应的实现。然后再考虑如何选择使用哪个日志框架。
由图可知我们经常使用的日志框架实质上是一些接口的实现。而目前使用较广泛的统一日志规范接口就是slf4j和commons-logging。
slf4j
它是基于API的java日志框架,slf4j提供了简单统一的日志记录的接口,开发者在配置部署
时只需要是吸纳这个接口就能是实现日志功能。它自身并没有提供具体的日志解决方案,它是负责
服务于各种各样的日志系统,允许用户在部署应用上使用自己常用的日志框架。
也就是说,SLF4j是一个抽象层,它提供了众多的适配器能是配合其他所有开源日志框架。
为了考虑其他项目会使用大量的第三方库,而第三方库使用的日志框架又各不相同,不同的日志框
架又需要不同的配置,不同配置就会导致日志输出到不同的位置。所以我们就需要一个可以将日志
level、日志输出等统一管理,而slf4j的适配器又对各种日志都实现了接管,接管后就可以统一
配置这些第三方库中使用的日志。
commons-logging
commons-logging(jcl)也为众多日志实现库提供了统一的接口,作用和slf4j类似。它允许运行时绑定
任意的日志库。但commons-loggins对log4j和java.util.logging的配置问题兼容性不太好,还会
遇到类加载问题。所以当时log4j的作者又创作了slf4j.....
有了日志接口,就需要选择实现框架。在众多的日志框架如何选择
log4j
Log4j是apache下一个功能非常丰富的java日志库实现,Log4j应该是出现比较早而且最受欢迎的java
日志组件,它是基于java的开源的日志组件。Log4j的功能非常强大,通过Log4j可以把日志输出到控制
台、文件、用户界面。也可以输出到操作系统的事件记录器和一些系统常驻进程。值得一提的是:Log4j可
以允许你非常便捷地自定义日志格式和日志等级,可以帮助开发人员全方位的掌控自己的日志信息是一个日
志开源框架。
logback
logback是log4j的改进版本,而且原生支持slf4j(因为是同一作者开发)。所以logback+slf4j的组
合是日志框架的最佳选择。logback解决了log4j不能使用占位符的问题。logback可以通过jmx修改日
志配置,可以从jmx控制台直接操作,无需重启应用程序。它相比于log4j有更多的优点:
- 原生实现了slf4j API(log4j需要中间层转换)
- 支持xml、Groovy方式配置
- 支持配置文件中加入条件判断
- 更强大的过滤器
- 更充分的测试
- 更丰富的免费文档
- 自动重载有变更的配置文件
- 自动压缩历史日志
等等
Log4j2
log4j2是log4j的升级版本2.x但并不兼容log4j因为它基本上把log4j版本的核心全部重构掉了,log4j2设计上很大程度模仿了slf4j-logback,性能也
获得了很大的提升。具体的差异自行百度。
至于网上不少说的性能比较,应该都是单个框架比较。但与slf4j绑定使用的话,怎么说都是logback性能最佳吧(猜测,欢迎指正)
日志级别
日志level定义应该遵循以下几个:
- debug: 完整详细的记录流程的关键路径,用于开发人员比较感兴趣的跟踪和调试信息,生产环境中正常不会打开debug状态
- info: 应简洁明确让管理员确定状态,记录相当重要有意义的信息。关键的系统参数的回显、后台服务的初始化状态、需要系统管理员确认的关键信息都需要使用info级别
- warn: 能清楚告知发生了什么情况,指示潜在问题能引起别人重视,但不一定需要处理
- error: 系统出现异常或不希望出现的问题,能及时得到关注处理。但也不是所有的异常都记录成error
根据上述,这里将以slf4j为日志接口,而其中logback与slf4j配合桥接性能最优,所以在日志实现上选择logback。
此处以maven进行管理,首先引入依赖,这两个依赖就够了,版本可根据需求修改
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.6</version>
</dependency>
classpath中编写logback的配置文件logback.xml, logback.xml文件放在/src/main/resources/路径中
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 上下文变量设置,用来定义变量值,其中name的值是变量的名称,value的值时变量定义的值。
通过<property>定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<property name="CONTEXT_NAME" value="logback-test" />
<!-- 上下文名称:<contextName>, 每个logger都关联到logger上下文,
默认上下文名称为“default”。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。
一旦设置,不能修改。 -->
<contextName>${CONTEXT_NAME}</contextName>
<!-- <appender>是<configuration>的子节点,是负责写日志的组件。
有两个必要属性name和class。
name指定appender名称,
class指定appender的实现类。 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 对日志进行格式化。 -->
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%class|%thread|%method|%line|%msg%n
</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。 -->
<file>${logs.dir}/logback-test.log</file>
<!-- 当发生滚动时的行为 -->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!-- 必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip -->
<FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern>
<!-- 窗口索引最小值 -->
<minIndex>1</minIndex>
<!-- 窗口索引最大值 -->
<maxIndex>1</maxIndex>
</rollingPolicy>
<!-- **滚动的条件。 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<!-- 活动文件的大小,默认值是10MB -->
<maxFileSize>30MB</maxFileSize>
</triggeringPolicy>
<!-- 对记录事件进行格式化。 -->
<encoder>
<charset>UTF-8</charset>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%class|%thread|%method|%line|%msg%n
</Pattern>
</encoder>
</appender>
<!-- 特殊的<logger>元素,是根logger。只有一个level属性,应为已经被命名为"root".
level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。
<root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。 -->
<root>
<level value="WARN" />
<appender-ref ref="stdout" />
<appender-ref ref="file" />
</root>
<!-- 用来设置某一个 包 或者具体的某一个 类 的日志打印级别、以及指定<appender>,
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
additivity:是否向上级logger传递打印信息。默认是true。(这个logger的上级就是上面的root)
<logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。-->
<logger name="xuyihao.logback.test" level="DEBUG" additivity="true"></logger>
</configuration>