简介
说明
logback是很好的一款日志框架,之前已经介绍过,见:
本文详细说明logback与SpringBoot如何整合。本文以最方便的整合方式进行实战,而且控制台的输出也是彩色的。
依赖关系
SpringBoot默认集成了logback,因此无需专门引入便可进行直接使用。其包的依赖关系如下:
配置文件
根据不同的日志系统,你可以按如下规则组织配置文件名,就能被正确加载:
Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
Log4j2:log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging):logging.properties
关于颜色
本文的所有配置在Idea执行都是彩色的,跟原来的输出颜色和格式是一样的。
博主也看过一些没有彩色输出的配置,没有彩色的输出就像看黑白两色的电影一样,真的绝绝子!????
实际上,完全可以配置成显示颜色的那个输出样式的,可以见本文的最后“多彩输出”。实例
注意
max-size设置的不要太小了,一般要大于10MB。如果设置太小,比如:100B,会导致子文件大小差别很大,而且太小了也没必要分文件了。
公共代码
测试代码
package com.example.demo.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class HelloController {
@GetMapping("/test1")
public void test1() {
while (true) {
log.info("进入到死循环");
}
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo_SpringBoot_logback</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo_SpringBoot_logback</name>
<description>demo_SpringBoot_logback</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
只用application.yml(最简配置)
application.yml
spring:
application:
name: demo
logging:
file:
# 如果写:demo.log,则会在jar包同路径下生成此日志文件。
name: D:/logs/${spring.application.name}/${spring.application.name}.log
level:
root: info
测试结果
启动(只会生成demo.log)
Idea的打印都是彩色的(后边有请求进来,它也是彩色的打印)
访问:http://localhost:8080/test1
确实生成了很多这种格式的文件:${LOG_PATH}/%d{yyyy-MM-dd}.%i.gz
解压(每个文本文件都是11.8MB左右)
查看其内容 (可得:demo.log若大小超过设定的值,会将这个大小的老数据切分出去,demo.log总是最新的,且大小永不会超过某个默认的值)
只用application.yml(日期+大小)
简介
优点
- 使用简单。
- 基本满足项目需求。
缺点
不能进行更详细的配置,比如:
- 不能配置将不同的级别的日志输出到不同文件
application.yml
spring:
application:
name: demo
logging:
file:
# 如果写:demo.log,则会在jar包同路径下生成此日志文件。
name: D:/logs/${spring.application.name}/${spring.application.name}.log
max-size: 20MB
level:
root: info
pattern:
rolling-file-name: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
测试结果
启动(只会生成demo.log)
Idea的打印都是彩色的(后边有请求进来,它也是彩色的打印)
访问:http://localhost:8080/test1
确实生成了很多这种格式的文件:${LOG_PATH}/%d{yyyy-MM-dd}.%i.log,每个文件大小都是20M左右
查看其内容 (可得:demo.log若大小超过设定的值,会将这个大小的老数据切分出去,demo.log总是最新的,且大小永不会超过设定的值)
application.yml+xml(日期+大小)
application.yml
spring:
application:
name: demo
logging:
file:
path: logs
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<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"/>
<!--<include resource="org/springframework/boot/logging/logback/file-appender.xml" />-->
<springProperty scope="context" name="appName" source="spring.application.name"/>
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<prudent>true</prudent>-->
<file>${LOG_PATH}/${appName}.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_PATH}/%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="logFile"/>
</root>
</configuration>
测试结果
启动(只会生成demo.log)
Idea的打印都是彩色的(后边有请求进来,它也是彩色的打印)
访问:http://localhost:8080/test1
确实生成了很多这种格式的文件:${LOG_PATH}/%d{yyyy-MM-dd}.%i.log
到文件浏览器下看:(每个文件大小都是20M左右)
application.yml+xml(只日期)(不推荐)
application.yml
spring:
application:
name: demo
logging:
file:
path: D:/logs
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<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"/>
<!--<include resource="org/springframework/boot/logging/logback/file-appender.xml" />-->
<springProperty scope="context" name="appName" source="spring.application.name"/>
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--<prudent>true</prudent>-->
<!--<file>${LOG_PATH}/${appName}.log</file>-->
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
${LOG_PATH}/${appName}/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
</FileNamePattern>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="logFile"/>
</root>
</configuration>
测试结果
启动(只会生成${LOG_PATH}/${appName}/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log)
Idea的打印都是彩色的(后边有请求进来,它也是彩色的打印)
访问:http://localhost:8080/test1
会一直往这天对应的文件里边写日志,不管大小
application.yml配置
综述
所有配置项
Spring的Envrionment到系统属性的转换
Spring Environment | System Property | Comments |
logging.exception-conversion-word | LOG_EXCEPTION_CONVERSION_WORD | 在记录异常时使用的转换字。 |
logging.file.name | logging.file | 如果定义,在默认的日志配置中使用 |
logging.file.path | LOG_PATH | 如果定义,在默认的日志配置中使用 |
logging.pattern.console | logging.pattern.console | 日志模式使用控制台(stdout)。(只支持默认logback设置。) |
logging.pattern.file | FILE_LOG_PATTERN | 日志模式中要使用的文件(如果log_file启用)。(只支持默认logback设置。) |
logging.pattern.levelFILE | LOG_LEVEL_PATTERN | 格式来呈现的日志级别(默认为5P)。(只支持默认logback设置。) |
PID | PID | 当前的处理进程(process)ID(如果能够被发现且还没有作为操作系统环境变量被定义) |
比如:定义logging.file.path=logs,那么在logback-spring.xml中,可以直接用${LOG_PATH}来使用。
指定配置文件
Spring Boot 的 logback 默认使用 src/main/resources 目录下的 logback.xml 或 logback-spring.xml 作为配置文件。Spring Boot 官方推荐使用 logback-spring.xml,因为可以在日志输出的时候引入一些 Spring Boot 特有的配置项。
也可指定配置文件: logging.config=classpath:logback-confg.xml
其他:由于日志是在ApplicationContext被创建之前初始化的,所以不可能在Spring的@Configuration文件中通过@PropertySources控制日志。系统属性和平常的Spring Boot外部配置文件能正常工作
日志级别设置
法1:application.yml的logging.level.*
默认为INFO。下面两种格式常用:
- logging.level.root=WARN # root 日志以 WARN 级别输出信息;
- logging.level.com.example.a=DEBUG # 指定包下的类以 DEBUG 级别输出;
级别从高到低:OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL
法2:命令行控制
java -jar D:\demo.jar --debug
法3: application.yml的debug
debug=true
该属性置为true时,核心Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但你自己应用的日志并不会输出为DEBUG级别。
指定日志文件
设置 logging.file.name 或者 logging.file.path:
- logging.file.name
设置日志文件:支持绝对路径、相对路径,相对路径的话是相对应用的根目录,比如 logging.file.name=logs/demo.log;
默认:spring.log - logging.file.path
设置日志路径:支持绝对路径、相对路径,比如 logging.file.path=logs,日志文件默认会存为 spring.log;
默认:根路径/LOG_PATH_IS_UNDEFINED/
logging.file.name | logging.file.path | 描述 | 示例 |
不指定 | 不指定 | 只记录到控制台 | |
指定 | 不指定 | 记录到:指定文件 | logging.file.name=demo.log #在项目路径下生成demo.log logging.file.name=logs/demo.log #在项目路径下生成logs/demo.log logging.file.name=e:/logs/demo.log #生成:e:/logs/demo.log |
不指定 | 指定 | 记录到:指定路径/spring.log | logging.file.path=logs #在项目路径下生成logs/spring.log logging.file.path=e:/logs/ #生成:e:/logs/spring.log |
注意:若我们只配置application.yml而不提供xml文件,若配置了logging.file.name 或者 logging.file.path,则必须配置:logging.level.*,否则,将没有任何日志产生。
比如:
logging:
file:
name: demo.log
level:
root: info
此时,将会生成:项目根路径/demo.log
分组
日志级别
批量设置日志级别,比如设定com.michael.controller 和 com.michael.service为同一组(包和包之间用英文逗号分隔):
logging.group.michael=com.michael.controller,com.michael.service
logging.level.michael=INFO
Spring Boot 默认提供两个日志组:
- logging.group.web=org.springframework.core.codec,org.springframework.http,org.springframework.web
- logging.group.sql=org.springframework.jdbc.core
其他配置
- logging.file.max-size
- 最大日志文件大小。默认为10MB。
- logging.file.max-history
- 最大归档文件保存的天数。默认为7
- logging.pattern.console
- 控制台输出的日志模式。默认如下
-
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
- logging.pattern.dateformat
- 日志的日期格式。默认为:yyyy-MM-dd HH:mm:ss.SSS
- logging.pattern.file
- 日志文件使用的日志模式。默认为:
-
%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
- logging.pattern.level
- 日志级别。默认为:%5P
- logging.pattern.rolling-file-name
- 文件超过max-size时保存的日志的的文件名。默认为:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
- %i:若一天中多次超过了max-size,则给这些文件添加序号。
- 若不想压缩,可以将gz去掉或者改掉,比如:${LOG_FILE}.%d{yyyy-MM-dd}.%i.log
XML
SpringBoot默认配置
SpringBoot的logback的默认配置效果就很好,可以打印彩色,其配置位置见:spring-boot-2.3.12.RELEASE.jar\org\springframework\boot\logging\logback\defaults.xml
源码:(控制台颜色配置见:<property name="CONSOLE_LOG_PATTERN")
<?xml version="1.0" encoding="UTF-8"?>
<!--
Default logback configuration provided for import
-->
<included>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
</included>
我把它单独拿出来:
${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}
logback-spring.xml(示例)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<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"/>-->
<!--<include resource="org/springframework/boot/logging/logback/file-appender.xml" />-->
<springProperty scope="context" name="appName" source="spring.application.name"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${appName}.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_PATH}/%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="logFile"/>
</root>
</configuration>
ELK
如果项目中的日志采用的是基于ELK(Elasticsearch,Logstash,Kibana三个开源软件的缩写)来进行日志管理。则可以在pom文件中引入logstash-logback-encoder依赖。
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.1</version>
</dependency>
然后在logback-spring.xml中配置对应的appender:
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<destination>192.168.0.11:5061</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"project": "springboot-logback-elk"}</customFields>
</encoder>
</appender>
该appender的使用与其他appender的使用无异。主要使用了LogstashTcpSocketAppender类来完成与Logstash的通信。其中destination为Logstash提供的服务地址。customFields为自定义的参数,便于Logstash识别日志是从哪个业务系统传输过来的。
输出logback状态
有时为了了解logback配置文件加载情况,配置中对应的appender、logger的装载情况等,我们需要启用logback状态数据的输出。这也是logback官网强烈推荐的,可以帮助我们排除诊断一些问题。
方案1:添加元素(statusListener)
logback-spring.xml:
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
方案2:启用调试(不推荐)
application.yml
debug=true
多环境
SpringBoot项目,针对不同环境(profile)有不同的日志输出,比如:开发(dev)环境只输出CONSOLE的,生产环境(prod)只输出info和error,那则可用到Spring支持的profile机制。对应的元素为springProfile。
profile的值与springboot中配置文件的spring.profiles.active值对应。
<!-- 开发环境 -->
<springProfile name="dev">
<logger name="com" level="debug" />
<root level="info">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<!-- 测试环境+生产环境 -->
<springProfile name="test,prod">
<logger name="com" level="info" />
<root level="info">
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</springProfile>
多彩输出
application.yml配置
如果你的终端支持ANSI,设置彩色输出会让日志更具可读性。通过在application.properties中设置spring.output.ansi.enabled参数来支持,默认为:detect。
never:禁用ANSI-colored输出
detect:会检查终端是否支持ANSI,是的话就采用彩色输出(推荐项)
always:总是使用ANSI-colored格式输出,若终端不支持的时候,会有很多干扰信息,不推荐使用
级别 | 颜色 |
FATAL | 红色 |
ERROR | 红色 |
WARN | 黄色 |
INFO | 绿色 |
DEBUG | 绿色 |
TRACE | 绿色 |
手动指定颜色
可以指定将其作为转换选项的颜色或样式。例如,使文本黄色:
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
支持以下颜色和样式:
1. blue
2. cyan
3. faint
4. green
5. magenta
6. red
7. yellow