一、完整的Log4j2的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- status="WARN"是Log4j2框架的日志级别,当框架启动有问题,会根据此配置来打印日志-->
<Configuration status="WARN" monitorInterval="30">
    <!-- 定义变量 -->
    <Properties>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
        <Property name="LOG_DIR">logs</Property>
        <Property name="LOG_FILE_NAME">app.log</Property>
    </Properties>

    <!-- 定义输出器(Appenders) -->
    <Appenders>
        <!-- 控制台输出 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>

        <!-- 滚动文件输出 -->
        <RollingFile name="RollingFile" fileName="${LOG_DIR}/${LOG_FILE_NAME}"
                     filePattern="${LOG_DIR}/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!-- 按时间滚动(每天) -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 按文件大小滚动(最大 100MB) -->
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
            <!-- 最多保留 30 天或 10 个文件 -->
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>

        <!-- 异步日志(提升性能) -->
        <Async name="AsyncAppender" bufferSize="1024">
            <AppenderRef ref="RollingFile"/>
        </Async>
    </Appenders>

    <!-- 定义日志记录器(Loggers) -->
    <Loggers>
        <!-- Spring 框架日志(INFO 级别) -->
        <Logger name="org.springframework" level="INFO" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <!-- MyBatis SQL 日志(DEBUG 级别) -->
        <Logger name="com.example.mapper" level="DEBUG" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="AsyncAppender"/>
        </Logger>

        <!-- 根日志记录器(全局默认),level="INFO"是应用程序的日志级别 -->
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="AsyncAppender"/>
        </Root>
    </Loggers>
</Configuration>

二、对Properties中LOG_PATTERN的proeprty的解释


完整配置

<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>

1. %d{yyyy-MM-dd HH:mm:ss.SSS}

  • 作用:输出日志事件的日期和时间。
  • 格式说明
    • yyyy:4 位年份(如 2024)。
    • MM:2 位月份(如 01 表示 1 月)。
    • dd:2 位日期(如 05)。
    • HH:24 小时制的 2 位小时(如 14 表示下午 2 点)。
    • mm:2 位分钟(如 30)。
    • ss:2 位秒(如 45)。
    • SSS:3 位毫秒(如 789)。
  • 示例
    2024-01-05 14:30:45.789
    

2. [%t]

  • 作用:输出当前线程的名称。
  • 示例
    [main]          // 主线程
    [http-nio-8080-exec-1]  // Web 请求线程
    

3. %-5level

  • 作用:输出日志级别,并左对齐固定占 5 个字符宽度。
  • 符号说明
    • %level:日志级别(如 INFO, DEBUG, ERROR)。
    • -5:左对齐,总宽度为 5 字符(不足部分用空格填充)。
  • 示例
    INFO     // 占 5 字符(INFO + 1 空格)
    DEBUG    // 占 5 字符(DEBUG + 0 空格)
    WARN     // 占 5 字符(WARN + 1 空格)
    

4. %logger{36}

  • 作用:输出日志记录器(Logger)的名称,并自动缩写以限制最大长度。
  • 格式说明
    • %logger:完整类名(如 com.example.service.UserService)。
    • {36}:最大显示 36 个字符,超长时按包名缩写(优先保留末尾类名)。
  • 缩写规则
    • 若包名过长,会缩写为单个首字母(如 com.examplec.e)。
    • 示例:
      c.e.s.UserService  // com.example.service.UserService 缩写后
      org.apache.logging.log4j.core.Logger  // 可能保持原样(不超过 36)
      

5. %msg

  • 作用:输出日志消息内容,即开发者调用日志 API 时传入的具体信息。
  • 示例
    logger.info("用户登录成功: {}", username);
    
    输出:
    用户登录成功: alice
    

6. %n

  • 作用:换行符,确保每条日志独占一行。
  • 跨平台兼容性
    • Windows 系统换行符为 \r\n
    • Linux/Mac 系统换行符为 \n
    • Log4j2 自动适配当前操作系统的换行符。

完整日志示例

假设有以下代码:

Logger logger = LogManager.getLogger(UserService.class);
logger.info("用户 {} 的年龄是 {}", "Alice", 30);

按此 LOG_PATTERN 输出结果:

2024-01-05 14:30:45.789 [main] INFO  c.e.s.UserService - 用户 Alice 的年龄是 30

总结

通过 LOG_PATTERN 可以自定义日志的:

  1. 时间精度:精确到毫秒。
  2. 线程追踪:快速定位多线程问题。
  3. 日志级别对齐:便于视觉扫描。
  4. 类名缩写:平衡可读性与日志行长度。
  5. 消息换行:确保日志整洁。

可根据需求调整格式(例如移除毫秒 SSS 或修改类名最大长度 {36})。


三、Appender配置及解释

以下是 Log4j2 中 <Appenders> 的常用和不常用配置详解,涵盖用途、参数说明及实际场景分析:

常用 Appenders(输出器)

1. Console(控制台输出)
  • 用途:将日志输出到控制台(如 IDEA、生产环境的标准输出流)。
  • 配置示例
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    
  • 关键参数
    • target:输出目标,可选 SYSTEM_OUT(标准输出)或 SYSTEM_ERR(错误输出)。
    • PatternLayout:定义日志格式(必填)。

2. RollingFile(滚动文件输出)
  • 用途:将日志写入文件,并支持按时间、大小滚动归档。
  • 配置示例
    <RollingFile name="RollingFile" 
                 fileName="logs/app.log" 
                 filePattern="logs/app-%d{yyyy-MM-dd}-%i.log.gz">
      <PatternLayout pattern="${LOG_PATTERN}"/>
      <Policies>
        <!-- 按时间滚动(每天) -->
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <!-- 按文件大小滚动(最大 100MB) -->
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
      <!-- 最多保留 7 天或 10 个文件 -->
      <DefaultRolloverStrategy max="10"/>
    </RollingFile>
    
  • 关键参数
    • fileName:当前日志文件路径。
    • filePattern:归档文件名模式(%d 日期,%i 滚动序号,支持压缩如 .gz)。
    • Policies:滚动触发策略:
      • TimeBasedTriggeringPolicy:按时间间隔滚动。
      • SizeBasedTriggeringPolicy:按文件大小滚动。
    • DefaultRolloverStrategy:归档文件保留策略(max 控制最大文件数)。
3. Async(异步输出)
  • 用途:将日志异步写入其他 Appender,提升性能(减少 I/O 阻塞)。
  • 配置示例
    <Async name="AsyncAppender" bufferSize="1024">
      <AppenderRef ref="RollingFile"/>
    </Async>
    
  • 关键参数
    • bufferSize:异步缓冲区大小(默认 128,增大可减少阻塞,但内存占用增加)。
    • AppenderRef:引用的底层 Appender(如 RollingFile)。

不常用但功能强大的 Appenders

1. SMTP(邮件发送)
  • 用途:当日志达到指定级别(如 ERROR)时,自动发送邮件通知。
  • 配置示例
    <SMTP name="Mail" 
          subject="应用错误报警" 
          to="admin@example.com" 
          from="noreply@example.com"
          smtpHost="smtp.example.com" 
          smtpPort="587"
          smtpUsername="user"
          smtpPassword="pass"
          bufferSize="10">
      <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
      <PatternLayout pattern="%d{ISO8601} [%t] %level %logger - %msg%n"/>
    </SMTP>
    
  • 关键参数
    • subject:邮件主题。
    • to/from:收件人/发件人邮箱。
    • smtpHost/smtpPort:SMTP 服务器地址和端口。
    • bufferSize:触发发送邮件的日志条数阈值。
    • ThresholdFilter:过滤低于 ERROR 级别的日志。
2. JDBC(数据库存储)
  • 用途:将日志写入数据库表。
  • 配置示例
    <JDBC name="DatabaseAppender" tableName="logs">
      <ConnectionFactory class="com.example.CustomConnectionFactory" method="getConnection"/>
      <Column name="timestamp" isEventTimestamp="true"/>
      <Column name="level" pattern="%level"/>
      <Column name="logger" pattern="%logger"/>
      <Column name="message" pattern="%message"/>
    </JDBC>
    
  • 关键参数
    • ConnectionFactory:自定义数据库连接工厂类。
    • Column:定义日志字段与数据库列的映射。
3. Kafka(消息队列)
  • 用途:将日志发送到 Kafka 集群,便于集中处理和分析。
  • 配置示例
    <Kafka name="KafkaAppender" topic="app-logs">
      <PatternLayout pattern="%d %level %msg"/>
      <Property name="bootstrap.servers">kafka1:9092,kafka2:9092</Property>
    </Kafka>
    
  • 关键参数
    • topic:Kafka 主题名称。
    • bootstrap.servers:Kafka 集群地址。
4. Socket(网络传输)
  • 用途:将日志通过 TCP/UDP 发送到远程服务器。
  • 配置示例
    <Socket name="SocketAppender" 
            host="logserver.example.com" 
            port="9500" 
            protocol="TCP">
      <SerializedLayout/>
    </Socket>
    
  • 关键参数
    • protocol:传输协议(TCP/UDP)。
    • SerializedLayout:序列化日志对象(或使用其他 Layout)。

Appenders 配置注意事项

  1. 性能与可靠性

    • 异步 Appender(Async)提升性能,但崩溃时可能丢失缓冲区日志。
    • 高频日志慎用 SMTPJDBC,避免拖慢应用。
  2. 日志保留策略

    • RollingFile 需合理设置 filePatternDefaultRolloverStrategy,避免磁盘占满。
  3. 敏感信息保护

    • 避免在日志中输出密码、密钥等敏感数据(通过 Replace 过滤器脱敏)。

实际场景配置组合

生产环境典型配置
<Appenders>
  <!-- 控制台输出(仅开发环境启用) -->
  <Console name="Console" target="SYSTEM_OUT">
    <PatternLayout pattern="${LOG_PATTERN}"/>
  </Console>

  <!-- 异步滚动文件(生产环境主用) -->
  <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd}-%i.log.gz">
    <PatternLayout pattern="${LOG_PATTERN}"/>
    <Policies>
      <TimeBasedTriggeringPolicy interval="1"/>
      <SizeBasedTriggeringPolicy size="100 MB"/>
    </Policies>
    <DefaultRolloverStrategy max="30"/>
  </RollingFile>

  <!-- 异步处理 -->
  <Async name="AsyncAppender" bufferSize="512">
    <AppenderRef ref="RollingFile"/>
  </Async>

  <!-- 错误报警邮件(按需启用) -->
  <SMTP name="Mail" subject="生产错误" to="admin@example.com" ...>
    <ThresholdFilter level="ERROR"/>
  </SMTP>
</Appenders>

总结

  • 常用 AppendersConsoleRollingFileAsync(满足大部分场景)。
  • 特殊需求 AppendersSMTP(报警)、Kafka(日志聚合)、JDBC(持久化)。
  • 配置要点:平衡性能、存储、可维护性,根据业务需求灵活组合。

四、Loggers常用配置和解释


一、<Loggers> 的作用

<Loggers> 用于定义日志记录器的行为,包括:

  • 指定日志级别(如 DEBUGINFOERROR)。
  • 关联 Appender(日志输出目标)。
  • 控制日志事件的传递(通过 additivity 属性)。

二、常见配置详解

1. 根日志记录器:<Root>
  • 作用:所有日志的默认配置,没有显式匹配的 Logger 时,使用 Root 的配置。
  • 配置示例
    <Root level="INFO">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="RollingFile"/>
    </Root>
    
  • 关键属性
    • level:全局默认日志级别(例如 INFO 表示仅输出 INFO 及以上级别的日志)。
    • AppenderRef:引用的 Appender,可关联多个输出器(如同时输出到控制台和文件)。
2. 自定义日志记录器(打印MyBatis的SQL日志):<Logger>
  • 作用:为特定包或类设置独立的日志规则,覆盖 Root 的默认配置。
  • 配置示例
    <!-- 为 MyBatis Mapper 接口启用 DEBUG 级别日志,在控制台打印出来 -->
    <Logger name="com.example.mapper" level="DEBUG" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    
    <!-- 抑制 Spring 框架的 DEBUG 日志 -->
    <Logger name="org.springframework" level="WARN" />
    
  • 关键属性
    • name:包名或类名(如 com.example.service)。
    • level:日志级别(优先级高于 Root)。
    • additivity:是否将日志事件传递给父 Logger(如 Root),默认为 true
    • AppenderRef:指定该 Logger 使用的 Appender。
3. additivity 属性的作用
  • additivity="true"(默认)
    子 Logger 的日志事件会传递给父 Logger(如 Root),可能导致重复输出。
    示例

    <Logger name="com.example" level="DEBUG">
      <AppenderRef ref="Console"/>
    </Logger>
    <Root level="INFO">
      <AppenderRef ref="Console"/>
    </Root>
    
    • com.example 包的 DEBUG 日志会由自身和 RootConsole 各输出一次。
  • additivity="false"
    阻止日志事件传递给父 Logger,避免重复。
    示例

    <Logger name="com.example" level="DEBUG" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>
    
    • com.example 包的日志仅由自身的 Console 输出,不会传递到 Root

三、RootLogger 的关系

1. 层级关系
  • Root 是顶层父 Logger:所有自定义 Logger 默认继承自 Root
  • 子 Logger 优先级更高:若子 Logger 配置了特定包或类的规则,则覆盖 Root 的默认配置。
2. 日志事件传递流程
  1. 日志事件产生:例如 com.example.service.UserService 类记录一条 DEBUG 日志。
  2. 查找匹配的 Logger
    • 优先查找最具体的 Logger(如 com.example.service)。
    • 若无匹配,逐级向上查找父包(如 com.examplecom)。
    • 最终匹配 Root
  3. 处理日志事件
    • 若匹配的 Logger 的 level 允许该日志级别(如 DEBUG ≥ 自身 level),则记录。
    • 根据 additivity 决定是否传递给父 Logger。

四、典型配置场景

1. 开发环境:详细日志
<Loggers>
  <!-- 根日志:输出 INFO 及以上到控制台 -->
  <Root level="INFO">
    <AppenderRef ref="Console"/>
  </Root>

  <!-- 项目代码启用 DEBUG -->
  <Logger name="com.example" level="DEBUG" additivity="false">
    <AppenderRef ref="Console"/>
    <AppenderRef ref="DebugFile"/>
  </Logger>

  <!-- 抑制第三方库日志 -->
  <Logger name="org.hibernate" level="WARN" />
</Loggers>
2. 生产环境:异步文件 + 错误报警
<Loggers>
  <!-- 根日志:异步文件 + 错误邮件 -->
  <Root level="INFO">
    <AppenderRef ref="AsyncFile"/>
    <AppenderRef ref="ErrorMail"/>
  </Root>

  <!-- 关键服务详细日志 -->
  <Logger name="com.example.payment" level="DEBUG" additivity="false">
    <AppenderRef ref="AsyncFile"/>
  </Logger>
</Loggers>

五、常见问题与解决

1. 日志重复输出
  • 原因:多个 Logger(包括 Root)引用了同一个 Appender,且 additivity="true"
  • 解决:为子 Logger 设置 additivity="false"
2. 日志级别不生效
  • 原因:未正确匹配包名或类名。
  • 检查:确认 Loggername 与实际代码的包路径一致。
3. 性能问题
  • 优化:使用异步 Appender(Async)并合理设置缓冲区大小

六、总结

  • Root:全局默认配置,确保所有日志至少有一个处理方式。
  • Logger:精细化控制特定包或类的日志行为。
  • additivity:控制日志事件传递,避免重复输出。
  • 最佳实践
    • 生产环境关闭 DEBUG 级别。
    • 关键模块单独配置 Logger。
    • 使用异步 Appender 提升性能。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐