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>