【日志技术】8 - 2 Logback
§8-2 Logback
8-2.2 Logback
本小节使用介绍 Logback 的日志使用方法。
8-2.2.1 配置 Logback
Logback 主要分为三个技术模块:
- logback-core:该模块为其他两个模块提供基础代码,必需项;
- logback-classic:完整实现了 SLF4j API 的模块;
- logback-access:与 Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能。
本节使用的是前两个模块,使用时,除了要导入上述两个 jar 包外,还需要导入 slf4j 的 jar 包。
导入包后,需要在项目源码根目录(src
)下放入 Logback 的核心配置文件。Logback 会依次读取以下类型配置文件:
logback.groovy
logback-test.xml
logback.xml
若上述文件不存在,则会采用默认配置。配置文件表明了日志输出需要使用到 Logback 当中的组件,组件之间的关系为:
Logger
:日志记录器。将它关联到应用对应的 Context 上后,主要用于存放日志对象,也可定义日志类型、级别。Appender
:日志追加器。用于指定日志输出目的地,可以是控制台、文件、数据库等。Layout
:日志布局。负责将事件转换为字符串,格式化日志信息输出。Logback 将Layout
对象封装在Encoder
中。
因此,当不确定 appender
标签内应当存储哪些标签时,可以查看对应类的源码以确定。
配置文件应当放入项目源码根目录(src
)下,配置文件 logback.xml
内容:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置集中管理的属性,可在此处修改属性值 -->
<!-- 格式:${name) -->
<property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread]: %msg%n"/>
<property name="html_pattern" value="%-5level%d{yyyy-MM-dd HH:mm:ss.SSS}%c%M%L%thread%msg"/>
<property name="log_dir" value="C:/code logs/Logback logs"/>
<!-- 日志输出到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 输出流对象:默认 System.out,可改为 System.err -->
<target>System.err</target>
<!-- 日志消息格式配置 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 格式化输出:
%d 表示日期,%thread 表示线程名,%-5level 级别从左显示 5 个字符宽度
%msg 或 $m:日志信息,%n:换行符,%c:类的完整名称
%M:方法,%L:行号
-->
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!-- 日志输出到文件 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- 日志输出路径 -->
<file>${log_dir}/com-zebt-data.log</file>
<!-- 日志消息格式配置 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>>${pattern}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 日志输出为 HTML 文件 -->
<appender name="HTML" class="ch.qos.logback.core.FileAppender">
<!-- 文件保存路径 -->
<file>${log_dir}/com-zebt-data.html</file>
<!-- 需要自定义编码器 -->
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<!-- 声明使用的布局 -->
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<!-- 声明日志格式 -->
<pattern>${html_pattern}</pattern>
</layout>
</encoder>
</appender>
<!-- 日志拆分和归档压缩的 Appender -->
<appender name="ROLL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 文件保存路径 -->
<file>${log_dir}/com-zebt-data-roll.log</file>
<!-- 日志消息格式配置 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<!-- 指定拆分规则 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 按时间和压缩格式声明拆分的文件名 -->
<fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-hh-ss}.log%i.gz</fileNamePattern>
<!-- 最大文件大小 -->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
<!-- 可选:日志过滤 -->
<!-- LevelFilter:级别过滤 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level> <!-- 日志级别 -->
<onMatch>ACCEPT</onMatch> <!-- 不低于此级别日志的过滤行为 -->
<onMismatch>DENY</onMismatch> <!-- 低于此级别日志的过滤行为 -->
</filter>
</appender>
<!-- 使用异步日志提高并发性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 指定某个具体的 Appender -->
<appender-ref ref="HTML"/>
<appender-ref ref="ROLL"/>
</appender>
<!-- level:设置打印级别,大小写无关,有 TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认为 DEBUG-->
<!-- root 可包含零个或多个 <appender-ref> 元素,标识这个输出位置会被本日志级别控制 -->
<!-- 日志级别从低到高分别为:TRACE < DEBUG < INFO < WARN < ERROR -->
<!-- 输出时,会将不低于所设计别的日志输出到指定位置 -->
<root level="ALL">
<appender-ref ref="ASYNC"/>
</root>
<!-- 使用自定义 Logger 灵活控制日志输出的目的地 -->
<!--
name:指定项目中哪个包下的日志由此 Logger 控制
level:指定控制的日志级别
additivity:自定义 Logger 是否继承 rootLogger(即 root 标签下的 Appender)
-->
<logger name="com.logging" level="info" additivity="false">
<!-- additivity 设为 false,该自定义 Logger 独立控制指定包下的日志输出 -->
<appender-ref ref="CONSOLE"/>
</logger>
</configuration>
8-2.2.2 Logback 输出日志
在代码中获取日志的对象
public static final Logger LOGGER = LoggerFactory.getLogger("Class 对象");
和 JUL 一样,日志记录器也需要一个唯一标识名唯一标识该记录器,通常为所在类的 Class 对象。这样,日志记录器所记录的日志就会携带对应的全限定名信息,有利于在查看日志时,定位产生日志的类与包。
此外,同一个全限定名所返回的日志记录器实例都是唯一的(单例模式),这种设计保证了资源的有效管理,并允许为每个命名的日志记录器共享和维护相同的日志级别、输出目的地等配置信息。
示例:
package com.logging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
public class LoggerDemo {
// 获取日志对象
public static final Logger LOGGER = LoggerFactory.getLogger("LoggerDemo.class");
public static void main(String[] args) {
// 性能测试
for (int i = 0; i < 10000; i++) {
LOGGER.error("error"); // 输出 ERROR 级别日志
LOGGER.warn("warn"); // 输出 WARN 级别日志
LOGGER.info("info"); // 输出 INFO 级别日志
LOGGER.debug("debug"); // 输出 DEBUG 级别日志
LOGGER.trace("trace"); // 输出 TRACE 级别日志
}
}
}
注意:
- 确保导入的包是正确的包,而不是 JUL 的
Logger
所在包; - 日志对象应当是公共的静态常量,以供程序可在任意地方调用;