下面这 5 个工程级配置最核心:
1 2 3 4 5
| 1. app.log 主业务日志 2. sql.log SQL 日志 3. slow-sql.log 慢 SQL 日志 4. http.log HTTP 请求日志 5. error.log 错误日志
|
一、推荐完整目录
1 2 3 4 5 6
| logs/${project.artifactId}/ ├── app.log ├── sql.log ├── slow-sql.log ├── http.log └── error.log
|
二、工程级 logback-spring.xml 模板
1. 公共变量
1 2 3 4
| <property name="log.path" value="logs/${project.artifactId}"/>
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{50} - %msg%n"/>
|
含义:
1 2 3 4 5 6 7 8
| log.path 日志根目录 %d 时间 %thread 当前线程名 %-5level 日志级别,左对齐,占 5 位 %X{traceId} MDC 里的 traceId,做链路追踪用 %logger{50} logger 名称,最长 50 个字符 %msg 日志正文 %n 换行
|
1. app.log:主业务日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <appender name="APP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/%d{yyyy-MM}/app.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>5GB</totalSizeCap> </rollingPolicy>
<encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender>
|
参数含义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| RollingFileAppender 滚动文件输出器 file 当前正在写入的日志文件 rollingPolicy 日志滚动策略 SizeAndTimeBasedRollingPolicy 按时间 + 文件大小滚动 fileNamePattern 历史日志文件命名规则 %d{yyyy-MM} 按月份建目录 %d{yyyy-MM-dd} 按天切日志 %i 同一天内第几个分片 .gz 自动压缩历史日志 maxFileSize 单个日志文件最大大小 maxHistory 最多保留多少天/月的历史日志 totalSizeCap 历史日志总大小上限 encoder 日志编码器 pattern 日志格式 charset 文件编码
|
对应 logger:
1 2 3 4
| <logger name="com.pig4cloud.pigx.fin" level="INFO" additivity="false"> <appender-ref ref="APP_FILE"/> <appender-ref ref="ERROR_FILE"/> </logger>
|
2. sql.log:MyBatis SQL 日志
需要把 MyBatis-Plus 改成走 Slf4j:
1 2 3
| mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
SQL appender:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <appender name="SQL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/sql.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/%d{yyyy-MM}/sql.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>15</maxHistory> <totalSizeCap>3GB</totalSizeCap> </rollingPolicy>
<encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender>
|
logger:
1 2 3
| <logger name="com.pig4cloud.pigx.fin.mapper" level="DEBUG" additivity="false"> <appender-ref ref="SQL_FILE"/> </logger>
|
含义:
1 2 3 4
| logger name 指定哪个包的日志进入这个文件 level="DEBUG" MyBatis SQL 通常是 DEBUG 级别 additivity=false 不再向 root 继续传递,避免 sql.log、app.log、console 重复输出 appender-ref 指定输出到哪个 appender
|
3. slow-sql.log:慢 SQL 日志
MyBatis 自带日志不太适合自动区分慢 SQL,推荐用 P6Spy 或自定义拦截器。
如果你用 P6Spy,可以设置:
1 2 3 4
| executionThreshold=1000 outagedetection=true outagedetectioninterval=1
|
含义:
1 2 3
| executionThreshold=1000 超过 1000ms 的 SQL 才记录,单位毫秒 outagedetection=true 开启慢查询检测 outagedetectioninterval=1 慢查询检测间隔,单位秒
|
Logback appender:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <appender name="SLOW_SQL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/slow-sql.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/%d{yyyy-MM}/slow-sql.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>2GB</totalSizeCap> </rollingPolicy>
<encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%X{traceId}] %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender>
|
logger:
1 2 3 4 5 6 7
| <logger name="p6spy" level="INFO" additivity="false"> <appender-ref ref="SQL_FILE"/> </logger>
<logger name="com.p6spy.engine.outage" level="INFO" additivity="false"> <appender-ref ref="SLOW_SQL_FILE"/> </logger>
|
4. http.log:HTTP 请求日志
这个需要你在代码里单独打日志,比如 Filter 或 AOP。
Logback appender:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <appender name="HTTP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/http.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/%d{yyyy-MM}/http.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>15</maxHistory> <totalSizeCap>3GB</totalSizeCap> </rollingPolicy>
<encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender>
|
logger:
1 2 3
| <logger name="HTTP_LOG" level="INFO" additivity="false"> <appender-ref ref="HTTP_FILE"/> </logger>
|
Java 里这样打:
1 2 3 4
| private static final Logger HTTP_LOG = LoggerFactory.getLogger("HTTP_LOG");
HTTP_LOG.info("method={} uri={} status={} cost={}ms ip={}", method, uri, status, cost, ip);
|
5. error.log:错误日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>60</maxHistory> <totalSizeCap>5GB</totalSizeCap> </rollingPolicy>
<encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{50} %file:%line - %msg%n</pattern> <charset>UTF-8</charset> </encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> </appender>
|
关键是这个:
1 2 3
| <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter>
|
含义:
1 2
| ThresholdFilter 阈值过滤器 level=ERROR 只有 ERROR 及以上级别才进入 error.log
|
root:
1 2 3 4 5
| <root level="INFO"> <appender-ref ref="console"/> <appender-ref ref="APP_FILE"/> <appender-ref ref="ERROR_FILE"/> </root>
|
三、最关键的 Logback 参数解释
logger
1
| <logger name="com.xxx.mapper" level="DEBUG" additivity="false">
|
1 2 3
| name 包名、类名,或自定义 logger 名称 level 日志级别:TRACE < DEBUG < INFO < WARN < ERROR additivity 是否继续向父 logger/root 传递
|
additivity=false 很重要。
不加的话,SQL 可能同时出现在:
appender
1
| <appender name="SQL_FILE" class="...RollingFileAppender">
|
1 2
| name appender 的名字,logger 通过 appender-ref 引用 class 输出器类型,比如控制台、文件、滚动文件
|
常用类型:
1 2 3 4
| ConsoleAppender 控制台 FileAppender 普通文件 RollingFileAppender 可滚动文件,最常用 AsyncAppender 异步日志,高并发项目常用
|
rollingPolicy
1
| <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
常用策略:
1 2
| TimeBasedRollingPolicy 只按时间滚动 SizeAndTimeBasedRollingPolicy 按时间 + 大小滚动,生产推荐
|
fileNamePattern
1
| <fileNamePattern>${log.path}/%d{yyyy-MM}/sql.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
1 2 3 4
| %d{yyyy-MM} 月份目录 %d{yyyy-MM-dd} 每天一个日志 %i 同一天文件过大时的序号 .gz 历史日志压缩
|
encoder / pattern
1 2 3
| <encoder> <pattern>%d [%thread] %-5level [%X{traceId}] %logger{50} - %msg%n</pattern> </encoder>
|
常用占位符:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| %d 时间 %level 日志级别 %-5level 左对齐日志级别 %thread 线程名 %logger logger 名 %logger{50} logger 名最多 50 个字符 %class 类名,性能较差 %method 方法名,性能较差 %file 文件名,性能较差 %line 行号,性能较差 %msg 日志内容 %n 换行 %ex 异常堆栈 %wEx Spring Boot 扩展异常格式 %X{traceId} MDC traceId
|
生产环境不建议大量使用:
因为获取调用栈有性能损耗。
四、推荐最终策略
开发环境:
1 2
| console + app.log + sql.log + error.log SQL DEBUG 打开
|
测试环境:
1 2
| app.log + sql.log + error.log + slow-sql.log SQL DEBUG 可开
|
生产环境:
1 2
| app.log + error.log + slow-sql.log 普通 SQL 建议关闭或只短期开启
|
生产建议:
1 2 3
| <logger name="com.pig4cloud.pigx.fin.mapper" level="INFO" additivity="false"> <appender-ref ref="SQL_FILE"/> </logger>
|