Logback
1、官方文档
https://logback.qos.ch/manual/index.html
2、下载地址
https://logback.qos.ch/download.html
3、快速使用
这里主要是 logback + SLF4j 配合使用。
- pom引入jar包
<!-- 日志:slf4j + logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.31</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
- src/main/resource 创建 logback.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
<contextName>logback</contextName>
<property name="log.path" value="./logs" />
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%15.15t] %-40.40logger{39} : %m%n}"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--root 标签和其他logger标签起相同的作用,只是其他logger 可以继承此标签的属性-->
<root>
<appender-ref ref="CONSOLE" />
</root>
</configuration>
- Java 代码
package com.black.nginx.app;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NginxApp {
private static Logger logger = LoggerFactory.getLogger(NginxApp.class);
public static void main(String[] args) {
logger.info("app start ...");
logger.info("app shutdown .");
}
}
- 效果
2021-07-13 23:19:41.591 INFO --- [ main] com.black.nginx.app.NginxApp : app start ...
2021-07-13 23:19:41.596 INFO --- [ main] com.black.nginx.app.NginxApp : app shutdown .
4、logback.xml拷贝就用
- console 打印
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" >
<contextName>logback</contextName>
<!--0. 日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<root>
<appender-ref ref="CONSOLE" />
</root>
</configuration>
打印结果:
2021-07-14 23:00:38.497 [INFO ] [main ] com.black.nginx.app.NginxApp.main[line:11]: app start ...
2021-07-14 23:00:38.497 [INFO ] [main ] com.black.nginx.app.NginxApp.main[line:14]: app shutdown .
- 日志文件
1、固定文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
<!--0. 日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/>
<!-- 时间戳 -->
<timestamp key="file_name_date" datePattern="yyyyMMdd"/>
<!--1. 记录日志到文件-->
<appender name="LogFile" class="ch.qos.logback.core.FileAppender">
<!-- 日志文件名 -->
<file>${file_name_date}/log-info-${file_name_date}.log</file>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<root>
<appender-ref ref="LogFile" />
</root>
</configuration>
2、基于时间分隔文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
<!--0. 日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/>
<!-- 时间戳 -->
<timestamp key="file_name_date" datePattern="yyyyMMdd"/>
<!--1. 记录日志到文件-->
<appender name="ROLL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- prudent 支持多个JVM 写入统一日志文件 -->
<prudent>true</prudent>
<!-- 设置滚动策略 -->
<!-- FixedWindowRollingPolicy: -->
<!-- TimeBasedRollingPolicy: -->
<!-- SizeAndTimeBasedRollingPolicy: -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 文件名以及文件路径(如果日志文件名以.gz or .zip,则半夜会自动压缩日志) -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志保留天数(如果 fileNamePattern 是按天滚动的) ,超过30天的日志会异步删除-->
<maxHistory>30</maxHistory>
<!-- 日志文件总大小,超过3GB时,会删除旧的日志文件 -->
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>
<root>
<appender-ref ref="ROLL_FILE" />
</root>
</configuration>
3、基于时间和大小分隔文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
<!--0. 日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/>
<!-- 时间戳 -->
<timestamp key="file_name_date" datePattern="yyyyMMdd"/>
<!--1. 记录日志到文件-->
<appender name="ROLL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- prudent 支持多个JVM 写入统一日志文件 -->
<prudent>true</prudent>
<!-- 设置滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 文件名以及文件路径(如果日志文件名以.gz or .zip,则半夜会自动压缩日志) -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 每个日志文件最多100M -->
<maxFileSize>100MB</maxFileSize>
<!-- 日志保留天数(如果 fileNamePattern 是按天滚动的) ,超过30天的日志会异步删除-->
<maxHistory>30</maxHistory>
<!-- 日志文件总大小,超过20GB时,会删除旧的日志文件 -->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
</appender>
<root>
<appender-ref ref="ROLL_FILE" />
</root>
</configuration>
4、基于固定大小
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" >
<!--0. 日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5p] [%-10.15t] %20.30logger{30}.%M[line:%L]: %m%n}"/>
<!-- 时间戳 -->
<timestamp key="file_name_date" datePattern="yyyyMMdd"/>
<!--1. 记录日志到文件-->
<appender name="ROLL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log-info.log</file>
<!-- 设置滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>log-info.%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>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="ROLL_FILE" />
</root>
</configuration>
5、logback.xml Appender 详解
- ConsoleAppender
<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
<configuration>
<!-- Insert the current time formatted as "yyyyMMdd‘T‘HHmmss" under
the key "bySecond" into the logger context. This value will be
available to all subsequent configuration elements. -->
<timestamp key="bySecond" datePattern="yyyyMMdd‘T‘HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- use the previously created timestamp to create a uniquely
named log file -->
<file>log-${bySecond}.txt</file>
<encoder>
<pattern>%logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
- RollingFileAppender
<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>
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- Support multiple-JVM writing to the same log file -->
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<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>
<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>
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%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>
<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>
fileNamePattern 与 Rollover关系:
fileNamePattern | Rollover schedule |
---|---|
/wombat/foo.%d | 每天 |
/wombat/%d{yyyy/MM}/foo.txt | Rollover 每月开始 |
/wombat/foo.%d{yyyy-ww}.log | Rollover 每周第一天 |
/wombat/foo%d{yyyy-MM-dd_HH}.log | Rollover 每小时滚动 |
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log | Rollover 每分钟滚动 |
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log | Rollover 每分钟滚动 |
/foo/%d{yyyy-MM,aux}/%d.log | Rollover daily. Archives located under a folder containing year and month. |
Rollover 就是 maxHistory 属性的单位。
6、logback.xml PatternLayout 详解
我对 logback.xml 中 pattern 里的 %d %c 什么的搞不明白什么含义,下面就介绍一下,pattern 中使用到的Conversion Word的含义:
- %c{length}
或 %lo{length} %logger{length}
Conversion | Logger name | Result |
---|---|---|
%logger | mainPackage.sub.sample.Bar | mainPackage.sub.sample.Bar |
%logger{0} | mainPackage.sub.sample.Bar | Bar |
%logger{5} | mainPackage.sub.sample.Bar | m.s.s.Bar |
%logger{10} | mainPackage.sub.sample.Bar | m.s.s.Bar |
%logger{15} | mainPackage.sub.sample.Bar | m.s.sample.Bar |
%logger{16} | mainPackage.sub.sample.Bar | m.sub.sample.Bar |
%logger{26} | mainPackage.sub.sample.Bar | mainPackage.sub.sample.Bar |
- %C{length}
或 %class{length}
打印类名
- %cn
或 contextName
- %d{pattern}
或 %date{pattern} %d{pattern, timezone}
%date{pattern, timezone}
打印日期
Conversion Pattern | Result |
---|---|
%d | 2006-10-20 14:06:49,812 |
%date | 2006-10-20 14:06:49,812 |
%date{ISO8601} | 2006-10-20 14:06:49,812 |
%date{HH:mm:ss.SSS} | 14:06:49.812 |
%date{dd MMM yyyy;HH:mm:ss.SSS} | 20 oct. 2006;14:06:49.812 |
- %F / %file
java 源文件的名字
-
%M / %method
打印日志所在方法名 -
%L / %line
logger.info等代码所在文件的行数 -
%m / %msg / %message
打印 用户日志信息,即 logger.info()的参数 -
%n
换行 -
%p / %le / %level
日志事件等级 INFO ,DEBUG等 -
%r / %relative
应用启动执行,一直到打印日志,执行的毫秒数 -
%t / %thread
线程名 -
%ex{depth}
exception{depth}
throwable{depth}
打印异常信息控制
格式 | 结果 |
---|---|
%ex | mainPackage.foo.bar.TestException: Houston we have a problem at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22) at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17) at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38) |
%ex{short} | mainPackage.foo.bar.TestException: Houston we have a problem at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22) |
%ex{full} | mainPackage.foo.bar.TestException: Houston we have a problem at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22) at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17) at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38) |
%ex{2} | mainPackage.foo.bar.TestException: Houston we have a problem at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22) at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17) |
-
%property{key}
打印Properties文件中的key 对应的 value -
%caller{depth}
打印方法调用层级信息
7、logback.xml Format modifiers 详解
Format modifier | 左对齐 | 最小宽度 | 最大宽度 | 评论 |
---|---|---|---|---|
%20logger | 否 | 20 | 无 | 如果小于20字符则默认右对齐 |
%-20logger | 是 | 20 | 无 | 如果小于20字符则左对齐 |
%.10logger | NA | 无 | 30 | 超出30字符则删除 com.black.nginx.app.NginxApp 会打印出:p.NginxApp |
%20.30logger | 否 | 20 | 30 | 如果超过30个字符,则将从末尾开始截取30个字符打印 |
%-20.30logger | 是 | 20 | 30 | 如果超过30个字符,则将从开头开始截取30个字符打印 |
%.-30logger | NA | 无 | 30 | 如果超过30个字符,则将从开头开始截取30个字符打印 |