Java基础 - 日志
日志
日志级别:
- TRACE: log.trace() 最详细的日志(几乎每一行代码都记录),不常用,只在本地调试
- DEBUG: log.debug() 调试用的信息,比如变量值、函数调用,但一般只在开发环境用
- INFO: log.info() 一般性的信息,比如“服务启动成功”、“任务完成”,生产环境常用
- WARN: log.warn() 警告,程序还能运行,但可能有问题,一定要看
- ERROR: log.error() 严重错误,比如连接失败、抛异常,非常重要
- FATAL: log.fatal() 致命错误,程序无法继续,较少用,一般跟 error 同级别处理
在配置文件里可以设置希望打印的日志级别,比如log4j.rootLogger=INFO, console
(只打印 INFO 及以上级别的日志,DEBUG 就不打印)。
log4j
Log4j 是一个流行的 Java 日志框架。Log4j 1.x 已经停止维护,不推荐使用。以下介绍 log4j 2.x。
如何使用
配置文件 src/main/resources/log4j2.xml
,用于定义日志的配置。主要包含两大部分:
<Appenders>
:用于定义输出目的地,以及其对应的输出格式等。<Loggers>
:用于配置不同类/包的日志级别和使用哪些 Appenders。
1 |
|
语法解释:
<Properties>
:用于在配置文件中定义变量,这些变量可以在后续的配置元素中被引用。<RollingFile>
:用于配置 日志文件滚动,即当日志文件达到一定条件时,自动进行日志切割(例如:按大小、按日期等)。<Policies>
:定义触发日志滚动的策略- TimeBasedTriggeringPolicy:按时间滚动
- SizeBasedTriggeringPolicy:按日志文件大小滚动
<PatternLayout>
:用于设置日志输出格式,比如<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t] %-5p [%c{2}] [%X{requestId}] - %m%n" />
的输出示例为:[2025-07-20 13:47:15.324] [main] INFO [MyService] [abc123] - 用户登录成功。%d{HH:mm:ss}
:时:分:秒%t
:当前线程名字%–5p
:等价于%-5level
,以5个字符宽度,左对齐的格式来输出日志级别,比如INFO,ERROR等。%m
:日志消息内容,就是代码中写的那段文字%c{2}
:%c
是日志记录器的名称,通常是当前类的全限定名,{2}
表示只输出“类名的最后两级”(包名 + 类名),比如:com.example.app.MyService
,那么{2}
代表app.MyService
,{1}
代表MyService
%X{requestId}
:输出MDC(Mapped Diagnostic Context)中的键值对,MDC由ThreadContext定义。这里输出ThreadContext中的requestId。
<Loggers>
:标签用于定义特定包、类或者模块的日志设置。它可以用来调整日志级别和指定该日志使用的输出目标。- name:指定要配置的日志器的名称,通常是包名或类名。
- additivity:表示日志是否向上传递到上级 Logger(通常是 Root Logger)继续输出。
additivity="true"
,向上传递,会输出多次。additivity="false"
:不向上传递,只在当前 Logger 配置的 Appender 中输出一次。 - AppenderRef:指定日志的输出目的地。一个
<Logger>
下可能有多个 AppenderRef,说明该包/类的日志会输出到多个目的地。
示例:
1 |
|
Commons Logging
Commons Logging 是 Apache 提供的一个轻量级日志抽象层,它并不实际提供日志实现,而是提供了一个统一的接口来调用不同的日志框架。在大型项目或类库中,如果直接使用 Log4j、JUL、SLF4J 等具体实现,会导致项目之间耦合太强、灵活性差。而使用 Commons Logging 可以做到代码不依赖具体的日志实现,可以切换日志底层实现。Commons Logging 会自动绑定到 Log4j,当它在 classpath 中找到 log4j.jar 时,Commons Logging 会选择 Log4j 作为底层日志实现。
1 |
|
SLF4J
类似 Commons Logging,但更加现代、稳定。它提供的是一组统一的日志接口(API),本身不处理日志的输出,而是将日志调用委托给具体的日志实现(如 Logback、Log4j2、JUL 等)来完成。
1 |
|
绑定器
在一个项目中只使用一个日志实现库,避免多个日志框架共同参与日志处理。
slf4j-log4j12
slf4j-log4j12 是 SLF4J 提供的一个绑定器,它的作用是把 SLF4J 的日志调用转发给 Log4j 1.x 实现。只要这个绑定器在你的 classpath 中,所有使用 SLF4J 打的日志(包括你和你引入的库)就都会被转发到 Log4j,并使用你项目里的 log4j.properties 或 log4j.xml 配置输出。
由于Logback 是 SLF4J 的原生实现,如果想要使用 SLF4J 作为日志门面,并使用 Log4j 作为底层日志实现,必须需要这个绑定器。
log4j-slf4j-impl
Log4j 2 提供的官方 SLF4J 绑定器,用于将所有 SLF4J API 的日志调用转发到 Log4j2 实现。