【日志文件配置详解】

日志文件配置详解

java应用部署需要打印日志,此时需要配置日志文件
分为Logback和Log4j2两种

Logback

Logback配置(logback-spring.xml / logback.xml)

属性说明:

  • scan: 配置文件改变时是否重新加载,默认true
  • scanPeriod: 扫描间隔,默认1分钟
  • debug: 是否打印logback内部日志,默认false
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
    scan: 配置文件改变时是否重新加载,默认true
    scanPeriod: 扫描间隔,默认1分钟
    debug: 是否打印logback内部日志,默认false
-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    
    <!-- ==================== 1. 定义变量/属性 ==================== -->
    <!-- 定义日志文件路径,可通过系统属性覆盖:-DLOG_PATH=/custom/logs -->
    <property name="LOG_PATH" value="${LOG_PATH:-./logs}" />
    
    <!-- 定义应用名称 -->
    <property name="APP_NAME" value="my-application" />
    
    <!-- 定义日志文件名 -->
    <property name="LOG_FILE" value="${LOG_PATH}/${APP_NAME}" />
    
    <!-- 定义日志输出格式 -->
    <!-- %d: 日期 %-5level: 日志级别(左对齐5个字符) %thread: 线程名 -->
    <!-- %logger{36}: logger名称(最多36字符) %msg: 日志消息 %n: 换行 -->
    <property name="CONSOLE_LOG_PATTERN" 
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
    
    <property name="FILE_LOG_PATTERN" 
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
    
    <!-- ==================== 2. 定义日志输出目的地 ==================== -->
    
    <!-- 控制台输出器 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 编码器 -->
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 字符集 -->
            <charset>UTF-8</charset>
        </encoder>
        <!-- 仅输出指定级别及以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>
    
    <!-- 文件输出器 - 滚动策略基于时间和大小 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在写入的日志文件名 -->
        <file>${LOG_FILE}.log</file>
        
        <!-- 滚动策略:基于时间和文件大小 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 滚动后的文件名格式 -->
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <!-- 每个文件最大大小 -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 保留的日志文件最大数量 -->
            <maxHistory>30</maxHistory>
            <!-- 日志文件总大小上限 -->
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        
        <!-- 编码器 -->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        
        <!-- 触发策略:立即刷新到磁盘 -->
        <immediateFlush>true</immediateFlush>
    </appender>
    
    <!-- 异步输出器 - 提升性能 -->
    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 队列大小,默认256 -->
        <queueSize>512</queueSize>
        <!-- 队列剩余容量小于阈值时丢弃TRACE, DEBUG, INFO级别日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 是否记录调用者数据,影响性能 -->
        <includeCallerData>false</includeCallerData>
        <!-- 引用具体的输出器 -->
        <appender-ref ref="FILE" />
    </appender>
    
    <!-- 错误日志专用输出器 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}-error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
        </encoder>
        <!-- 仅输出ERROR级别日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
    <!-- JSON格式输出器(用于ELK等日志系统) -->
    <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/json/${APP_NAME}.json</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/json/${APP_NAME}.%d{yyyy-MM-dd}.json.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <!-- 使用Logstash编码器输出JSON格式 -->
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <includeCallerData>true</includeCallerData>
            <customFields>{"app":"${APP_NAME}","env":"${ENV:-dev}"}</customFields>
        </encoder>
    </appender>
    
    <!-- ==================== 3. 定义Logger ==================== -->
    
    <!-- 项目业务日志 -->
    <logger name="com.mycompany" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="ASYNC_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </logger>
    
    <!-- 第三方框架日志级别控制 -->
    <logger name="org.springframework" level="WARN" />
    <logger name="org.springframework.web" level="INFO" />
    <logger name="org.mybatis" level="DEBUG" />
    <logger name="org.apache.ibatis" level="DEBUG" />
    <logger name="com.alibaba.druid" level="WARN" />
    <logger name="java.sql" level="DEBUG" />
    <logger name="java.sql.ResultSet" level="INFO" />
    
    <!-- 特定包单独配置 -->
    <logger name="com.mycompany.mapper" level="DEBUG" />
    <logger name="com.mycompany.web.controller" level="INFO" />
    
    <!-- ==================== 4. 根Logger ==================== -->
    <!-- 接收所有未指定logger的日志 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="ASYNC_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>
    
</configuration>

Log4j2配置(log4j2.xml)

属性说明

  • status: log4j2内部日志级别
  • monitorInterval: 自动重载间隔(秒)
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
    status: log4j2内部日志级别
    monitorInterval: 自动重载间隔(秒)
-->
<Configuration status="WARN" monitorInterval="30" packages="">
    
    <!-- ==================== 1. 属性定义 ==================== -->
    <Properties>
        <Property name="LOG_PATH">./logs</Property>
        <Property name="APP_NAME">my-application</Property>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
        <Property name="ROLLING_FILE_PATTERN">${LOG_PATH}/${APP_NAME}.%d{yyyy-MM-dd}.%i.log.gz</Property>
    </Properties>
    
    <!-- ==================== 2. Appender定义 ==================== -->
    <Appenders>
        
        <!-- 控制台输出 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>
        
        <!-- 滚动文件输出 -->
        <RollingFile name="RollingFile" 
                     fileName="${LOG_PATH}/${APP_NAME}.log"
                     filePattern="${ROLLING_FILE_PATTERN}">
            <!-- 日志格式 -->
            <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
            
            <!-- 滚动策略 -->
            <Policies>
                <!-- 基于时间的滚动 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 基于大小的滚动 -->
                <SizeBasedTriggeringPolicy size="100MB"/>
            </Policies>
            
            <!-- 默认滚动策略 -->
            <DefaultRolloverStrategy max="30">
                <Delete basePath="${LOG_PATH}" maxDepth="2">
                    <IfFileName glob="*.log.gz"/>
                    <IfLastModified age="30d"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        
        <!-- 异步Appender -->
        <Async name="AsyncFile" bufferSize="1024">
            <AppenderRef ref="RollingFile"/>
        </Async>
        
        <!-- 错误日志单独输出 -->
        <RollingFile name="ErrorFile" 
                     fileName="${LOG_PATH}/error.log"
                     filePattern="${LOG_PATH}/error.%d{yyyy-MM-dd}.log.gz">
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <TimeBasedTriggeringPolicy interval="1"/>
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>
        
    </Appenders>
    
    <!-- ==================== 3. Logger配置 ==================== -->
    <Loggers>
        
        <!-- 项目日志 -->
        <Logger name="com.mycompany" level="DEBUG" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="AsyncFile"/>
            <AppenderRef ref="ErrorFile"/>
        </Logger>
        
        <!-- 第三方框架 -->
        <Logger name="org.springframework" level="WARN"/>
        <Logger name="org.springframework.web" level="INFO"/>
        <Logger name="org.apache.ibatis" level="DEBUG"/>
        
        <!-- 根Logger -->
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="AsyncFile"/>
        </Root>
        
    </Loggers>
    
</Configuration>

示例

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="6000000" debug="false">

    <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} %-5p [%t:%c{1}:%L] - %msg%n"/>
    <property name="LOG_PATH" value="./smsplatform/logs/search/"/>
    <!-- 系统级配置文件 开始 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
    </appender>

    <!-- stdout -->
    <appender name="rootstdout"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOG_PATH}rootstdout.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>${LOG_PATH}rootstdout.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>20</MaxIndex>
        </rollingPolicy>
        <triggeringPolicy
                class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
    </appender>

    <!-- debug -->
    <appender name="rootDebug" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOG_PATH}root-debug.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>${LOG_PATH}root-debug.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>10</MaxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- info -->
    <appender name="rootInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOG_PATH}root-info.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>${LOG_PATH}root-info.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>10</MaxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- warn -->
    <appender name="rootWarn" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOG_PATH}root-warn.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>${LOG_PATH}root-warn.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>10</MaxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- error -->
    <appender name="rootError" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${LOG_PATH}root-error.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${LOG_PATH}root-error.%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>Error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <springProfile name="local">
        <root level="info">
            <!-- 本地测试时使用,将日志打印到控制台,实际部署时请注释掉 -->
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="rootstdout"/>
            <appender-ref ref="rootDebug"/>
            <appender-ref ref="rootInfo"/>
            <appender-ref ref="rootWarn"/>
            <appender-ref ref="rootError"/>
        </root>
    </springProfile>

    <springProfile name="dev">
        <root level="info">
            <!-- 本地测试时使用,将日志打印到控制台,实际部署时请注释掉 -->
            <appender-ref ref="rootstdout"/>
            <appender-ref ref="rootDebug"/>
            <appender-ref ref="rootInfo"/>
            <appender-ref ref="rootWarn"/>
            <appender-ref ref="rootError"/>
        </root>
    </springProfile>

    <springProfile name="prod">
        <root level="info">
            <!-- 本地测试时使用,将日志打印到控制台,实际部署时请注释掉 -->
            <appender-ref ref="rootstdout"/>
            <appender-ref ref="rootDebug"/>
            <appender-ref ref="rootInfo"/>
            <appender-ref ref="rootWarn"/>
            <appender-ref ref="rootError"/>
        </root>
    </springProfile>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <jmxConfigurator/>
</configuration>

配置项详解对照表

配置项 作用 推荐值
日志级别 控制日志输出粒度 DEBUG(开发)/INFO(生产)
滚动策略 防止单文件过大 100MB/天
保留天数 控制磁盘占用 7-30天
异步队列 提升性能 256-1024
输出格式 便于日志分析 包含时间、级别、线程
字符集 避免中文乱码 UTF-8
相关推荐
迷藏4942 小时前
**发散创新:基于角色与属性的混合权限模型在微服务架构中的实战落地**在现代分布式系统中,
java·python·微服务·云原生·架构
码以致用2 小时前
Java垃圾回收器笔记
java·jvm·笔记
暴力袋鼠哥2 小时前
基于springboot与vue的ai多模态数据展示看板
java·spring boot
用户8307196840822 小时前
VS Code Java开发配置与使用经验分享
java·visual studio code
立莹Sir2 小时前
云原生全解析:从概念到实践,Java技术栈如何拥抱云原生时代
java·开发语言·云原生
程序员老邢2 小时前
【技术底稿 12】内网统一日志系统 Loki + Promtail 全流程部署(对接 Grafana,监控日志一体化)
java·运维·程序人生·grafana·devops
银河系的一束光3 小时前
使用 IntelliJ IDEA 开发 Java 程序时 , 会遇到以下中文乱码问题 :
java·ide·intellij-idea
Via_Neo3 小时前
判断字符串前缀(26年蓝桥杯JAVA B组)
java·职场和发展·蓝桥杯