Logback使用指南

336 阅读3分钟

Logback使用指南

Logback是Java应用程序的日志记录框架,是作为流行的log4j项目的继承者,其实它们都同一开发者开发的。

Logback的核心特性和优势

  • 执行速度比log4j快

  • 对slf4j的本机支持,这使切换到不同的日志记录框架变得容易,如果以后需要的话

  • 已定义配置的条件处理

  • 先进的过滤功能

  • 压缩归档的日志文件

  • 支持设置日志存档文件的最大数量

  • http访问日志

  • 从I/O失败恢复

Logback项目由3个主要模块组成

  • Logback-core——包含基本的日志功能
  • Logback-classic -包含额外的日志改进,例如slf4j支持

  • logback-access -提供与servlet容器的集成,例如Tomcat和Jetty

Logback架构

Logback体系结构由三个类组成:Logger、Appender和Layout

1.Logger是日志消息的上下文。这是应用程序与之交互以创建日志消息的类。

2.Appender将日志消息放置到它们的最终目的地。一个Logger可以有多个Appender。我们通常认为Appenders是附加到文本文件的,但是Logback比它强大得多。

3.Layout为输出准备消息。Logback支持创建用于格式化消息的自定义类,也支持为现有类创建健壮的配置选项。

在下面的小节中,我们将了解如何在典型的Java应用程序中最好地利用这个库。

基本设置

Maven

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.3.4</version>
</dependency>

只需要引用这个包就好,因为它依赖core和sjf4j-api,其它的access暂时我们使用不到。

Logback的"hello world"

首先你的classpath下创建一个logback.xml如下:

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

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

接下来创一个class并运行它

public class Example {

    private static final Logger logger 
      = LoggerFactory.getLogger(Example.class);

    public static void main(String[] args) {
        logger.info("Example log from {}", Example.class.getSimpleName());
    }
}

运行结果:

11:21:02.431 [main] INFO  log.Example1 - Example log from Example1

Logger Contexts

1.创建并使用Logger Context

通过Logback记录消息,我们首先初始化一个Logger使用SLF4或Logback,然后使用它:

private static final Logger logger = LoggerFactory.getLogger(Example.class);
logger.info("Example log from {}", Example.class.getSimpleName());

Logging Context(上下文)存在和Java对象类似的层次结构:

1.当日志记录程序的名称后面跟着一个点时,它就是一个祖先日志记录程序

2.当logger与子节点之间没有祖先节点时,它就是父节点

3.所有记录器都是预定义根记录器的后代

4.如果Logger没有显式指定级别,它会继承最近的祖先的级别,root Logger缺省的Level是DEBUG,

ch.qos.logback.classic.Logger parentLogger = 
  (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.blueheart.logback");

parentLogger.setLevel(Level.INFO);

Logger childlogger = 
  (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.blueheart.logback.tests");

parentLogger.warn("This message is logged because WARN > INFO.");
parentLogger.debug("This message is not logged because DEBUG < INFO.");
childlogger.info("INFO == INFO");
childlogger.debug("DEBUG < INFO");

结果如下:

13:52:26.915 [main] WARN  com.blueheart.logback - This message is logged because WARN > INFO.
13:52:26.921 [main] INFO  com.blueheart.logback.tests - INFO == INFO

另外一个例子,修改rootLogger

 ch.qos.logback.classic.Logger logger =
                (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.blueheart.logback");
        logger.debug("Hi there!");

        Logger rootLogger =
                (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
        logger.debug("This message is logged because DEBUG == DEBUG.");

        rootLogger.setLevel(Level.ERROR);

        logger.warn("This message is not logged because WARN < ERROR.");
        logger.error("This is logged.");

结果:

13:55:36.609 [main] DEBUG com.blueheart.logback - Hi there!
13:55:36.614 [main] DEBUG com.blueheart.logback - This message is logged because DEBUG == DEBUG.
13:55:36.614 [main] ERROR com.blueheart.logback - This is logged.

参数化消息

使用{}接收对象并使用它的toString()方法构建消息。

例子:

String message = "This is a String";
Integer zero = 0;

try {
    logger.debug("Logging message: {}", message);
    logger.debug("Going to divide {} by {}", 42, zero);
    int result = 42 / zero;
} catch (Exception e) {
    logger.error("Error dividing {} by {} ", 42, zero, e);
}

详细配置

前面提供的例子,使用的是默认配置,一个rootLogger,ConsloeAppender关联到它。

1.定位配置信息

Logback配置使用classpath下的一个名为logback.xml或logback-test.xml的文件,它的搜索顺序如下:

1.查找logback-test.xml,logback.groovy或logback.xml在classpath下

2.在找不到的情况下,会使用Java ServiceLoader查找一个*com.qos.logback.classic.spi.Configurator.的实现

3.都找不到的情况输出日志到console

2.基本配置

<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>
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

3.有问题配置

<configuration debug="true">
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    <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>
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

4.配置自动重新加载

<configuration debug="true" scan="true">
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    <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>
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

5.修改Loggers

<configuration debug="true" scan="true">
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    <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="com.blueheart.logback" level="INFO" /> 
    <logger name="com.blueheart.logback.tests" level="WARN" /> 
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

6.变量引用

<configuration debug="true" scan="true">
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    <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>
  <property name="LOG_DIR" value="/var/log/application" />
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
      <file>${LOG_DIR}/tests.log</file>
      <append>true</append>
      <encoder>
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
      </encoder>
  </appender>	
    <logger name="com.blueheart.logback" level="INFO" /> 
    <logger name="com.blueheart.logback.tests" level="WARN" /> 
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

Appenders

有多种的Appenders,常用的有如下几种:

1.ConsoleAppender

前面的配置文件已经说明

2.FileAppender

前面的配置文件已经说明

3.*RollingFileAppender*

<property name="LOG_FILE" value="LogFile" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_FILE}.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- daily rollover -->
        <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>

        <!-- keep 30 days' worth of history capped at 3GB total size -->
        <maxHistory>30</maxHistory>
        <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
        <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender> 

这个Appender值得好好研究一下,它有滚动的策略和触发策略,可以将日志文件自动进行归档打包在.gz或.zip文件。

详细请看 logback.qos.ch/manual/appe…

Layouts

Layouts格式化输出的消息,一般使用default PatternLayout输出它他们。

<encoder>
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>

Logger Additivity

默认情况下,一个日志会输出到它的日志记录器及它的祖先日志记录器,rootLogger是所有Logger的祖先,所以都会输出到rootLogger,要关闭这个特性,使用additivity=false在logger元素中:

<logger level="info" name="rollingFileLogger" additivity=false>
   ...
</logger>