Files
rikako-note/spring/logback/logback.md
2024-08-05 12:53:54 +08:00

8.4 KiB
Raw Blame History

Logback

Introduce

logback-classic模块需要classpath下存在slf4j-api.jar, logback-core.jar, logback-classic.jar

logback使用示例如下

package chapters.introduction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld1 {

  public static void main(String[] args) {

    Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
    logger.debug("Hello world.");

  }
}

HelloWorld1类定义在chapters.introduction包下其引入了slf4j中的LoggerLoggerFactory类。

在上述示例中并没有引入任何logback的类在使用日志的大多数场景中只需要引入slf4j的api类即可。

Logback Architecture

logback目前结构分为3个模块logback-corelogback-classiclogback-access

logback-core是其他两个模块的基础,classic模块拓展了core模块。classic模块实现了slf4j api因而在使用slf4j时可以在logback和其他日志系统之间轻松切换。而access模块和servlet容器做了集成可以通过http对日志进行访问。

Logger, Appender, Layout

logback基于3个主要的类构成Logger, Appender, LayoutLogger类属于logback-classic模块Appender和Layout类则是属于logback-core模块。

Log Context

在logback-classic中每个logger都关联了一个Log Contextlog Context负责创建logger并且log context将创建的logger按照树状结构排列。

Logger都拥有名称其名称大小写敏感并遵循分层的命名规则

如果一个logger的名称其名称加上.后形成的字符串为另一个logger的前缀那么可称后一个logger是前一个logger的后代。如果一个logger和后代logger之间没有其他的logger那么可以称前一个logger是后一个logger的parent。

例如,名称为"com.foo"的logger是名称为"com.foo.Bar"的parent。

root logger是位于最顶层的logger其可以通过如下方式进行获取

Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

其他所有的logger也可以通过getLogger方法进行获取该方法接收logger name来作为参数Logger接口具有如下方法:

package org.slf4j; 
public interface Logger {

  // Printing methods: 
  public void trace(String message);
  public void debug(String message);
  public void info(String message); 
  public void warn(String message); 
  public void error(String message); 
}

有效级别

logger都会被指定一个log levellevel可以是TRACE, DEBUG, INFO, WARN, ERROR中的一个,其定义在ch.qos.logback.classic.Level类中。如果指定logger没有被指定level那么其会从离其最近并且被指定level的先祖logger中继承level。

为了保证所有logger都可以继承levelroot logger一定会被指定log level。默认情况下level为debug

log level顺序为

TRACE < DEBUG < INFO < WARN < ERROR

获取Logger

在通过LoggerFactory.getLogger获取logger对象时如果向方法传入相同的名称那么会获得相同的logger对象。

通常应在每个class中指定一个loggerlogger name为class的全类名。

Appender

在logback中允许将日志打印到多个目的地在logback中目的地被称为Appender。目前目的地可以是console、文件、remote socket server、数据库、JMS等。

对每个logger都可以关联不止一个Appender。

addAppender将会将Appender关联到指定的logger。每个被允许打印的log请求都会被发送到该logger关联的所有Appender中并且log请求还会被发送到树结构更高的Appender中。在logger结构中Appender是增量继承的后代logger会继承先祖logger的Appender。

如果为root logger指定一个console appender并且为L指定一个file appender那么对于L和L的后代logger打印日志的请求不仅会被发送到console还会被打印到文件中。

可以手动指定logger L增量继承appender的标志为false那么L和其所有后代logger都不会继承L先祖logger的appender。

默认情况下appender是否增量继承的标志默认值为true

Layout

如果想要指定日志打印的格式可以将Layout对象和logger相关联。PatternLayout可以通过c语言printf的格式来指定打印格式。

PatternLayout若指定conversion pattern为%-4relative [%thread] %-5level %logger{32} - %msg%n,其会按如下格式打印消息:

176  [main] DEBUG manual.architecture.HelloWorld2 - Hello world.

参数化打印

可以通过如下形式来进行参数化打印

Object entry = new SomeObject(); 
logger.debug("The entry is {}.", entry);

只有当前消息被评估应该打印时,才会通过消息模板来构造消息,将{}替换为entry的实际值。

Logback Configuration

logback配置顺序

  1. 如果logback.configurationFile系统变量设置
  2. 如果1步骤失败会尝试在classpath中寻找logback-test.xml
  3. 如果2步骤失败会尝试在classpath中寻找logback.xml

通过命令行System Properties设置logback配置文件位置

可以通过向命令行传递-Dlogback.configurationFile=/path/to/config.xml来设置logback配置文件的位置

通过xml形式配置logback

<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} -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

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

自动加载配置文件更新

logback支持对配置文件的变动进行扫描并且对扫描到的变动进行自动配置。为了令logback支持配置自动更新需要为configuration元素配置scan属性示例如下所示

<configuration scan="true">
  ...
</configuration>

在开启配置自动更新时,默认会每间隔1 minute就扫描配置变动。可以通过scanPeriod属性自定义扫描周期,周期单位可以是milliseconds, seconds, minutes, hours。示例如下所示:

<configuration scan="true" scanPeriod="30 seconds" >
  ...
</configuration> 

如果在没有为scanPerod属性值指定单位时默认单位为ms

xml配置文件语法

一个基础的xml配置文件可以包含如下结构

  1. 一个<configuration>元素
    1. 0或多个<appender>元素
    2. 0或多个<logger>元素
    3. 最多一个<root>元素

<logger>

<logger>元素用于配置logger其接收一个必填的name属性,一个可选的level属性,一个可选的additivity属性。

  • additivity属性的值可以为true或者false。
  • level属性的值可以为TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,是大小写不敏感的。
    • 如果想要从上级继承level可以将level属性的值设置为INHERITED或是NULL

logger元素中可以包含0个或多个<appender-ref>元素这样每个引用的appender都会被加入到logger中。

<root>

root元素用于配置root logger其只支持一个属性level。由于root元素已经被命名为ROOT,故而也不允许指定name属性。

<root>元素的level属性只能被赋值为TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,不能被赋值为INHERITED或是NULL.

和logger元素一样root元素中也能包含0个或多个<appender-ref>元素。

<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} -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration" level="INFO"/>

  <!-- Strictly speaking, the level attribute is not necessary since -->
  <!-- the level of the root level is set to DEBUG by default.       -->
  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>

</configuration>