Logback简单使用
Logback 日志框架介绍
正如你所知,开发者拥有大量日志工具可供选择。本节中,我们将学习一个非常流行的日志库 —— Logback
。它是 Log4j
日志库的继任者,基于相似的理念构建。Logback
在同步和异步日志记录方面都非常快速,并提供了很多实用的功能,因此适用于任何规模的项目。
与直接使用 System.out
打印信息相比,Logback
最大的不同在于它的 每个日志记录器(Logger)都有一个上下文(context)。这个上下文可以启用或禁用某些日志消息,还负责创建 Logger 实例并管理它们的层次结构。接下来我们就来详细了解这些功能。
将 Logback 添加到项目中
安装 Logback 十分简单,只需将依赖添加到 Maven 或 Gradle 即可。
要开始使用 Logback,你需要添加 logback-classic
依赖。
Maven 示例:
在 pom.xml
中添加以下内容:
<dependencies><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency>
</dependencies>
这表示你引入了 Logback 核心的实现包 logback-classic
。
Gradle 示例:
在 build.gradle
中添加以下内容:
dependencies {implementation ("ch.qos.logback:logback-classic:1.2.11")
}
这个依赖会自动传递引入两个其他库:slf4j-api
和 logback-core
。
-
SLF4J(Simple Logging Facade for Java)是一个为各种日志库提供统一接口的“门面”框架。它提供简单的日志 API,而 Logback 是其原生实现。
-
logback-core 是 Logback 的基础库,提供了若干现成的类,例如:
-
ConsoleAppender
: 将日志事件输出到标准控制台(System.out
或System.err
); -
FileAppender
: 将日志事件输出到文件; -
RollingFileAppender
: 当满足特定条件时,将日志滚动写入新文件。
-
-
logback-classic
还提供了可以将日志发送到外部系统的类,例如:-
SMTPAppender
: 在特定事件发生后将日志通过邮件发送; -
DBAppender
: 将日志存入数据库表。
-
基本日志记录
我们来创建一个名为 Example
的类,并声明几个 Logger 对象:
import org.slf4j.Logger
import org.slf4j.LoggerFactoryclass Example {private val LOG_1: Logger = LoggerFactory.getLogger(Example::class.java)private val LOG_2: Logger = LoggerFactory.getLogger("com.example.Example")init {LOG_1.info("Information from LOG_1")LOG_2.warn("Warning from LOG_2")LOG_1.info("Are the loggers the same? {}", LOG_1 === LOG_2)}
}fun main() {Example()
}
代码解释:
如你所见,我们并未直接引用 Logback 的任何类,而是使用 SLF4J 提供的接口,SLF4J 再将日志操作交由 Logback 实现。
使用 LoggerFactory.getLogger()
创建 Logger 时,可以传入类对象或字符串。两者都作为日志记录器的名称。如果同名 Logger 已存在,会复用它;否则会新建一个。
Logger 提供 trace
、debug
、info
、warn
、error
等方法来输出对应级别的日志。
日志默认输出的内容包括:时间戳、线程名、日志级别、Logger 名称、日志信息。这些都可以自定义,稍后会介绍配置方式。
日志消息参数化
Logback 支持在日志消息中添加对象或变量。这可以帮助你追踪出错位置和原因。
示例:
import org.slf4j.Logger
import org.slf4j.LoggerFactoryclass Example {private val LOG: Logger = LoggerFactory.getLogger(Example::class.java)init {val result = "Any operation"LOG.info("To track the value of a variable. The result is $result")}
}fun main() {Example()
}
这段代码展示了如何将变量插入到日志中。
此外,我们还可以记录异常信息:
import org.slf4j.Logger
import org.slf4j.LoggerFactoryclass Example {private val LOG: Logger = LoggerFactory.getLogger(Example::class.java)init {val number = 1val divisor = 0try {val result = number / divisor} catch (e: ArithmeticException) {LOG.error("Something went wrong with divisor $divisor\n$e")}}
}fun main() {Example()
}
说明:
Logback
能提取堆栈跟踪信息。如果你将异常对象作为日志方法的最后一个参数传入,即可自动记录异常详情,无需在消息中显式添加占位符。
配置 Logger
Logback 支持使用 XML 或 Groovy 文件进行配置。我们使用 XML 配置文件,名为 logback.xml
,应放在资源目录(resources
)中。
控制台输出配置:
<configuration><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss} %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="info"><appender-ref ref="console" /></root>
</configuration>
说明:
-
<appender>
:配置日志输出方式;-
name
:定义appender
的名称; -
class
:指定输出到控制台的类。
-
-
<encoder>
:设置日志输出格式; -
%d
:时间戳; -
%level
:日志级别; -
%logger{36}
:日志器名称(最多 36 个字符); -
%msg
:日志消息; -
<root>
:定义默认根日志器,指定日志级别并绑定appender
。
文件输出配置:
<configuration><appender name="file" class="ch.qos.logback.core.FileAppender"><file>${user.dir}/logs/example.log</file><encoder><pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="info"><appender-ref ref="file" /></root>
</configuration>
这里我们使用 FileAppender
将日志输出到 ${user.dir}/logs/example.log
。如果该文件不存在,会自动创建。
日志级别配置
Logback 允许为 特定类或包设置不同的日志级别,例如:
class Example {private val LOG = LoggerFactory.getLogger(Example::class.java)fun log() {LOG.warn("WARN level message")LOG.info("INFO level message")}
}class LoggerLevelClass {private val LOG = LoggerFactory.getLogger(LoggerLevelClass::class.java)fun log() {LOG.debug("DEBUG level message")LOG.info("INFO level message")}
}fun main() {Example().log()LoggerLevelClass().log()
}
对应的 XML 配置:
<configuration>
<appender name="console" 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.example" level="warn"/>
<logger name="com.example.LoggerLevelClass" level="info"/><root level="info"><appender-ref ref="console" />
</root>
</configuration>
说明:
-
每个 logger 只会输出大于或等于当前设置级别的日志。
-
Logback 使用基于名称的层级结构,如:
-
com.logback.first
是com.logback.first.second
的父级; -
com.logback.first.second
是com.logback.first.second.third
的父级。
-
-
层级结构的最顶层是
root
。
总结
在本节中,你学习了 Logback
是做什么的,以及它提供了哪些功能。使用 Logback
,你可以清楚地知道程序执行的每一步,还可以根据需求灵活配置日志记录器、按包或类追踪操作、快速发现并定位错误。
如需进一步了解 Logback
的配置层级和使用技巧,建议查阅官方文档。