根节点<configuration>
包含的属性
- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
<configuration>
下面一共有2个属性,3个子节点,分别是:
属性一:设置上下文名称<contextName>
每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用<contextName>
设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改,可以通过%contextName
来打印日志上下文名称。
<contextName>logback</contextName>
属性二:设置变量<property>
用来定义变量值的标签,<property>
有两个属性,name
和value
;其中name的值是变量的名称,value的值时变量定义的值。通过<property>定义的值会被插入到logger上下文中。定义变量后,可以使${}
来使用变量。
<property name="log.path" value="E:\\logback.log" />
变量有三个作用域:
- local
- context
- system
local 作用域在配置文件内有效,context 作用域的有效范围延伸至 logger context,system 作用域的范围最广,整个 JVM 内都有效。
logback 在替换变量时,首先搜索 local 变量,然后搜索 context,然后搜索 system。
<property scope="context" name="nodeId" value="firstNode" />
也可以通过外部文件来定义:
<property file="src/main/java/chapters/configuration/variables1.properties" />
子节点一:<appender>
appender
用来格式化日志输出节点,有俩个属性name
和class
,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
1、控制台输出ConsoleAppender:
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
ThresholdFilter为系统定义的拦截器,例如我们用ThresholdFilter来过滤掉ERROR级别以下的日志不输出到文件中。如果不用记得注释掉,不然你控制台会发现没日志~
2、输出到文件RollingFileAppender
另一种常见的日志输出到文件,随着应用的运行时间越来越长,日志也会增长的越来越多,将他们输出到同一个文件并非一个好办法。
RollingFileAppender用于切分文件日志:
<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logback.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<fileNamePattern>logback.%d{yyyy-MM-dd}.log</fileNamePattern>
定义了日志的切分方式——把每一天的日志归档到一个文件中。<maxHistory>30</maxHistory>
表示只保留最近30天的日志,以防止日志填满整个磁盘空间。同理,可以使用%d{yyyy-MM-dd_HH-mm}
来定义精确到分的日志切分方式。<totalSizeCap>1GB</totalSizeCap>
用来指定日志文件的上限大小,例如设置为1GB的话,那么到了这个值,就会删除旧的日志。
子节点二:<root>
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。
<root level="debug">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
子节点三: <loger>
<loger>
用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>
。
<loger>
仅有一个name
属性,一个可选的level
和一个可选的addtivity
属性。
if表达式(条件化处理配置文件)
logback 允许在配置文件中定义条件语句,以决定配置的不同行为,
<!-- if-then form -->
<if condition="some conditional expression">
<then>
...
</then>
</if>
<!-- if-then-else form -->
<if condition="some conditional expression">
<then>
...
</then>
<else>
...
</else>
</if>
常用条件表达式函数
1. property('key')
2. isDefined('key')
3. isNull("key")
文件包含
可以使用 ≶include> 标签在一个配置文件中包含另外一个配置文件。
<configuration>
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
<root level="DEBUG">
<appender-ref ref="includedConsole" />
</root>
</configuration>
被包含的文件必须有以下格式:
<included>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>"%d - %m%n"</pattern>
</encoder>
</appender>
</included>
支持从多种源头包含
- 从文件中包含
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
- 从 classpath 中包含
<include resource="includedConfig.xml"/>
- 从 URL 中包含
<include url="http://some.host.com/includedConfig.xml"/>
如果包含不成功,那么 logback 会打印出一条警告信息,如果不希望 logback 抱错,只需这样做:
<include optional="true" ..../>
添加一个 Context Listener
LoggerContextListener
接口的实例能监听 logger context 上发生的事件,比如说日志级别的变化,添加的方式如下所示:
<configuration debug="true">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
....
</configuration>
多环境日志输出
据不同环境(prod:生产环境,test:测试环境,dev:开发环境)来定义不同的日志输出。
文件名称不是logback.xml,想使用spring扩展profile支持,要以logback-spring.xml命名
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
<logger name="com.dudu.controller" level="info" />
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
<logger name="com.dudu.controller" level="ERROR" />
</springProfile>
1,blockingQueue长度。
blockingQueue长度决定了队列能放多少信息,在默认的配置下,如果blockingQueue放满了,后续想要输出日志的线程会被阻塞,直到Worker线程处理掉队列中的信息为止。根据实际情况适当调整队列长度,可以防止线程被阻塞。
2,immediateFlush=false。不立即清空输出流。
immediateFlush参数可以配置在<appender>里面,默认是true,代表是否立即刷新OutputStream中的信息。如果设置为false,会在OutputStream放满或隔断时间进行flush,具体由OutputStream类决定。据说设置为false之后输出日志的效率能提高为原来的4倍。
官网说:setting thisproperty to 'false' is likely to quadruple (your mileage may vary) loggingthroughput.
3,neverBlock=true。队列满了也不卡线程
neverBlock参数可以配置在<appender>里面,默认是false,代表在队列放满的情况下是否卡住线程。也就是说,如果配置neverBlock=true,当队列满了之后,后面阻塞的线程想要输出的消息就直接被丢弃,从而线程不会阻塞。这个配置用于线程很重要,不能卡顿,而且日志又不是很重要的场景,因为很有可能会丢日志。
4,自定义appender
开发者可以自己写一个appender类,需要继承AppenderBase<LoggingEvent>类并重写append(LoggingEventeventObject)方法,然后像别的appender一样配置到logback.xml里面,就可以定义自己的日志输出方式了。
logback的日志级别动态调整:
方案一:开启logback的自动扫描更新<configuration scan="true"
方案二:自定义api logger.setLevel(ch.qos.logback.classic.Level.toLevel(level));
方案三:springboot的Actuator的loggers的endpoint
发送POST 请求到 http://localhost:8080/actuator/loggers/com.xxx.aa,其中请求 Body 的内容如下:{ "configuredLevel": "DEBUG" }
方案四 集成springcloudadmin来动态修改配置