简介
logback
是当下最受欢迎的log记录工具,高性能,功能全,文档全,同时作者也log4j
的系列的开发者, 本文从logback
常用的组件和功能点进行介绍,并提供了简单的例子参考,logback
官网
java
中如何使用logback
在
pom.xml
中引入关键的两个包
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
然后在resources目录下创建一个logback.xml就可以了,请参考全量的可用配置文件这个章节
日志级别
推荐使用以下几种,级别从高到低排列
Level | 描述 |
---|---|
ERROR | 错误事件可能仍然允许应用程序继续运行 |
WARN | 指定具有潜在危害的情况 |
INFO | 指定能够突出在粗粒度级别的应用程序运行情况的信息的消息 |
DEBUG | 指定细粒度信息事件是最有用的应用程序调试 |
Appender级别
Appender class dependency
ConsoleAppender
(将日志输出到控制台)
将日志信息打印在控制台中
配置 | 类型 | 描述 |
---|---|---|
encoder | Encoder | 日志输出格式 |
target | String | 日志输出目标,可以是System.out或者System.err,默认是System.out |
withJansi | boolean | 默认是false,这个使用不到,好像是开启后输出的ANSI会有颜色,具体看官网介绍 |
sample:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
FileAppender
(将日志输出到文件中)
FileAppender OutputStreamAppender
的子类,将日志输出到指定文件中。如果文件已经存在,根据配置属性来判断在末尾追加或者重新生成文件
配置 | 类型 | 描述 |
---|---|---|
append | boolean | 默认为true,会将日志追加到现有文件末尾 |
encoder | Encoder | 日志输出格式 |
file | String | 文件名,可以带路径,如不过文件或目录不存在则会创建,例如: logs /info.log,该属性没有默认值 |
immediateFlush | boolean | 一旦有日志产生立即刷新到文件,通过情况下把它设为false,以提高性能,因为会频繁的flush buffer; |
sample:
<configuration>
<!-- 使用时间戳作为文件名 -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile-${bySecond}.log</file>
<append>true</append>
<!-- set immediateFlush to false for much higher logging throughput -->
<immediateFlush>true</immediateFlush>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
RollingFileAppender
(滚动式输出)
RollingFileAppender继承于FileAppender, 按照一些特定策略生成滚动文件,例如与TimeBasedRollingPolicy策略搭配时,当文件到达指定时间,会重新生成一个新的文件,关于策略,后面章节会有具体详细介绍。
配置 | 类型 | 描述 |
---|---|---|
append | boolean | 看FileAppender配置 |
encoder | Encoder | 看FileAppender配置 |
file | String | 看FileAppender配置 |
rollingPolicy | RollingPolicy | 日志滚动策略:配置这个选项会让日志文件按照指定策略进行滚动 |
triggeringPolicy | TriggeringPolicy | 触发滚动策略:通常搭配rollingPolicy一起使用,用于设置滚动的触发条件 |
sample:
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<!-- 设置滚动策略 TimeBasedRollingPolicy 按日期滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--设置日志命名模式-->
<fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!--最多保留30天log-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 超过150MB时,立即触发滚动策略,生成新的文件 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>150</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d [%p] %-5level %logger - %msg%newline</pattern>
</encoder>
</appender>
日志文件策略 *Policy(常用)
TimeBasedRollingPolicy
(按日期滚动策略)
TimeBasedRollingPolicy
可能是logback最受欢迎的滚动策略,基于时间的滚动,可以是一天也可以是一个月,这个较为常用,通常我们可以设置一天生成一个新的文件,很好归纳,统计
配置 | 类型 | 描述 |
---|---|---|
fileNamePattern | String | log文件命名规则,通常使用%d来按天或按月输出,例如errorFile.%d{yyyy-MM-dd}.log,生成出来的文件类似于errorFile.2018-10-09.log,带上日期后这样每天生成的文件就不会名字重复了,这个还支持选择时区,例如%d{yyyy-MM-dd,UTC} |
maxHistory | int | 日志保留天数,超过该天数的历史日志文件将会被logback异步删除 |
totalSizeCap | int | 归档文件的总大小,优先应用maxHistory的策略。 |
cleanHistoryOnStart | boolean | 默认为false,触发归档文件立即删除的动作。 |
滚动输出支持自动压缩,文件名以
.gz
或者.zip
结尾即可,例如:/wombat/foo.%d.gz
sample:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
SizeAndTimeBasedRollingPolicy
(按大小和时间滚动策略)
这个应该是最常用的吧,按照指定时间和文件大小的策略来滚动日志。废话不多说看下面的例子
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
请注意除
“%d”
之外的“%i”
转换标记。%i
和%d
令牌都是强制性的。 每当当前日志文件在当前时间段结束之前达到maxFileSize时,它将以增加的索引存档,从0开始
FixedWindowRollingPolicy
(以固定的算法策略生成滚动文件 不常用)
这个策略不常用,咱就不多bb了,属性和其他滚动策略是一样的,通常文件命名规范是这样的:
tests.%i.log
,当到达条件触发滚动时会生成文件test1.log
,test2.log
,test3.log
...
SizeBasedTriggeringPolicy
(根据大小触发滚动的策略)
这个标签里的配置,用来触发滚动时间的,例如文件大小到了指定值,就是触发滚动
sample:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
fileNamePatten
的一些规则(例子,按年,月,日,天,时,分,秒滚动)
例子 | 描述 |
---|---|
/wombat/foo.%d | 按天滚动,格式 年-月-日,都生成在一个文件夹中 |
/wombat/%d{yyyy/MM}/foo.txt | 按月滚动,每个月生成一个相同的文件,在不同的月份文件夹中,例如first: /wombat/2018/09/foo.txt,next: /wombat/2018/10/foo.txt |
/wombat/foo.%d{yyyy-ww}.log | 每周生成一次,每周的第一天开始重新生成 |
/wombat/foo%d{yyyy-MM-dd_HH}.log | 每小时生成一次 |
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log | 每分钟生成一次 |
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log | 按指定时区每分钟生成一次 |
/foo/%d{yyyy-MM,aux}/%d.log | 每天生成一次,按照年和月区分,例如,/foo/2018-09/中存在一个月的log,log名是每天的日期 |
pattern
配置(日志输出格式化)
例子
下面会介绍一些常用的配置规则。
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
%-4relative
: 将输出日志记录的时间,进行左对齐,宽度为4.%thread
: 将输出记录日志的线程号%-5level
: 输出5个日志级别,进行左对齐。%logger{35}
: 输出日志记录的logger
名通常为类名,长度为35。%msg%n
: 输出应用程序提供的信息,并换行。
注意:所有关键字在使用的时候必须带上%
,如上,-
为对其标志
pattern
表格
关键字 | 描述 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
c{length} lo{length} |
输出logger所属的类目,通常就是所在类的全名,参数为logger名保留长度,默认不填为全名.
|
||||||||||
C{length} class{length} |
和上面用法类似,输出调用者的全名,性能较差,不推荐配置。 | ||||||||||
contextName cn| |
输出上下文名称 | ||||||||||
d{pattern} date{pattern} |
输出日志的打印时间,和java中的日期格式化类似
|
||||||||||
caller{depth} | 输出日志调用者的调用栈深度信息,值越大,输出的栈信息越多
|
||||||||||
L line |
输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。如不考虑性能问题,可以使用 | ||||||||||
m msg message |
应用程序提供的信息 | ||||||||||
M method |
输出执行日志记录的方法名性能较差,如不考虑性能问题,可以使用 | ||||||||||
n | 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n” | ||||||||||
p le level |
输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL | ||||||||||
t thread |
输出打印日志的线程名 | ||||||||||
replace(msg){r,t} | msg为日志内容,r是正则表达式,将msg中符合r的内容替换成t。 例如:%replace(%msg){'\s',""} |
||||||||||
r relative |
输出自应用启动到输出该log信息耗费的毫秒数 |
配置:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日期 [线程] [class类]-[日志级别] log内容 回车符号 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n</pattern>
</encoder>
</appender>
<!-- 输出INFO及以上的日志 -->
<root level="INFO">
<!-- 让自定义的appender生效 -->
<appender-ref ref="STDOUT"/>
</root>
</configuration>
控制台输出:
2018-10-09 14:27:55 [main] [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping]-[INFO] Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-09 14:27:55 [main] [org.springframework.jmx.export.annotation.AnnotationMBeanExporter]-[INFO] Registering beans for JMX exposure on startup
2018-10-09 14:27:55 [main] [org.apache.coyote.http11.Http11NioProtocol]-[INFO] Starting ProtocolHandler ["http-nio-6677"]
2018-10-09 14:27:55 [main] [org.apache.tomcat.util.net.NioSelectorPool]-[INFO] Using a shared selector for servlet write/read
2018-10-09 14:27:55 [main] [org.springframework.boot.web.embedded.tomcat.TomcatWebServer]-[INFO] Tomcat started on port(s): 6677 (http) with context path ''
2018-10-09 14:27:55 [main] [com.xj.plugins.Springboot2AnalyzeApplication]-[INFO] Started Springboot2AnalyzeApplication in 2.014 seconds (JVM running for 3.949)
控制台输出的log配置颜色
格式 | 描述 |
---|---|
%black | 黑色 |
%red | 红色 |
%green | 绿色 |
%yellow | 黄色 |
%blue | 蓝色 |
%magenta | 品红 |
%cyan | 青色 |
%white | 白色 |
%gray | 灰色 |
%highlight | 高亮色 |
%bold | 更鲜艳色颜色,强化以上所有的颜色,例如%boldRed,%boldBlack |
例子:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日期 [线程] [class类]-[日志级别] log内容 回车符号 -->
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss,SSS}) [%cyan(%t)] [%yellow(%c)]-[%highlight(%p)] %m%n</pattern>
</encoder>
</appender>
<!-- 输出INFO及以上的日志 -->
<root level="INFO">
<!-- 让自定义的appender生效 -->
<appender-ref ref="STDOUT"/>
</root>
</configuration>
配置过后的控制台输出
日志定向输出
logback.xml中如何需要将某中日志输出到文件中可以使用过滤器,类似于以下这个例子
xml配置过滤器,例如将error日志输出到error.log中
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c]-[%p] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${LOG_HOME}/error-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- 文件最大30MB,保留60天,总大小20GB -->
<maxFileSize>30MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- 过滤器,只写入error级别log -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
如果有需要特殊log需要定向输出的话可以重写 Filter方法
public class MyLogFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
if(event.getMessage() != null
&& (event.getMessage().startsWith("test")
|| event.getMessage().startsWith("demo"))) {
return FilterReply.ACCEPT;
} else {
return FilterReply.DENY;
}
}
}
然后将filter加入到你的appender中
<!-- 过滤器,写入test和demo开头的日志 -->
<filter class="xx.xxx.xxxx.MyLogFilter" />
关闭类中某个级别的log输出
在logback.xml中加入以下配置
OFF表示全部关闭,可以配置指定级别如INFO,DEBUG...
<logger name="xx.xx.class" level="OFF" />
logback.xml
读取环境变量
logback.xml
支持两种读取方式,从系统环境中读取,从spring配置文件中读取
读取系统环境变量 通过${envName}方式获取
<!-- 从系统环境变量读取日志输出目录 -->
<property name="LOG_HOME" value="${log.dir}"/>
读取spring配置文件的方式
<!-- 从context中读取所以不需要使用${}获取 -->
<springProperty scope="context" name="LOG_HOME" source="logback.dir"/>
默认值设置
如果在环境变量中没有取到
LOG_HOME
的值,则会使logs
作为默认值,和Shell
语法中设置默认值类似
<file>${LOG_HOME:-logs}/test/test-info.log</file>
-
全量的可用配置文件
以下配置会生成三个日志文件,具体的策略是:每天会生成一个新的文件,当天日志文件达到指定大小会自动压缩,并且生成新的文件进行记录。
main.log
(只记录info
级别及以上的日志输出)warn.log
(只记录warn
级别的日志输出)error.log
(只记录error
级别的日志输出)
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!-- 从spring中获取配置,如获取不到会使用默认值 -->
<springProperty scope="context" name="LOG_HOME" source="logging.path"/>
<springProperty scope="context" name="LOG_LEVEL" source="logging.output.level"/>
<springProperty scope="context" name="LOG_MAX_SIZE" source="logging.file.max-size"/>
<springProperty scope="context" name="LOG_TOTAL_SIZE_CAP" source="logging.file.total-size-cap"/>
<springProperty scope="context" name="LOG_MAX_HISTORY" source="logging.file.max-history"/>
<!-- 输出样式 -->
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%logger{10}]-[%p] %m%n"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%blue(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%cyan(%t)] [%yellow(%logger{10})]-[%highlight(%p)] %m%n</pattern>
</encoder>
</appender>
<appender name="Main-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/main.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/main-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<appender name="Error-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/error-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="Warn-Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-logs}/logback/warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME:-logs}/logback/warn-%d{yyyy-MM-dd}_%i.log.zip</FileNamePattern>
<MaxHistory>${LOG_MAX_HISTORY:-30}</MaxHistory>
<MaxFileSize>${LOG_MAX_SIZE:-10MB}</MaxFileSize>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP:-10GB}</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<!-- log filter -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 关闭类中某个级别的输出 OFF全部关闭 , INFO,DEBUG ...
<logger name="x.x.Constants">
<level value="OFF"/>
</logger>
-->
<!-- log output level -->
<root level="${LOG_LEVEL:-INFO}">
<appender-ref ref="STDOUT"/>
<appender-ref ref="Main-Log"/>
<appender-ref ref="Warn-Log"/>
<appender-ref ref="Error-Log"/>
</root>
</configuration>