配置文件的结构

因为logback的配置十分灵活,所以无法通过一个DTD文件或者XML Schema来指定允许的语法。

标签名区分大小写

对于特定的标签名字是大小写不敏感的,比如, 都是合法的配置,但是只能用关闭,不能是,但是针对驼峰规则是适用的,比如只能用关闭,不能是。驼峰规则可以参考维基百科camelCase convention

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

设置上下文名称

每个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>

定义变量

可以用定义变量,在 1.0.7 版本之后可以使用互换。

可以通过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>

变量的范围

${xxx}到底可以引用哪些地方的变量呢?

读取顺序依次:

  1. 配置文件直接定义的
  2. LoggerContext
  3. VM的参数列表
  4. 环境变量

可以通过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>

变量的默认值

可以通过 -: 操作符合来使用默认值,比如${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>

定义动态的变量

通过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>

条件判断

需要依赖Janino库,支持嵌套

<dependency>
  <groupId>org.codehaus.janino</groupId>
  <artifactId>janino</artifactId>
  <version>3.0.6</version>
</dependency>

例子:

其中property可以简写为p,语法和java中字符串语法一样

%d %-5level %logger{35} - %msg %n ${randomOutputDir}/conditional.log %d %-5level %logger{35} - %msg %n

从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>

配置引入

可以通过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>

includedConfig.xml:

<included>
  <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>"%d - %m%n"</pattern>
    </encoder>
  </appender>
</included>

日志级别改变传播器

0.9.25版本开始, logback-classic附带了LevelChangePropagator,是LoggerContextListener的实现类,用于监控日志等级改变,然后传输到java.util.logging框架中,这种传播消除了禁用日志语句对性能的影响

<configuration debug="true">
  <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
  .... 
</configuration>

设置resetJUL属性来实现日志等级改变时重置jcl。

<configuration debug="true">
  <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
    <resetJUL>true</resetJUL>
  </contextListener>
  ....
</configuration>

参考

Chapter 3: Logback configuration

博客
分类
标签
归档
关于