日志文件配置详解
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 |