springboot集成logback
配置:
关于日志系统的配置文件,官方推荐我们使用logback-spring.xml 而不是 logback.xml
因此我们在resources(classpath路径)下创建一个名为logback-spring.xml的配置文件。
代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<conversionRule conversionWord="serverIp" converterClass="com.lmes.contract.config.LogIpConfig" />
<property name="logback.logdir" value="@profileLogdir@" defaultValue="./logs" />
<property name="SystemCode" value="L115" />
<springProperty scope="context" name="applicationName" source="spring.application.name" defaultValue="lmes-app" />
<springProperty scope="context" name="serverPort" source="server.port" defaultValue="8080" />
<contextName>${applicationName}</contextName>
<!--输出到控制台 ConsoleAppender -->
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern>
</pattern>
</layout>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高, 所以我们使用下面的策略,可以避免输出 Error 的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ALL</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。 -->
<File>${logback.logdir}/${applicationName}/logs/info.${applicationName}.log</File>
<!--滚动策略,按照大小和时间滚动 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间 -->
<FileNamePattern>${logback.logdir}/${applicationName}/logs/info.${applicationName}.log.%d{yyyy-MM-dd}.%i</FileNamePattern>
<maxFileSize>1GB</maxFileSize>
</rollingPolicy>
<!--日志输出编码格式化 -->
<encoder>
<charset>UTF-8</charset>
<pattern>%d|%level|${serverPort}|%class|%method|${SystemCode}|%serverIp|%X{traceId}|${applicationName}|1|%msg %replace(%ex{full}){"[\r\n]+", "###"} %nopex|$|$|%n</pattern>
</encoder>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>Error</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。 -->
<File>${logback.logdir}/${applicationName}/logs/error.${applicationName}.log</File>
<!--滚动策略,按照大小和时间滚动 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间 -->
<FileNamePattern>${logback.logdir}/${applicationName}/logs/error.${applicationName}.log.%d{yyyy-MM-dd}.%i</FileNamePattern>
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<!--日志输出编码格式化 -->
<encoder>
<charset>UTF-8</charset>
<pattern>%d|%level|${serverPort}|%class|%method|${SystemCode}|%serverIp|%X{traceId}|${applicationName}|1|%msg|$|$|%n</pattern>
</encoder>
</appender>
<appender name="fileWarnLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 DEBUG 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 DEBUG -->
<level>WARN</level>
<!--匹配到就允许 -->
<onMatch>ACCEPT</onMatch>
<!--没有匹配到就禁止-->
<onMismatch>DENY</onMismatch>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。 -->
<File>${logback.logdir}/${applicationName}/logs/warn.${applicationName}.log</File>
<!--滚动策略,按照大小和时间滚动 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间 -->
<FileNamePattern>${logback.logdir}/${applicationName}/logs/warn.${applicationName}.log.%d{yyyy-MM-dd}.%i</FileNamePattern>
<maxFileSize>20MB</maxFileSize>
</rollingPolicy>
<!--日志输出编码格式化 -->
<encoder>
<charset>UTF-8</charset>
<pattern>%d|%level|${serverPort}|%class|%method|${SystemCode}|%serverIp|%X{traceId}|${applicationName}|1|%msg|$|$|%n</pattern>
</encoder>
</appender>
<!--指定最基础的日志输出级别 -->
<root level="INFO">
<!--appender将会添加到这个loger -->
<appender-ref ref="fileInfoLog" />
<appender-ref ref="fileWarnLog" />
<appender-ref ref="fileErrorLog" />
<appender-ref ref="consoleLog" />
</root>
</configuration>
然后nacos配置文件中指定日志系统使用的配置文件,如下图所示:
使用:
使用的方法有两种
- 在类头上使用@slf4j注解
-
手动创建Logger对象
看到16行和19行,就分别是我们上面说到的两种方式,40和41行就是关于日志输出的使用。
常用Appender
AsyncAppender
AsyncAppender并不处理日志,只是将日志缓冲到一个BlockingQueue里面去,并在内部创建一个工作线程从队列头部获取日志,之后将获取的日志循环记录到附加的其他appender上去,从而达到不阻塞主线程的效果。因此AsynAppender仅仅充当事件转发器,必须引用另一个appender来做事。
默认情况下,AsyncAppender会在队列满80%的情况下删除TRACE、DEBUG和INFO级别的事件。这种策略以事件损失为代价,对性能有惊人的有利影响。
由于使用了BlockingQueue来缓存日志,因此就会出现队列满的情况,默认情况下,AsyncAppender会在队列满80%的情况下删除TRACE、DEBUG和INFO级别的事件。这种策略以事件损失为代价,对性能有惊人的有利影响。
queueSize:blockingQueue长度决定了队列能放多少信息,在默认的配置下,如果blockingQueue放满了,后续想要输出日志的线程会被阻塞,直到Worker线程处理掉队列中的信息为止。根据实际情况适当调整队列长度,可以防止线程被阻塞。
discardingThreshold:为了提高性能,默认情况下,当事件添加到事件队列时,不会提取与事件关联的调用者数据。默认情况下,只复制像线程名和MDC这样的“廉价”数据。您可以通过将inclecallerdata属性设置为true来引导这个appender包含调用者数据。
maxFlushTime:根据队列深度和被引用的appender的延迟,AsyncAppender可能会花费不可接受的时间来完全刷新队列。当LoggerContext停止时,AsyncAppender stop方法将等待工作线程完成此超时。使用maxFlushTime指定以毫秒为单位的最大队列刷新超时。无法在此窗口内处理的事件将被丢弃。该值的语义与Thread.join(long)相同。
neverBlock:如果为false(默认值),代表在队列放满的情况下是否卡住线程,不会丢失消息。当队列满了时,会阻塞业务线程,此时异步处理会变成同步等待;只有队列有可用容量时,业务线程才从阻塞状态恢复。如果配置neverBlock=true,当队列满了之后,后面阻塞的线程想要输出的消息就直接被丢弃,从而线程不会阻塞。
详解见:(17条消息) logback教程logback快速入门超实用详细教程收藏这一篇就够了(万字长文)_「已注销」的博客-CSDN博客