SpringBoot 底层使用slf4j+logback 方式。
SpringBoot 也把其他日志替换成的 slf4j。
SpringBoot 能适配所有的日志,引入其他框架的时候需要把这个框架的依赖的日志框架排除掉。
日志门面(抽象层) | 日志实现 |
JCL SLF4j Jboss-logging | JUL log4j log4j2 logback |
如何让系统中所有日志统一到 sIf4j:
- 将系统中其他日志排除。
- 用中间包替换原有日志框架。
- 导入sIf4j其他实现。
LogBack配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--引入logback defaults.xml 带有默认的 输出格式-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!--配置自定义ip属性-->
<define name="localIp" class="com.eurekaclient3.config.IPLogDefiner"/>
<!--自定义获取Spring属性-->
<springProperty scope="context" name="logging.level.root" source="logging.level.root"/>
<springProperty scope="context" name="logging.console.level" source="logging.console.level"/>
<springProperty scope="context" name="logging.path" source="logging.splunk-file.path"/>
<springProperty scope="context" name="logging.name" source="logging.splunk-file.name"/>
<springProperty scope="context" name="logging.file.max-history" source="logging.splunk-file.max-history"/>
<springProperty scope="context" name="logging.file.max-size" source="logging.splunk-file.max-size"/>
<springProperty scope="context" name="logging.file.total-size-cap" source="logging.splunk-file.total-size-cap"/>
<springProperty scope="context" name="localPort" source="server.port"/>
<!-- springbootAdmin日志输出属性配置-->
<springProperty scope="context" name="spring.log.file" source="logging.file"/>
<springProperty scope="context" name="spring.log.max-size" source="logging.max-size"/>
<springProperty scope="context" name="spring.log.max-history" source="logging.max-history"/>
<springProperty scope="context" name="spring.log.total-size-cap" source="logging.total-size-cap"/>
<!-- springbootAdmin日志输出ERROR -->
<appender name="SPRING_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${spring.log.file}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${spring.log.file}.%d{yyyy-MM-dd}_%i</fileNamePattern>
<maxHistory>${spring.log.max-history:-1}</maxHistory>
<maxFileSize>${spring.log.max-size:-100MB}</maxFileSize>
<totalSizeCap>${spring.log.total-size-cap:-1GB}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS} %p] R[%X{traceId}%X{traceId},%X{spanId}%X{spanId}] (%C..%M:%L\)%n%m%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- DEBUG日志 appender -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logging.path}/debug_${logging.name}_${localIp}${localPort}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logging.path}/debug_${logging.name}_${localIp}${localPort}.log.%d{yyyy-MM-dd}_%i</fileNamePattern>
<maxHistory>${logging.file.max-history:-7}</maxHistory>
<maxFileSize>${logging.file.max-size:-100MB}</maxFileSize>
<totalSizeCap>${logging.file.total-size-cap:-1GB}</totalSizeCap>
</rollingPolicy>
<encoder>
<!--日志输出格式-->
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS} %p] R[%X{traceId}%X{traceId},%X{spanId}%X{spanId}] (%C..%M:%L\)%n%m%n</pattern>
</encoder>
<!--只接受debug类型日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- INFO日志 appender -->
<!--追加器以哪种方式进行输出(RollingFileAppender 为文件流)-->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logging.path}/info_${logging.name}_${localIp}_${localPort}.log</file>
<!--归档相关-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--归档文件名字-->
<fileNamePattern>${logging.path}/info_${logging.name}_${localIp}${localPort}.log.%d{yyyy-MM-dd}_%i</fileNamePattern>
<!--归档文件最大保存天数-->
<maxHistory>${logging.file.max-history:-7}</maxHistory>
<!--文件超过多少时归档-->
<maxFileSize>${logging.file.max-size:-100MB}</maxFileSize>
<!--每个归档文件最大值-->
<totalSizeCap>${logging.file.total-size-cap:-1GB}</totalSizeCap>
</rollingPolicy>
<!--日志内容的格式-->
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS} %p] R[%X{traceId}%X{traceId},%X{spanId}%X{spanId}] (%C..%M:%L\)%n%m%n</pattern>
</encoder>
<!--日志级别-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--什么级别以上的(trace("跟踪");debug("调试");info("信息");warn("警告");error("异常"))-->
<level>INFO</level>
<!--符合条件处理方式(DENY:跳出过滤器,不执行后续处理,类似循环中的black,NRUTRAL:继续下一个过滤器,ACCEPT:跳出过滤器,不做本过滤器处理,类似循环中的continue)-->
<!--ACCEPT(接受),DENY(拒绝),NEUTRAL(中立)-->
<onMatch>ACCEPT</onMatch>
<!--不符合条件处理方式DENY:跳出过滤器,不执行后续处理,类似循环中的black,NRUTRAL:继续下一个过滤器,ACCEPT:跳出过滤器,不做本过滤器处理,类似循环中的continue)-->
<!--ACCEPT(接受),DENY(拒绝),NEUTRAL(中立)-->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- WARN ERROR日志 appender -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logging.path}/error_${logging.name}_${localIp}${localPort}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logging.path}/error_${logging.name}_${localIp}${localPort}.log.%d{yyyy-MM-dd}_%i</fileNamePattern>
<maxHistory>${logging.file.max-history:-7}</maxHistory>
<maxFileSize>${logging.file.max-size:-100MB}</maxFileSize>
<totalSizeCap>${logging.file.total-size-cap:-1GB}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS} %p] R[%X{traceId}%X{traceId},%X{spanId}%X{spanId}] (%C..%M:%L\)%n%m%n</pattern>
</encoder>
<!--只接受warn以及以上级别日志-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<!--生产环境控制台日志输出控制-->
<springProfile name="pro">
<!--控制台输出日志 ,ConsoleAppender 为控制台类型的 appender-->
<appender name="NEW_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--日志内容格式,采用 defaults.xml 中的默认格式-->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
<!--控制台输出级别通过额外配置控制-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!--此配置在yaml中是 error-->
<level>${logging.console.level}</level>
</filter>
</appender>
</springProfile>
<!--开发测试环境控制台日志输出控制-->
<!--同springBoot中的(spring.profiles.active:) 可指定环境-->
<springProfile name="dev,uat,pre,test">
<!--控制台输出日志,控制台输出日志不额外控制-->
<appender name="NEW_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
</springProfile>
<!--全局日志控制,用来指定最基础的日志输出级别,ref 为上面配置的 appender name-->
<root level="${logging.level.root}">
<appender-ref ref="SPRING_ERROR"/>
<appender-ref ref="DEBUG"/>
<appender-ref ref="INFO"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="NEW_CONSOLE"/>
</root>
</configuration>
IPLogDefiner
package com.eurekaclient3.config;
import ch.qos.logback.core.PropertyDefinerBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.UUID;
public class IPLogDefiner extends PropertyDefinerBase {
private static final Logger LOG = LoggerFactory.getLogger(IPLogDefiner.class);
private String getUniqName() {
String localIp = null;
try {
localIp = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
LOG.error("fail to get ip...", e);
}
String uniqName = UUID.randomUUID().toString().replace("-", "");
if (localIp != null) {
uniqName = localIp + "-" + uniqName;
}
return uniqName;
}
@Override
public String getPropertyValue() {
return getUniqName();
}
}
yaml
logging:
#设置feign日志监控级别
level:
root: info #全局级别
com.eurekaclient3.feign.FeignService: debug
com.eurekaclient3.controller: trace
file:
name: ludb.log #日志的名字,如果没有设置路径则在项目根目录中, 也可以路径+文件名 D:/ludb.log
path: D:\workPackageLwj\workPackage\logs\ #不可以指定文件名称,仅能指定文件夹,默认使用spring.log记录
splunk-file:
path: D:\logs
name: ludb
注意:
日志级别由低到高:trace<debug<info<warn<error
SpringBoot 默认使用info级别日志。
给类路径下放置每个日志框架自己的配置文件后,SpringBoot 就不使用其他的默认配置了。
Logging System | Customization |
---|---|
Logback |
|
Log4j2 |
|
JDK (Java Util Logging) |
|
logback-spring.xml:由 SpringBoot 解析日志配置,可以使用:<springProfile name="pro"> 等 SpringBoot 配置信息。
logback.xml:直接被日志框架识别了。