logback配置文件语法
# 配置文件的结构
因为logback的配置十分灵活,所以无法通过一个DTD文件或者XML Schema来指定允许的语法。
# 标签名区分大小写
对于特定的标签名字是大小写不敏感的,比如<logger>
, <Logger>
和 <LOGGER>
都是合法的配置,但是<xyz>
只能用</xyz>
关闭,不能是<XyZ>
,但是针对驼峰规则是适用的,比如<xyz>
只能用</Xyz>
关闭,不能是<xYz>
。驼峰规则可以参考维基百科camelCase convention (opens new window)
# configuration标签
根标签,其中可以包含:
- Appender
- Logger
- Root
- property
# logger标签
- name(string): 必填,logger的名称
- additivity(boolean):选填,是否最累加Appender(是否继承是用父logger的Appender)
- level(TRACE,DEBUG,INFO,WARN,ERROR,ALL,OFF,INHERITED):选填,不填则同INHERITED,代表继承父logger的日志级别,大小写不敏感。
- appender-ref:选填,子标签(非属性),可以配置多个。中有ref标签指定Appender的name.
# root标签
在整个配置文件中只能存在一个,可以当做是一个name为"ROOT"的Logger标签,但是不能有additivity属性,全局只能存在一个。
- level(TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF):选填,不填则默认为debug
- appender-ref:同logger
# appenders标签
name(string):必填,名称,用于引用
class(string):必填,Appender全限定类名,指定Appender
<encoder>
<layout>
<filter>
# 设置上下文名称
每个logger都属于loggerContext, loggerContext默认的名字是“default”,这个名字可以设置
<configuration>
<contextName>myAppName</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %contextName [%t] %level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
# 定义变量
可以用<property>
定义变量,在 1.0.7 版本之后可以使用<variable>
互换。
可以通过file属性引入指定路径的properties文件进行变量填充。
通过resource属性可以加载classpath下面的properties文件。
可以通过${xxx}读取变量,可以是声明的变量,也可以是System.properties
<configuration>
<property name="USER_HOME" value="/home/sebastien" />
<property file="src/main/java/resource/var.properties" />
<property resource="resource1.properties" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${USER_HOME}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 变量的范围
${xxx}到底可以引用哪些地方的变量呢?
读取顺序依次:
- 配置文件直接定义的
- LoggerContext
- VM的参数列表
- 环境变量
可以通过scope指定property的作用域,可选值:"local", "context" 和 "system",不填默认为local
定义一个context作用域的变量:
<configuration>
<property scope="context" name="nodeId" value="firstNode" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>/opt/${nodeId}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
# 变量的默认值
可以通过 -: 操作符合来使用默认值,比如${LOG_DIR -: /path/logdir}
如果LOG_DIR在域中取不到,则用默认值/path/logdir
# 变量的嵌套
名称和值都是支持嵌套的,默认值中也可以使用。
假设 userid=uncle
比如{{userid}.password},可能值就是变为取${uncle.password}这个变量的值。
{id:-{userid}},id不存在则返回uncle
# 设置时间戳
可以定义一个根据当前时间的动态变化的变量。
- key:引用名字
- datePattern:时间格式化,和Java的SimpleDateFormat一样。
- timeReference 设置值“contextBirth”为logback启动时间,不写默认为当前时间
<configuration>
<!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
the key "bySecond" into the logger context. This value will be
available to all subsequent configuration elements. -->
<timestamp key="now" datePattern="yyyyMMdd'T'HHmmss"/>
<timestamp key="startTime" datePattern="yyyyMMdd'T'HHmmss"
timeReference="contextBirth"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- use the previously created timestamp to create a uniquely
named log file -->
<file>log-${bySecond}.txt</file>
<encoder>
<pattern>%logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 定义动态的变量
通过define标签定义变量,name为变量的值,class为PropertyDefiner接口的实现类,其中的属性是将会通过setter注入这个类,最后这个类的getPropertyValue()方法将为name对应的值。
目前已经有的实现类:
- FileExistsPropertyDefiner 变量为主机名
- ResourceExistsPropertyDefiner 校验文件是否存在
- CanonicalHostNamePropertyDefiner 校验资源是否存在
可间一般用于动态获取一些值。
<configuration>
<define name="rootLevel" class="a.class.implementing.PropertyDefiner">
<shape>round</shape>
<color>brown</color>
<size>24</size>
</define>
<root level="${rootLevel}"/>
</configuration>
2
3
4
5
6
7
8
9
10
# 条件判断
需要依赖Janino库,支持嵌套
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.6</version>
</dependency>
2
3
4
5
例子:
其中property可以简写为p,语法和java中字符串语法一样
<configuration debug="true">
<if condition='property("HOSTNAME").contains("torino")'>
<then>
<appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root>
<appender-ref ref="CON" />
</root>
</then>
</if>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${randomOutputDir}/conditional.log</file>
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="ERROR">
<appender-ref ref="FILE" />
</root>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 从JNDI中获取变量
从JNDI中检索一个AppName的值,赋值给contextName。
<configuration>
<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />
<contextName>${appName}</contextName>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d ${CONTEXT_NAME} %level %msg %logger{50}%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
# 配置引入
可以通过include标签引入一个配置从其他xml中
include:可以多种方式
- resource:类路径
- url:web
- file: 文件路径
include如果引入文件不存在,则会报告这个错误信息,如果想不报,可以使用属性 optional="true"
<configuration>
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
<root level="DEBUG">
<appender-ref ref="includedConsole" />
</root>
</configuration>
2
3
4
5
6
7
8
includedConfig.xml:
<included>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>"%d - %m%n"</pattern>
</encoder>
</appender>
</included>
2
3
4
5
6
7
# 日志级别改变传播器
0.9.25版本开始, logback-classic附带了LevelChangePropagator,是LoggerContextListener的实现类,用于监控日志等级改变,然后传输到java.util.logging框架中,这种传播消除了禁用日志语句对性能的影响
<configuration debug="true">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
....
</configuration>
2
3
4
设置resetJUL属性来实现日志等级改变时重置jcl。
<configuration debug="true">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
....
</configuration>
2
3
4
5
6