SpringBoot优雅地配置⽇志
本⽂主要给⼤家介绍SpringBoot中如何通过sl4j⽇志组件优雅地记录⽇志。其实,我们⼊门 JAVA 的第⼀⾏代码就是⼀⾏⽇志,那你现在还在使⽤System.out.println("Hello,⼩明!")记录⽇志吗?
我经历过的⽇志组件
我最开始接触的⽇志组件是Log4j
Log4j 作为Apache的⼀个开放源代码的项⽬,通过使⽤Log4j,我们可以控制⽇志信息输送的⽬的地是控制台、⽂件等我们期望它输出到的地⽅;我们也可以控制每⼀条⽇志的输出格式;通过定义每⼀条⽇志信息的级别,我们能够更加细致地控制⽇志的⽣成过程。
我们可以通过⼀个配置⽂件来灵活地进⾏上⾯的配置,⽽不需要修改应⽤的代码。Log4j作为当时作为最先⽐较流⾏的⽇志框架,给我们在应⽤开发和维护带来了很⼤的便捷。
但是,如今还是慢慢的⾛下“神坛”呢,逐渐被Logback替代,众⾥寻她千百度,原来Logback是升级版,相对Log4j⽽⾔有了更多的改进,⽽且开发⼈员竟然是同班⼈马(其实就是⼀个⼈写的)!
新星Logback
Logback主要有下⾯的特性:
1. 更快的执⾏速度:基于我们先前在Log4j上的⼯作,Logback 重写了内部的实现,在某些特定的场景上⾯,甚⾄可以⽐之前的速度快上
10倍。在保证Logback的组件更加快速的同时,同时所需的内存更加少;
2. 充分的测试:Logback 历经了⼏年,数不清⼩时数的测试。尽管Log4j也是测试过的,但是Logback的测试更加充分,跟Log4j不在同
⼀个级别。我们认为,这正是⼈们选择Logback⽽不是Log4j的最重要的原因。谁不希望即使在恶劣的条件下,你的⽇志框架依然稳定⽽可靠呢?
由三个模块组成
logback-core
logback-classic
logback-access
logback-core是其它模块的基础设施,其它模块基于它构建,显然,logback-core提供了⼀些关键的通⽤机制。logback-classic的地位和作⽤等同于Log4J,它也被认为是Log4J的⼀个改进版,并且它实现了简单⽇志门⾯SLF4J;⽽logback-access主要作为⼀个与Servlet容器交互的模块,⽐如说tomcat或者jetty,提供⼀些与HTTP访问相关的功能。
那Sl4J⼜是什么?
slf4j:The Simple Logging Facade for Java 即java的简单⽇志门⾯
简答的讲就是slf4j是⼀系列的⽇志接⼝,slf4j是作为⼀个⽇志的抽象⾏为存在的,但是并没有提供真正的实现。
slf4j为各种⽇志框架提供了⼀个统⼀的界⾯,使⽤户可以⽤统⼀的接⼝记录⽇志,动态地决定要使⽤的实现框架,⽐如
Logback,Log4j,common-logging等框架都实现了这些接⼝。
我是如何配置⽇志的?
路⼈皆知,Springboot默认使⽤的⽇志框架是Logback。顺势⽽为,在项⽬中,我们使⽤Logback,其实只需增加⼀个配置⽂件(⾃定义你的配置)即可。
配置⽂件详解
配置⽂件精简结构如下所⽰
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 属性⽂件:在properties/yml⽂件中到对应的配置项 -->
<springProperty scope="context" name="logging.path" source="logging.path"/>
<contextName>程序员⼩明</contextName>
<appender>
//xxxx
</appender>
<logger>
//xxxx
</logger>
<root>
//xxxx
</root>
</configuration>
这个⽂件在springboot中默认叫做l,我们只要新建⼀个同名⽂件放在resources下⾯,配置即可⽣效。
每个配置的解释如下所⽰:
contextName
每个logger都关联到logger上下⽂,默认上下⽂名称为“default”。但可以使⽤contextName标签设置成其他名字,⽤于区分不同应⽤程序的记录
property
⽤来定义变量值的标签,property标签有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过property定义的值会被插⼊到logger上下⽂中。定义变量后,可以使“${name}”来使⽤变量。如上⾯的xml所⽰。
logger
⽤来设置某⼀个包或者具体的某⼀个类的⽇志打印级别以及指定appender。
root
根logger,也是⼀种logger,且只有⼀个level属性
appender
负责写⽇志的组件
appender 的种类
ConsoleAppender:把⽇志添加到控制台
FileAppender:把⽇志添加到⽂件
RollingFileAppender:滚动记录⽂件,先将⽇志记录到指定⽂件,当符合某个条件时,将⽇志记录到其他⽂件。它是FileAppender的⼦类
filter
filter其实是appender⾥⾯的⼦元素。它作为过滤器存在,执⾏⼀个过滤器会有返回DENY,NEUTRAL,ACCEPT三个枚举值中的⼀个。
DENY:⽇志将⽴即被抛弃不再经过其他过滤器
NEUTRAL:有序列表⾥的下个过滤器过接着处理⽇志
ACCEPT:⽇志会被⽴即处理,不再经过剩余过滤器
有以下⼏种过滤器
ThresholdFilter
临界值过滤器,过滤掉低于指定临界值的⽇志。当⽇志级别等于或⾼于临界值时,过滤器返回NEUTRAL;当⽇志级别低于临界值时,⽇志会被拒绝。
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
LevelFilter
级别过滤器,根据⽇志级别进⾏过滤。如果⽇志级别等于配置级别,过滤器会根据onMath(⽤于配置符合过滤条件的操作) 和
onMismatch(⽤于配置不符合过滤条件的操作)接收或拒绝⽇志。
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
项⽬实例
准备
⼀个简单正常的Springboot项⽬
配置⽂件
有关⽇志的简单配置,我们可以直接在l中进⾏简单的配置,⽐如指明⽇志的打印级别和⽇志的输出位置
logging:
level:
root: info
path: ./logs
也可以根据分环境配置指明使⽤的配置⽂件,缺省为l
logging:
level:
root: info
path: ./logs
config: classpath:/l
在resources⽬录下新建l⽂件,举例⼀个简单的需求,如果在项⽬中我们如果需要指定⽇志的输出格式以及根据⽇志级别输出到不同的⽂件,可以配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 属性⽂件:在properties⽂件中到对应的配置项 -->
<springProperty scope="context" name="logging.path" source="logging.path"/>
<contextName>xiaoming</contextName>
<appender name="consoleLog" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.PatternLayoutEncoder">
<!--格式化输出(配⾊):%d表⽰⽇期,%thread表⽰线程名,%-5level:级别从左显⽰5个字符宽度%msg:⽇志消息,%n是换⾏符-->
<pattern>%yellow(%d{yyyy-MM-dd HH:mm:ss}) %red([%thread]) %highlight(%-5level) %cyan(%logger{50}) - %magenta(%msg) %n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--根据⽇志级别分离⽇志,分别输出到不同的⽂件-->
<appender name="fileInfoLog" class="ch.olling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder class="ch.qos.der.PatternLayoutEncoder">
springboot框架的作用<pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
<!--按时间保存⽇志修改格式可以按⼩时、按天、⽉来保存-->
<fileNamePattern>${logging.path}/xiaoming.info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!--保存时长-->
<MaxHistory>90</MaxHistory>
<!--⽂件⼤⼩-->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="fileErrorLog" class="ch.olling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${logging.path}/%d{yyyy-MM-dd}.log</fileNamePattern>
<MaxHistory>90</MaxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="consoleLog"/>
<appender-ref ref="fileInfoLog"/>
<appender-ref ref="fileErrorLog"/>
</root>
</configuration>
再⽐如如果粒度再细⼀些,根据不同的模块,输出到不同的⽂件,可以如下配置
<!--特殊功能单独appender 例如调度类的⽇志-->
<appender name="CLASS-APPENDER" class="ch.olling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${logging.path}/mkc.class.%d{yyyy-MM-dd}.log</fileNamePattern>
<MaxHistory>90</MaxHistory>
</rollingPolicy>
</appender>
<!--这⾥的name和业务类中的getLogger中的字符串是⼀样的-->
<logger name="xiaoming" level="INFO" additivity="true">
<appender-ref ref="CLASS-APPENDER" />
</logger>
正常情况下xiaoming是指的
private Logger xiaoming = Logger("xiaoming");
如果我们使⽤的是lomok插件,则xiaoming指的是topic
@Slf4j(topic = "xiaoming")
public class XiaoMingTest {
}
其他
⼩明⽬前⽤到的就这么多啦,更多的⽇志配置场景,⼤家可以访问:
有什么问题,欢迎⼤家留⾔~
欢迎关注”程序员⼩明”,获取更多资源。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论