logback-log-configuration

logback自身初始化步骤

  • 在classpath中查找名为logack-test.xml的文件
  • 如果未找到此类文件,则logback会尝试在classpath中查找名为logback.groovy的文件
  • 如果找不到这样的文件,它会检查classpath中的文件logback.xml
  • 如果找不到这样的文件,会通过SPI的方式查找META-INF\services\ch.qos.logback.classic.spi.Configurator
  • 如果以上都不成功,则logback将使用BasicConfigurator自动配置自身,这将导致日志记录输出定向到控制台。

以上初始化的步骤在ch.qos.logback.classic.util.ContextInitializer.autoConfig()中实现的。

如果正在使用Maven,并且将logback-test.xml放在src / test / resources文件夹下。这样就可以使用不同的配置文件,即测试期间的logback-test.xml ,以及生产中的另一个文件,即logback.xml。

自动配置logback

1
2
3
4
5
6
7
public class Foo {
static final Logger logger = LoggerFactory.getLogger(Foo.class);

public void doIt() {
logger.debug("Did it again!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>

一个最基本的配置

如果在解析配置文件期间发生警告或错误,则logback将自动在控制台上打印其内部状态数据。 请注意,为避免重复,如果用户显式注册状态侦听器(在下面定义),则禁用自动状态打印。

内部状态的打印

1
2
3
4
// assume SLF4J is bound to logback in the current environment
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
// print logback's internal status
StatusPrinter.print(lc);

如果在配置文件中配置<configuration debug="true"> 则会把相关内部状态打印出来。

将默认配置文件的位置指定为系统属性

您可以使用名为”logback.configurationFile”的系统属性指定默认配置文件的位置。 此属性的值可以是URL,类路径上的资源或应用程序外部文件的路径

修改后自动重新加载配置文件

<configuration scan =“true” >

默认情况下,将每分钟扫描一次配置文件以进行更改。 您可以通过设置元素的scanPeriod属性来指定不同的扫描周期。 可以以毫秒或者秒,如configuration scan ="true" scanPeriod ="30 seconds" >

在堆栈跟踪中启用打包数据

如果指示这样做,则logback可以包括它输出的堆栈跟踪线的每一行的打包数据。 打包数据由jar文件的名称和版本组成,从而生成堆栈跟踪行的类。 打包数据在识别软件版本问题时非常有用。 但是,计算起来相当昂贵,尤其是在频繁抛出异常的应用程序中。

  • <configuration packagingData =“true” >
1
2
LoggerContext lc =(LoggerContext)LoggerFactory.getILoggerFactory();
lc.setPackagingDataEnabled(true);

停止logback-classic

为了释放logback-classic使用的资源,停止logback上下文总是一个好主意。 停止上下文将关闭附加到上下文定义的记录器的所有appender,并以有序的方式停止任何活动线程。

1
2
LoggerContext loggerContext =(LoggerContext)LoggerFactory.getILoggerFactory();
loggerContext.stop();

通过关闭钩子停止logback-classic

配置文件语法

Logback 允许重新定义日志记录行为,而无需重新编译代码。 实际上,可以轻松配置日志记录,以便禁用应用程序某些部分的日志记录,或者直接输出到UNIX Syslog守护程序,数据库,日志可视化程序或将日志记录事件转发到远程日志服务器,这将记录日志根据本地服务器策略,例如通过将日志事件转发到第二个logback服务器。

正logback配置文件的语法非常灵活。 因此,无法使用DTD文件或XML架构指定允许的语法。
然而,配置文件的基本结构可以描述为<configuration>元素,包含零个或多个<appender>元素,后跟零个或多个<logger>元素,后跟最多一个<root>元素。

配置根记录器

<root>元素配置根记录器。它支持单个属性,即level属性。
它不允许任何其他属性。此外,由于根记录器已被命名为”ROOT”,因此它也不允许使用name属性。
level属性的值可以是不区分大小写的字符串TRACE,DEBUG,INFO,WARN,ERROR,ALLOFF之一。 请注意,根记录器的级别不能设置为INHERITEDNULL
<logger>元素类似, <root>元素可以包含零个或多个<appender-ref>元素,这样引用的每个appender都被添加到根记录器中。 请注意,与log4j不同,logback-classic在配置根记录器时不会关闭也不会删除任何先前引用的appender。

配置输出级别

可以通过<logger name="com.xx.xx.Main" level="trace" />来配置级别。
如果没有配置,就用根配置器的的级别。

配置Appender

appender使用该<appender>置,该元素采用两个必需属性nameclass
该名称属性指定,而该附加目的地的名称类属性指定的appender类实例化的全名。
<appender>元件可含有零个或一个<layout>元素,零个或多个<encoder>元件以及零层或更多<filter>的元件。除了这三个公共元素之外,<appender>元素可以包含与appender类的JavaBean属性相对应的任意数量的元素。

<layout>元素采用强制类属性,指定要实例化的布局类的完全限定名称。与<appender>元素一样,<layout>可以包含与布局实例的属性对应的其他元素。由于它是如此常见的情况,如果布局类是PatternLayout,则可以省略类属性,如默认类映射规则所指定的那样。

appender通过在appender-ref元素中按名称引用它们而附加到根记录器。请注意,每个appender都有自己的编码器。编码器通常不被设计为由多个appender共享。布局也是如此。因此,logback配置文件不提供用于共享编码器或布局的任何语法手段。

Appenders积累

默认Appenders是累加的。如下的示例会输出重复的日志

1
2
3
4
5
6
7
8
9
10
11
12
13
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="chapters.configuration">
<appender-ref ref="STDOUT" />
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>

注意重复的输出,名为STDOUT的appender附加到两个记录器。由于根记录器是所有记录器的祖先。所以使用两个记录器对每个记录输出了两次。

appender可加性不是新用户的陷阱,它是一个非常方便的特性。
比如,你可以配置日志记录,以便日志消息显示在控制台上,而仅来自某些特定记录集的消息则流入特定的appender.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>myApp.log</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<logger name="chapters.configuration">
<appender-ref ref="FILE" />
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>

在此示例中,控制台appender将记录所有消息(对于系统中的所有记录器),而只有来自chapters.configuration记录器及其子记录的记录请求将进入myApp.log文件。

覆盖默认的累积行为

如果默认累积行为证明不适合您的需要,您可以通过将additivity标志设置为false来覆盖它。因此,记录器树中的分支可以将输出定向到与树的其余部分不同的一组appender。

比如上面的,在logger 后面加上additivity="false",则上面的内容就是输出到文件上,不输出到看

设置上下文名称

设置上下文名称是一种简单而直接的方法,以便区分记录到同一目标的多个应用程序。上下文一单设置就不能改变
<contextName> myAppName </ contextName>
在日志格式中cn来代表上下文

变量替换

变量替换可以发生在配置文件中可以指定值的任何位置。变量替换的语法类似于Unix shell的语法。开头$ {和结束}之间的字符串被解释为对属性值的引用。对于属性aName,字符串“$ {aName}”将替换为aName属性保存的值。

定义变量

一个简单logback配置文件

同时输出到console与文件中,把指定logger的级别设置为trace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<configuration>
<contextName> myAppName </contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} %cn [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>foo.log</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</pattern>
</encoder>
</appender>
<logger name="com.xyz.logconfigtest.Main" level="trace" />
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>

参考


logback-log-configuration
https://blog.fengcl.com/2018/07/27/logback-log-configuration/
作者
frank
发布于
2018年7月27日
许可协议