十七、log4j 使用

5 阅读6分钟

Log4j知识点

一、Log4j 整体介绍

1. 概念全称

  • Log4jLog for Java,Apache 开源日志记录框架
  • 作用:替代 System.out.println,统一规范化记录程序运行日志
  • 版本划分
  1. Log4j 1.x:初代版本,已停止维护、高危漏洞、淘汰
  2. Log4j 2.x:全称 Log4j2,全新重构、高性能、异步日志、漏洞修复,目前企业主流

2. 为什么抛弃 System.out.println

  1. 日志分级,所有信息混在一起,无法过滤
  2. 无法控制日志开关,上线后不能关闭调试信息
  3. 无统一格式:没有时间、线程、类名、行号、异常堆栈
  4. 输出目的地单一,只能控制台,无法写入文件、数据库、远程服务器
  5. 多线程下打印混乱、性能差、无法持久化排查问题

3. 日志框架体系关系

  • 日志门面(抽象层):SLF4J、JCL
  • 日志实现(底层):Log4j1、Log4j2、Logback
  • 企业标准组合:SLF4J + Log4j2

二、Log4j 核心三大核心组件(必考)

1. Logger 日志记录器

  • 作用:代码中直接使用,产生日志事件
  • 绑定日志级别,控制日志是否输出
  • 分为:根Logger(Root)自定义局部Logger

2. Appender 输出目的地

日志要打印到哪里,一个Logger可以绑定多个Appender
常见类型:

  1. ConsoleAppender:控制台输出
  2. FileAppender:输出到本地固定文件
  3. RollingFileAppender滚动日志(按大小/时间分割文件,生产必备)
  4. JDBCAppender:日志存入数据库
  5. SocketAppender:远程发送日志

3. Layout 日志格式器

作用:控制日志打印格式、内容排版

  • 格式化时间、线程、日志级别、类名、日志信息、异常堆栈
  • 常用:PatternLayout 自定义正则格式

三、日志级别(完整完整版 由低到高)

1. 完整级别排序

TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF  
  1. TRACE:追踪日志,粒度最细,记录代码完整执行流程,极少使用
  2. DEBUG:调试日志,开发环境专用,打印SQL、参数、变量、接口入参出参
  3. INFO:普通业务日志,记录正常运行流程(项目启动、接口请求、业务完成)
  4. WARN:警告日志,程序不崩溃、功能正常,但存在潜在风险(参数为空、过期配置)
  5. ERROR:错误日志,业务报错、数据库异常、IO异常、代码BUG
  6. FATAL:致命错误,服务直接崩溃、无法继续运行
  7. OFF:关闭所有日志输出

2. 级别过滤规则

  • 配置文件设置全局最低级别
  • 只输出 大于等于 当前级别的日志
  • 示例:
    配置 level="INFO"
    → 生效:INFO、WARN、ERROR、FATAL
    → 屏蔽:DEBUG、TRACE

3. 环境级别规范

  • 开发环境:DEBUG
  • 测试环境:INFO
  • 生产环境:INFO / WARN

四、Log4j 配置文件 全详解

1. 支持的配置文件类型

(1)Log4j 1.x 旧版本
  • log4j.properties 【最经典】
  • log4j.xml
(2)Log4j2 新版本(重点)

自动加载顺序(resources 目录下自动识别):

  1. log4j2.xml 🔥 企业最常用
  2. log4j2.yml / log4j2.yaml
  3. log4j2.properties
  4. log4j2.json

核心区别:Log4j2 配置文件必须带后缀 2

2. 两种主流配置文件语法

① properties 键值对风格(简单、扁平)
# 根日志级别、绑定输出源  
log4j.rootLogger=DEBUG,console,file  
  
# 控制台配置  
log4j.appender.console=org.apache.log4j.ConsoleAppender  
log4j.appender.console.layout=org.apache.log4j.PatternLayout  
log4j.appender.console.layout.ConversionPattern=%d %p %c - %m%n  
② xml 标签风格(复杂配置首选、功能最全)

分层结构,支持过滤器、多环境、滚动策略、异步日志

3. 日志格式占位符(完整对照表)

%d 日期时间  
%p / %-5p 日志级别  
%c 全类名  
%m 自定义日志信息  
%n 换行  
%t 线程名称  
%L 代码行号  
%logger 日志器名称  
%throwable 异常堆栈  

五、Log4j2 完整依赖

<!-- 日志门面 api -->  
<dependency>  
<groupId>org.apache.logging.log4j</groupId>  
<artifactId>log4j-api</artifactId>  
<version>2.23.1</version>  
</dependency>  
<!-- 日志核心实现 -->  
<dependency>  
<groupId>org.apache.logging.log4j</groupId>  
<artifactId>log4j-core</artifactId>  
<version>2.23.1</version>  
</dependency>  

六、代码固定使用语法

1. 声明日志对象(全局标准写法)

import org.apache.logging.log4j.LogManager;  
import org.apache.logging.log4j.Logger;  
  
public class DemoDao {  
// 绑定当前类  
private static final Logger log = LogManager.getLogger(DemoDao.class);  
}  

2. 分级打印日志

// 调试  
log.debug("SQL语句:{}", sql);  
// 正常信息  
log.info("用户新增成功,id:{}", userId);  
// 警告  
log.warn("传入参数为空");  
// 错误(必传异常对象,打印堆栈)  
try {  
// 数据库操作  
} catch (Exception e) {  
log.error("数据库操作失败", e);  
}  

七、Appender 详细分类与作用

  1. ConsoleAppender
    输出到 IDEA / 控制台,开发环境必备
  2. FileAppender
    写入单个固定文件,缺点:文件越来越大,生产不用
  3. RollingFileAppender
    滚动日志:
  • 日期分割:每天一个日志文件
  • 文件大小分割:单个文件达到指定大小自动新建
  • 自动删除过期日志,节省磁盘空间
  1. JDBCAppender
    将日志批量插入数据库,用于日志溯源审计

八、异步日志(Log4j2 核心优势)

1.x 全部为同步日志

  • 日志打印阻塞主线程,高并发下严重拖慢系统性能

Log4j2 支持全异步 / 混合异步

  • 日志操作放入独立线程
  • 业务线程无需等待日志落地
  • 高并发项目必开,大幅提升吞吐量

九、Log4j1 与 Log4j2 核心区别

对比项Log4j 1.xLog4j2
维护状态停止维护、漏洞多持续更新、安全修复
性能同步、性能差异步架构、性能极强
配置文件log4j.propertieslog4j2.xml/yml
异步支持不原生支持原生强力异步
漏洞严重远程漏洞已修复
企业使用老旧遗留项目新项目、主流标配

十、日志开发强制规范(工作/面试)

  1. 禁止使用 System.out.printlne.printStackTrace()
  2. 异常捕获必须使用:log.error(描述, 异常对象)
  3. 不同级别严格区分场景,不滥用 error
  4. 生产环境关闭控制台输出,只保留滚动文件日志
  5. 日志中关键参数使用占位符 {} 拼接,避免字符串拼接性能损耗
  6. 禁止打印密码、手机号、身份证等敏感信息

十一、面试高频简答题(直接背诵)

  1. 简述 Log4j 三大组件

Logger(日志记录器)、Appender(输出目的地)、Layout(格式处理器)

  1. 日志级别由低到高

TRACE < DEBUG < INFO < WARN < ERROR < FATAL

  1. Log4j2 常见配置文件

log4j2.xml、log4j2.yml、log4j2.properties

  1. 为什么使用日志框架

日志分级管理、多目的地输出、自定义格式、持久化存储、线上动态控制级别、方便问题排查

  1. 滚动日志作用

分割大日志文件、按天归档、自动清理过期日志、便于日志查询与运维


十二、完整可直接使用 log4j2.xml 模板

<?xml version="1.0" encoding="UTF-8"?>  
<Configuration status="WARN">  
<Appenders>  
<!-- 控制台输出 -->  
<Console name="Console" target="SYSTEM_OUT">  
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>  
</Console>  
<!-- 按天滚动日志文件 -->  
<RollingFile name="RollingFile" fileName="logs/app.log"  
filePattern="logs/$${date:yyyy-MM-dd}/app-%d{yyyy-MM-dd}.log">  
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>  
</RollingFile>  
</Appenders>  
<Loggers>  
<Root level="DEBUG">  
<AppenderRef ref="Console"/>  
<AppenderRef ref="RollingFile"/>  
</Root>  
</Loggers>  
</Configuration>