日志系统($\text {Logging System}$) vs 日志门面($\text {Logging Facade}$)
日志系统是具体的日志实现,直接负责日志的记录、输出和管理。
日志门面是抽象层,提供统一的接口来使用不同的日志系统。
1 日志系统
1.1 JUL (java.util.logging)
从 JDK1.4(2002 年)开始内置的官方日志库。
1.2 Log4j
Logger(记录器):负责捕获记录信息。
Appender(输出源):负责发布日志信息,以不同的首选目的地。
Layout(布局):负责格式化不同风格的日志信息。
1.3 Logback
logback-core
logback-classic
logback-access
1.4 Log4j2
2 日志门面
2.1 SLF4J (Simple Logging Facade for Java)
http://www.slf4j.org/
2.2 Commons Logging
https://commons.apache.org/proper/commons-logging/
3 日志库实践
推荐使用 $\text {SLF4J + Logback}$。
日志级别:TRACE < DEBUG < INFO < WARN < ERROR
3.1 Maven 依赖配置
1 2 3 4 5 6 7 8 9 10 11 12 13 <dependency > <groupId > org.slf4j</groupId > <artifactId > slf4j-api</artifactId > <version > 2.0.16</version > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > <version > 1.5.16</version > </dependency >
3.2 Logback 配置文件
在 src/main/resources
目录下创建 logback.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?xml version="1.0" encoding="UTF-8" ?> <configuration > <property name ="LOG_PATTERN" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" /> <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <encoder > <pattern > ${LOG_PATTERN}</pattern > </encoder > </appender > <appender name ="FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > logs/application.log</file > <rollingPolicy class ="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" > <fileNamePattern > logs/application-%d{yyyy-MM-dd}.log</fileNamePattern > <maxHistory > 30</maxHistory > </rollingPolicy > <encoder > <pattern > ${LOG_PATTERN}</pattern > </encoder > </appender > <root level ="INFO" > <appender-ref ref ="CONSOLE" /> <appender-ref ref ="FILE" /> </root > <logger name ="com.solisamicus" level ="DEBUG" /> </configuration >
日志格式定义
1 2 <property name ="LOG_PATTERN" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
%d{yyyy-MM-dd HH:mm:ss.SSS}
- 时间戳
[%thread]
- 线程名
%-5level
- 日志级别,左对齐5个字符
%logger{36}
- logger名称,最大36个字符
%msg
- 日志消息
%n
- 换行符
控制台输出配置:使用之前定义的 LOG_PATTERN
格式,定义了名为"CONSOLE
"的追加器,使用 ConsoleAppender
输出到控制台。
1 2 3 4 5 <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <encoder > <pattern > ${LOG_PATTERN}</pattern > </encoder > </appender >
文件输出配置:
1 2 3 4 5 6 7 8 9 10 <appender name ="FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > logs/application.log</file > <rollingPolicy class ="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" > <fileNamePattern > logs/application-%d{yyyy-MM-dd}.log</fileNamePattern > <maxHistory > 30</maxHistory > </rollingPolicy > <encoder > <pattern > ${LOG_PATTERN}</pattern > </encoder > </appender >
<file>
- 当前活动日志文件位置
<rollingPolicy>
- 按时间滚动策略
<fileNamePattern>
- 归档日志文件名格式,按天滚动
<maxHistory>
- 保留30天的历史日志
根日志级别配置:设置全局日志级别为 INFO,日志同时输出到控制台和文件。
1 2 3 4 <root level ="INFO" > <appender-ref ref ="CONSOLE" /> <appender-ref ref ="FILE" /> </root >
特定包的日志级别:专门为 com.solisamicus
包设置 DEBUG 级别。
1 <logger name ="com.solisamicus" level ="DEBUG" />
3.3 示例代码
com/solisamicus/Main.java
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.solisamicus;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Main { private static final Logger logger = LoggerFactory.getLogger(Main.class); public void performOperation (String data) { logger.trace("Trace level: Processing data: {}" , data); logger.debug("Debug level: Processing data: {}" , data); logger.info("Info level: Processing data: {}" , data); logger.warn("Warn level: Be careful with data: {}" , data); try { if (data == null ) { throw new IllegalArgumentException ("Data cannot be null" ); } logger.info("Successfully processed data: {}" , data); } catch (Exception e) { logger.error("Failed to process data: {}" , data, e); } } public static void main (String[] args) { Main example = new Main (); example.performOperation("test data" ); example.performOperation(null ); } }
运行结果显示:
1 2 3 4 5 6 7 8 9 10 11 2025-01-20 21:29:35.623 [main] DEBUG com.solisamicus.Main - Debug level: Processing data: test data 2025-01-20 21:29:35.625 [main] INFO com.solisamicus.Main - Info level: Processing data: test data 2025-01-20 21:29:35.625 [main] WARN com.solisamicus.Main - Warn level: Be careful with data: test data 2025-01-20 21:29:35.625 [main] INFO com.solisamicus.Main - Successfully processed data: test data 2025-01-20 21:29:35.626 [main] DEBUG com.solisamicus.Main - Debug level: Processing data: null 2025-01-20 21:29:35.626 [main] INFO com.solisamicus.Main - Info level: Processing data: null 2025-01-20 21:29:35.626 [main] WARN com.solisamicus.Main - Warn level: Be careful with data: null 2025-01-20 21:29:35.628 [main] ERROR com.solisamicus.Main - Failed to process data: null java.lang.IllegalArgumentException: Data cannot be null at com.solisamicus.Main.performOperation(Main.java:16) at com.solisamicus.Main.main(Main.java:27)
logs/application.log
同样记载了上述内容。