现在spring boot日志流行两个一个是 Logback + SLF4J 组合,一个是 log4j2,每都有自己的特点。这里先使用spring boot默认的日志组合 Logback + SLF4J ,它使用起来比较简单没有太复杂的配置关系。
- Logback日志库需要和SLF4J配合使用。SLF4J是一个实现Java日志切换库。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
----------------- 导入任何一个都可以 ------------------
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
1 日志基本输出
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextLog {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(TextLog.class);
logger.info("Hello Logback!!");
}
}
10:54:22.651 [main] INFO cn.core.sys.TextLog - Hello Logback!!
- 配置文件(
logback.xml
)不存在,则默认将日志输出到控制台。
日志级别
所有日志都会遵守这个级别顺序 TRACE < DEBUG < INFO < WARN < ERROR
logger.trace("跟踪");
logger.debug("调试");
logger.info("信息");
logger.warn("警告");
logger.error("错误");
参数输出
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextLog {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(TextLog.class);
logger.info("{}", "日志");
logger.info("{} {}", "日志", "信息");
logger.info("{} {}", "日志");
logger.info("{}", "日志", "信息");
logger.info("\\{}", "日志");
logger.info("{ }", "日志");
}
}
11:00:13.027 [main] INFO cn.core.sys.TextLog - 日志
11:00:13.030 [main] INFO cn.core.sys.TextLog - 日志 信息
11:00:13.031 [main] INFO cn.core.sys.TextLog - 日志 {}
11:00:13.031 [main] INFO cn.core.sys.TextLog - 日志
11:00:13.031 [main] INFO cn.core.sys.TextLog - {}
11:00:13.031 [main] INFO cn.core.sys.TextLog - { }
- 声明的参数字符串传将递给第一个{},如果有第二个参数传递给第二个{}。
- 如果参数没有对应的{},{}将输出为{}字符串。
异常输出
Logger logger = LoggerFactory.getLogger(Main.class);
try {
throw new Exception("test exception");
} catch (Exception e) {
logger.info("error", e);
}
11:04:15.972 [main] INFO cn.core.sys.TextLog - error
java.lang.Exception: test exception
at cn.core.sys.TextLog.main(TextLog.java:9)
- 可以将异常跟踪输出到日志。
2 logback.xml 配置文件
文件目录
src/main/
|-java
| -cn/core/sys
| |-Test.java
|-resources
|-logback.xml
配置文件logback.xml
直接放在类路径下。例如 src下 ,resources 下,classpath下
种类 | 说明 |
appender 附加器 | 设置日志输出目的地和日志格式。由记录器和根指定。 |
logger 记录器 | 设置要输出的日志级别。通过将 appender 指定为子元素来设置输出目标等。 |
root 根 | 记录器的常用设置。 |
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="STDOUT" />
</root>
</configuration>
< appender >标签定义了 appender
-
<encoder>
标签的<pattern>
用于定义输出的格式。 -
ch.qos.logback.core.ConsoleAppender
通过指定类,您可以定义要输出到控制台的附加程序。
< root >标签描述根记录器的设置
-
<appender-ref>
指定 appender(日志输出目标)。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextLog {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(TextLog.class);
logger.info("欢迎来到 韬哥的Logback!!");
}
}
日志输出
欢迎来到 韬哥的Logback!!
3 输出格式
日志消息打印格式可以定义为开头是特殊参数%m
,例如.%
每个转换格式的日志输出信息可以加入特定参数。**例如,您可以传递一种格式,例如输出日期date
。
格式参数参照
设定参数 | 输出结果 | 说明 |
%c(c | sample.logback.Main | 打印记录器的名称。 |
%d(d | 2022-04-01 00:36:55,947 | 输出日期和时间。 |
%d{HH:mm} | 00:57 | 输出指定时间格式。 |
%m(m | 欢迎来到 韬哥的Logback!! | 输出传递给记录器的消息。 |
a%n b | a<换行> b | 输出与执行环境匹配的换行代码。 |
%p (p | INFO | 输出日志级别。 |
%t (t | main | 输出日志时输出线程名。 |
例如 xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
// 日期%d 打印类名%c 空格 %m日志 %n回车换行
<pattern>%d %c %m%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="STDOUT" />
</root>
</configuration>
输出格式
2022-07-13 11:39:03,833 cn.core.sys.TextLog 欢迎来到 韬哥的Logback!!
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
2022-07-13 12:13:23.647 [main] INFO cn.core.sys.TextLog - 欢迎来到 韬哥的Logback!!
- %date{yyyyMMdd} 自定义格式。
输出字符串
设定参数 | 输出结果 | 说明 |
[%5m] | “123” [ 123] “123456” [123456] | 最小字符长度,右对齐并用半角空格填充。 |
[%.5m] | “123” [123] “123456” [23456] | 超出最大字符长度,从左起依次省略超过位数的部分。 |
[%-5] | “123” [123 ] | 最小宽度设置为负,它将左对齐。 |
[%.-5] | “123456” [12345] | 如果最大宽度设置为负,则从右起依次省略超过位数的部分。 |
[%3.5m] | “123456” [23456] “12” [ 12] | 最小宽度和最大宽度。 |
[%-3.-5m] | “123456” [12345] “1234” [1234] | 最小宽度和最大宽度,它将左对齐。 |
4 日志记录器
-
<logger>
标签中设置声明记录器的引用名称。 -
getLogger()
记录器的名称作为方法参数传递给指定的记录器。
public class TextLog {
public static void main(String[] args) {
//指定输出的记录器名称 zhtbs
Logger logger = LoggerFactory.getLogger("zhtbs");
logger.debug("debug"); |
logger.info("欢迎来到 韬哥的Logback!!"); |
} |
} |
<appender> |
<encoder> |
<pattern></pattern> |
</encoder> |
</appender> |---------------------------|
<logger name="zhtbs" level="info" />
<root>
<appender-ref ref="STDOUT" />
</root>
打印输出 zhtbs记录器的日志信息
2022-07-13 12:24:43.406 [main] INFO sampleLogger - 欢迎来到 韬哥的Logback!!
level 输出级别
-
<logger>
level使用属性指定记录器的级别。 - 只输出指定级别以上的日志。
继承关系
记录器可以父子关系的命名关系输出日志信息。
- 父子关系用“.”号来分割
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="zht" level="trace" />
<logger name="zht.bar" level="info" />
<root>
<appender-ref ref="STDOUT" />
</root>
</configuration>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextLog {
public static void main(String[] args) {
Logger z = LoggerFactory.getLogger("zht");
z.trace("trace");
z.debug("debug");
z.info("info");
Logger z1 = LoggerFactory.getLogger("zht.bar");
z1.trace("trace");
z1.debug("debug");
z1.info("info");
Logger z2 = LoggerFactory.getLogger("zht.bar.Hoge");
z2.trace("trace");
z2.debug("debug");
z2.info("info");
}
}
输出结果
2022-07-13 12:54:55.662 [main] TRACE zht - trace
2022-07-13 12:54:55.664 [main] DEBUG zht - debug
2022-07-13 12:54:55.664 [main] INFO zht - info
2022-07-13 12:54:55.665 [main] INFO zht.bar - info
2022-07-13 12:54:55.665 [main] INFO zht.bar.Hoge - info
- 默认情况下,根记录器的级别为
debug
。 - zht 使用logger覆盖它 trace级别日志。
- zht.bar 记录器设置info,它之覆盖info级别的日志。
- 另一方面,zht.bar.Hoge
logger
foo.bar继承了 logger 的设置,
info`只输出级别日志。
记录器 appender 对应关系设置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="zht1" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="zht2" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>zht.bar.Hoge : %msg%n</pattern>
</encoder>
</appender>
<logger name="zht" level="trace" />
<logger name="zht.bar.Hoge" >
<appender-ref ref="zht2" />
</logger>
<root>
<appender-ref ref="zht1" />
</root>
</configuration>
- 通过为 logger 设置 appender,中的ref="zht2"属性来指定 logger 的日志输出方式,与appender name=“zht1” 名字为对应关系。
public static void main(String[] args) {
Logger z = LoggerFactory.getLogger("zht");
z.trace("trace");
z.debug("debug");
z.info("info");
Logger z1 = LoggerFactory.getLogger("zht.bar");
z1.trace("trace");
z1.debug("debug");
z1.info("info");
Logger z2 = LoggerFactory.getLogger("zht.bar.Hoge");
z2.trace("trace");
z2.debug("debug");
z2.info("info");
}
输出结果
2022-07-13 12:56:27.667 [main] TRACE zht - trace
2022-07-13 12:56:27.669 [main] DEBUG zht - debug
2022-07-13 12:56:27.669 [main] INFO zht - info
2022-07-13 12:56:27.670 [main] TRACE zht.bar - trace
2022-07-13 12:56:27.670 [main] DEBUG zht.bar - debug
2022-07-13 12:56:27.670 [main] INFO zht.bar - info
zht.bar.Hoge : trace
2022-07-13 12:56:27.670 [main] TRACE zht.bar.Hoge - trace
zht.bar.Hoge : debug
2022-07-13 12:56:27.670 [main] DEBUG zht.bar.Hoge - debug
zht.bar.Hoge : info
2022-07-13 12:56:27.670 [main] INFO zht.bar.Hoge - info
- additivity=“false”
<logger name="zht.bar" additivity="false">
<appender-ref ref="zht3" />
</logger>
additivity
属性,false
则不会继承父logger中设置的appender 输出格式, logger 的子节点将再次继承父节点的 appender 输出格式。
5 日志文件输出
使用**ch.qos.logback.core.FileAppender
** 日志文件输出类,创建日志文件保存到本地硬盘中。
logback.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="zht1" class="ch.qos.logback.core.FileAppender">
<file>logback-zht.log</file>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="zht1" />
</root>
</configuration>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TextLog {
public static void main(String[] args) {
Logger z = LoggerFactory.getLogger("zht");
z.trace("trace");
z.debug("debug");
z.info("info");
}
}
项目跟目录下出现一个logback-zht.log文件。
|-src/main/
| |-java
| | -cn/core/sys
| | |-Test.java
| |-resources
| |-logback.xml
|-logback-zht.log 日志文件
6 轮换日志文件
如果要轮换日志文件,请在 appender 类中指定 ch.qos.logback.core.rolling.RollingFileAppender
这给工具类。
- rollingPolicy标签中设置ch.qos.logback.core.rolling.TimeBasedRollingPolicy 日志时间创建日志类。
- fileNamePattern 中指定日志文件名称。
日志文件的日期格式会自动推断并执行按时间进行分割日志文件
-
%d{yyyyMMdd_HHmmss}
这个格式情况下,时间格式被指定到秒,所以当以秒为单位执行分割日志文件。 -
%d{yyyy-MM-dd}
如果日期发生变化,它将按天进行分割日志文件。 - 根据自定义的时间格式来分割日志文件。
<xml version="1.0" encoding="UTF-8">
<configuration>
<appender name="zht1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logback-zht.log</file>
<---------TimeBasedRollingPolicy 时间分割日志文件 ----------->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<---------{yyyyMMdd_HHmmss} 以秒为单位分割日志文件 ----------->
<---------logback-zht-%d{yyyyMMdd}.log 以天分割日志文件 ----------->
<fileNamePattern>logback-zht-%d{yyyyMMdd_HHmmss}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="zht1" />
</root>
</configuration>
多次执行日志输出。
|-src/main/
| |-java
| | -cn/core/sys
| | |-Test.java
| |-resources
| |-logback.xml
|-logback-zht.log 日志文件
|-logback-zht-20220711_132131.log
|-logback-zht-20220711_133531.log
自动删除文件设置
-
<maxHistory>
使用标签,设置要保留多少日志文件。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="zht1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logback-zht.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logback-zht-%d{yyyyMMdd_HH}.log</fileNamePattern>
<maxHistory>3</maxHistory> <!-- ★最大保存文件数 -->
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="zht1" />
</root>
</configuration>
------------------------ 时间格式 ----------------------------
%d{yyyyMMdd_HH} 按每天小时分割创建文件
<fileNamePattern>logback-sample-%d{yyyyMMdd_HH}.log</fileNamePattern>
2022-07-11 20:00 52 logback-sample-2022-07-11_20.log
2022-07-11 21:00 52 logback-sample-2022-07-1121.log
2022-07-11 22:00 37 logback-sample-2022-07-11_22.log
2022-07-11 23:58 37 logback-sample.log
格局时间格式判断删除文件 ,例如 为and %d{yyyyMMdd_HH}
,“超过 3 小时的文件”将被删除 maxHistory``3 。日志输出为 23:00的时候 删除了 3 小时以外的(20:00)所有文件。
日志存储每月的文件夹中,每天轮换创建新日志文件
在日期格式中%d{yyyyMM,aux}
指定选项,aux
属性数值。例如 代表每月文件夹的部分。
-
aux
是auxiliary
(auxiliary) 的缩写,这并%d
中使用aux标识文件轮换的时间。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="zht1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logback-zht.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>%d{yyyyMM,aux}/logback-zht-%d{yyyyMMdd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="zht1" />
</root>
</configuration>
------------------------ 时间格式 ----------------------------
日志文件都保存在对应的年月文件夹下
<fileNamePattern>%d{yyyyMM,aux}/logback-zht-%d{yyyyMMdd}.log</fileNamePattern>
压缩日志
需要压缩日志,在fileNamePattern属性中更改指定文件名的扩展名,它将zip
自动压缩。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="zht1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logback-zht.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logback-zht-%d{yyyyMMdd_HHmmss}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="zht1" />
</root>
</configuration>
7 Spring boot 基础配置
在spring boot项目中,logback.xml配置文件需要放在 src/main/resource 中,它会自动被程序加载到。
spring boot中logback.xml配置文件名称,最好推荐名“logback-spring.xml”
如果要更改配置文件的位置,请在 application.properties 中设置以下内容
logging.config=classpath:logback/logback-spring.xml
logging:
config: classpath:logback-spring.xml
level:
org.thymeleaf: info
org:
springframework:
boot:
autoconfigure:
logging: info
- 当解析 logback-spring.xml 时出现警告或错误时,控制台上会显示一条指示内部状态的消息。如果您希望消息显示时没有警告或错误,请将配置选项卡上的调试属性设置为 true。
- Spring Boot 提供了 logback 的默认设置。 通过将以下包含标签添加到 logback-spring.xml 来加载默认设置。
logback-spring.xml
<configuration debug="true">
<include resource="org/springframework/boot/logging/logback/base.xml" />
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
</configuration>
普通日志设置logback-spring.xml
<xml version="1.0" encoding="UTF-8">
<configuration debug="true">
<include resource="org/springframework/boot/logging/logback/base.xml" />
<appender name="zht1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logback-zht.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>%d{yyyyMMdd,aux}/logback-zht-%d{yyyyMMdd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="zht2" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="zht1" />
<appender-ref ref="zht2" />
</root>
</configuration>
自动保存与删除多余日志设置logback-spring.xml
<xml version="1.0" encoding="UTF-8">
<configuration>
<!-- 后台打印 -->
<appender name="zht1" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy/MM/dd HH:mm:ss} %-5level [%thread] - %msg%n</pattern>
</encoder>
</appender>
<!-- 日志保持到本地文件中 -->
<appender name="zht2" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志名称设置 -->
<file>/log/zht/app.log</file>
<!--日志按规则保持压缩文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/log/zht/app-%d{yyyy-MM-dd}.log.zip</fileNamePattern>
<maxHistory>3</maxHistory>
</rollingPolicy>
<!--日志输出格式 -->
<encoder>
<charset>UTF-8</charset>
<pattern>%d{yyyy/MM/dd HH:mm:ss} %-5level [%thread] - %msg%n</pattern>
</encoder>
</appender>
<!-- 保存日志 -->
<logger name="appLogger" level="INFO">
<appender-ref ref="zht2" />
</logger>
<!-- 后台输出日志 -->
<root level="INFO">
<appender-ref ref="zht1" />
</root>
</configuration>
日志使用方法
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
/** 指定日志类名称class **/
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@GetMapping("/test")
public void test() {
logger.info("访问");
}
}