Java日志框架学习--LogBack和Log4j2--下
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java日志框架学习--LogBack和Log4j2--下相关的知识,希望对你有一定的参考价值。
Java日志框架学习--LogBack和Log4j2--下
Logback
Logback是由log4j创始人设计的又一个开源日志组件。
Logback当前分成三个模块:logback-core,logback- classic和logback-access。
- logback-core是其它两个模块的基础模块。
- logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API。使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
- logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能
Logback中的组件
- Logger: 日志的记录器,主要用于存放日志对象,也可以定义日志类型、级别。
- Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
- Layout: 负责把事件转换成字符串,格式化的日志信息的输出。
- 在Logback中Layout对象被封装在encoder中。
- 也就是说我们未来使用的encoder其实就是Layout
Logback配置文件
Logback提供了3种配置文件
- logback.groovy
- logback-test.xml
- logback.xml
如果都不存在则采用默认的配置
日志输出格式
日志输出格式:
- %-10level 级别 案例为设置10个字符,左对齐
- %dyyyy-MM-dd HH:mm:ss.SSS 日期
- %c 当前类全限定名
- %M 当前执行日志的方法
- %L 行号
- %thread 线程名称
- %m或者%msg 信息
- %n 换行
使用演示
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
配置文件
输出到控制台
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--
配置文件通用属性
可以在当前配置文件中通过$name的形式,取得value值
我们在此指定通用的日志输出格式
日志输出格式:
%-10level 级别 案例为设置10个字符,左对齐
%dyyyy-MM-dd HH:mm:ss.SSS 日期
%c 当前类全限定名
%M 当前执行日志的方法
%L 行号
%thread 线程名称
%m或者%msg 信息
%n 换行
-->
<property name="pattern" value="[%-5level] %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>
<!--
配置控制台输出的appender
-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--
表示对于日志输出目标的配置
默认: system.out 表示以黑色字体输出日志
system.err 表示以红色字体输出日志
-->
<target>
System.err
</target>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!--
日志记录器
配置Root Logger
level: 日志级别
-->
<root level="all">
<appender-ref ref="console"/>
</root>
</configuration>
输出到控制台和文件
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--
配置文件通用属性
可以在当前配置文件中通过$name的形式,取得value值
我们在此指定通用的日志输出格式
日志输出格式:
%-10level 级别 案例为设置10个字符,左对齐
%dyyyy-MM-dd HH:mm:ss.SSS 日期
%c 当前类全限定名
%M 当前执行日志的方法
%L 行号
%thread 线程名称
%m或者%msg 信息
%n 换行
-->
<property name="pattern" value="[%-5level] %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>
<!-- 配置文件的输出路径 -->
<property name="dir" value="logback.log"></property>
<!-- 配置文件输出的appender -->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<!-- 引入文件位置 -->
<file>$dir</file>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!--
配置控制台输出的appender
-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--
表示对于日志输出目标的配置
默认: system.out 表示以黑色字体输出日志
system.err 表示以红色字体输出日志
-->
<target>
System.err
</target>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!--
日志记录器
配置Root Logger
level: 日志级别
-->
<root level="all">
<appender-ref ref="file"/>
<appender-ref ref="console"/>
</root>
</configuration>
因为符合OGNL规范,因此配置文件中可以配置的属性,大多可以通过翻看对应的类源码,通过set方法或者属性名推测出来
输出到控制台,文件和html
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--
配置文件通用属性
可以在当前配置文件中通过$name的形式,取得value值
我们在此指定通用的日志输出格式
日志输出格式:
%-10level 级别 案例为设置10个字符,左对齐
%dyyyy-MM-dd HH:mm:ss.SSS 日期
%c 当前类全限定名
%M 当前执行日志的方法
%L 行号
%thread 线程名称
%m或者%msg 信息
%n 换行
-->
<property name="pattern" value="[%-5level] %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>
<!-- 配置文件的输出路径 -->
<property name="fileDir" value="logback.log"></property>
<!-- 配置输出为html形式的appender -->
<appender name="html" class="ch.qos.logback.core.FileAppender">
<!-- 输出的文件位置 -->
<file>logback.html</file>
<!-- 设置layout为输出html形式的 -->
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>
$pattern
</pattern>
</layout>
</appender>
<!-- 配置文件输出的appender -->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<!-- 引入文件位置 -->
<file>$fileDir</file>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!--
配置控制台输出的appender
-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--
表示对于日志输出目标的配置
默认: system.out 表示以黑色字体输出日志
system.err 表示以红色字体输出日志
-->
<target>
System.err
</target>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!--
日志记录器
配置Root Logger
level: 日志级别
-->
<root level="all">
<appender-ref ref="file"/>
<appender-ref ref="console"/>
<appender-ref ref="html"/>
</root>
</configuration>
html展示效果如果:
日志拆分
日志拆分使用的是RollingFileAppender,它继承了FileAppender,因此父类中能配置的属性,这里都可以配置,我们只需要关注当前类新增的查日志拆分策略属性即可。
在当前RollingFileAppender中也为我们提供了两个设置日志拆分策略的set方法:
先看一波如何配置,再来分析源码:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--
配置文件通用属性
可以在当前配置文件中通过$name的形式,取得value值
我们在此指定通用的日志输出格式
日志输出格式:
%-10level 级别 案例为设置10个字符,左对齐
%dyyyy-MM-dd HH:mm:ss.SSS 日期
%c 当前类全限定名
%M 当前执行日志的方法
%L 行号
%thread 线程名称
%m或者%msg 信息
%n 换行
-->
<property name="pattern" value="[%-5level] %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>
<!-- 配置文件的输出路径 -->
<property name="fileDir" value="logback.log"></property>
<!-- 配置输出为html形式的appender -->
<appender name="html" class="ch.qos.logback.core.FileAppender">
<!-- 输出的文件位置 -->
<file>logback.html</file>
<!-- 设置layout为输出html形式的 -->
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>
$pattern
</pattern>
</layout>
</appender>
<!-- 配置文件输出的appender -->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<!-- 引入文件位置 -->
<file>$fileDir</file>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!--
配置控制台输出的appender
-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--
表示对于日志输出目标的配置
默认: system.out 表示以黑色字体输出日志
system.err 表示以红色字体输出日志
-->
<target>
System.err
</target>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
</appender>
<!-- 配置文件的appender,可拆分可归档-归档是压缩的意思 -->
<appender name="roll" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 设置输出格式 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>$pattern</pattern>
</layout>
<!-- 设置未归档的日志文件输出位置 -->
<file>roll_logback.log</file>
<!-- 指定拆分规则 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 按照时间和压缩格式声明文件名,压缩格式gz -->
<fileNamePattern>roll.%dyyyy-MM-dd.log%i.gz</fileNamePattern>
<!-- 按照文件大小来进行拆分 -->
<maxFileSize>1KB</maxFileSize>
</rollingPolicy>
</appender>
<!--
日志记录器
配置Root Logger
level: 日志级别
-->
<root level="all">
<appender-ref ref="roll"/>
</root>
</configuration>
下面分析一波,这里源码流程从subAppend函数讲起,因为每一条日志的输出,都需要交给至少一个appender,完成日志的输出,而交给appender后,一定会来到appender的subAppend这里,各位可以自行debug源码流程
这里拿RollingFileAppender进行讲解:
@Override
protected void subAppend(E event)
//日志真正写入前,现需要判断是否应该触发当前日志文件的归档行为
//因为可能当前写入数据超过了日志文件大小的限制,那么当前日志就应该归档,再创建一个新的日志文件
// The roll-over check must precede actual writing. This is the
// only correct behavior for time driven triggers.
// We need to synchronize on triggeringPolicy so that only one rollover
// occurs at a time
//加锁确保一次只有一个线程进行日志roll操作
synchronized (triggeringPolicy)
//triggeringPolicy负责判断是否需要进行roll over
if (triggeringPolicy.isTriggeringEvent(currentlyActiveFile, event))
rollover();
//调用父类方法真正执行写入操作
super.subAppend(event);
具体回滚策略是如何执行的,这里不再进行分析
过滤器
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<property name="pattern" value="[%-5level] %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>
<!-- 配置文件的输出路径 -->
<property name="fileDir" value="logback.log"></property>
<!--
配置控制台输出的appender
-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!--
表示对于日志输出目标的配置
默认: system.out 表示以黑色字体输出日志
system.err 表示以红色字体输出日志
-->
<target>
System.err
</target>
<!--
配置日志输出格式
-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式引用通用属性配置 -->
<pattern>$pattern</pattern>
</encoder>
<!-- 配置过滤器 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置日志的输出级别 -->
<level>ERROR</level>
<!-- 高于Level中设置的日志级别,则打印日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 低于Level中设置的日志级别,则跳过 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
日志记录器
配置Root Logger
level: 日志级别
-->
<root level="all">
<appender-ref ref="console"/>
</root>
</configuration>
通过过滤器,我们可以设置某个appender的日志过滤输出
过滤器链在何时会执行呢?
异步日志
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<property name="pattern" value="[%-5level] %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n">Java日志框架:logback详解
Java日志框架SLF4J和log4j以及logback的联系和区别