logback 配置详解
概览
Logback 是一个 Java 领域的日志框架。它被认为是 Log4J 的继承人。
Logback 主要由三个模块组成:
logback-core :
logback-core 是其它模块的基础设施,其它模块基于它构建,显然,logback-core 提供了一些关键的通用机制logback-classic :
logback-classic 的地位和作用等同于 Log4J,它也被认为是 Log4J 的一个改进版,并且它实现了简单日志门面 SLF4Jlogback-access :
logback-access 主要作为一个与 Servlet 容器交互的模块,比如说 tomcat 或者 jetty,提供一些与 HTTP 访问相关的功能
目前 Logback 的使用很广泛,很多知名的开源软件都使用了 Logback作为日志框架,比如说 Akka,Apache Camel 等。
Logback 与 Log4J
实际上,这两个日志框架都出自同一个开发者之手,Logback 相对于 Log4J 有更多的优点
- 同样的代码路径,Logback 执行更快
- 更充分的测试
- 原生实现了 SLF4J API(Log4J 还需要有一个中间转换层)
- 内容更丰富的文档
- 支持 XML 或者 Groovy 方式配置
- 配置文件自动热加载
- 从 IO 错误中优雅恢复
- 自动删除日志归档
- 自动压缩日志成为归档文件
- 支持 Prudent 模式,使多个 JVM 进程能记录同一个日志文件
- 支持配置文件中加入条件判断来适应不同的环境
- 更强大的过滤器
- 支持 SiftingAppender(可筛选 Appender)
- 异常栈信息带有包信息
快速上手
想在 Java 程序中使用 Logback,需要依赖三个 jar 包,分别是 slf4j-api,logback-core,logback-classic。其中 slf4j-api 并不是 Logback 的一部分,是另外一个项目,但是强烈建议将 slf4j 与 Logback 结合使用。要引用这些 jar 包,在 maven 项目中引入以下3个 dependencies
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.11</version>
</dependency>
SLF4J不同于其他日志类库,与其它有很大的不同。SLF4J(Simple logging Facade for Java)不是一个真正的日志实现,而是一个抽象层( abstraction layer),它允许你在后台使用任意一个日志类库
第一个简单的例子
package io.beansoft.logback.demo.universal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SimpleDemo {
private static final Logger logger = LoggerFactory.getLogger(SimpleDemo.class);
public static void main(String[] args) {
logger.info("Hello, this is a line of log message logged by Logback");
}
}
注意到这里,代码里并没有引用任何一个跟 Logback 相关的类,而是引用了 SLF4J 相关的类,这边是使用 SLF4J 的好处,在需要将日志框架切换为其它日志框架时,无需改动已有的代码。
LoggerFactory 的 getLogger() 方法接收一个参数,以这个参数决定 logger 的名字,这里传入了 SimpleDemo 这个类的 Class 实例,那么 logger 的名字便是 SimpleDemo 这个类的全限定类名:io.beansoft.logback.demo.universal.SimpleDemo
让 Logback 打印出一些它自身的内部消息
package io.beansoft.logback.demo.universal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
public class LogInternalStateDemo {
private static final Logger logger = LoggerFactory.getLogger(LogInternalStateDemo.class);
public static void main(String[] args) {
logger.info("Hello world");
//打印 Logback 内部状态
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
}
}
Logger,Appenders 与 Layouts
在 logback 里,最重要的三个类分别是
- Logger
- Appender
- Layout
Logger 类位于 logback-classic 模块中, 而 Appender 和 Layout 位于 logback-core 中,这意味着, Appender 和 Layout 并不关心 Logger 的存在,不依赖于 Logger,同时也能看出, Logger 会依赖于 Appender 和 Layout 的协助,日志信息才能被正常打印出来。
分层命名规则
为了可以控制哪些信息需要输出,哪些信息不需要输出,logback 中引进了一个 分层 概念。每个 logger 都有一个 name,这个 name 的格式与 Java 语言中的包名格式相同。这也是前面的例子中直接把一个 class 对象传进 LoggerFactory.getLogger() 方法作为参数的原因。
logger 的 name 格式决定了多个 logger 能够组成一个树状的结构,为了维护这个分层的树状结构,每个 logger 都被绑定到一个 logger 上下文中,这个上下文负责厘清各个 logger 之间的关系。
例如, 命名为 io.beansoft 的 logger,是命名为 io.beansoft.logback 的 logger 的父亲,是命名为 io.beansoft.logback.demo 的 logger 的祖先。
在 logger 上下文中,有一个 root logger,作为所有 logger 的祖先,这是 logback 内部维护的一个 logger,并非开发者自定义的 logger。
可通过以下方式获得这个 logger :
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
同样,通过 logger 的 name,就能获得对应的其它 logger 实例。
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 有日志打印级别,可以为一个 logger 指定它的日志打印级别。
如果不为一个 logger 指定打印级别,那么它将继承离他最近的一个有指定打印级别的祖先的打印级别。这里有一个容易混淆想不清楚的地方,如果 logger 先找它