工程经验 - 服务日志打印方案
一、背景
在工程中,服务日志尤其重要,因为线上是不能 debug 的,只能通过日志分析排查
这里分享实际工作中,我搭建工程时常使用的日志打印方案,以及我为业务组研发组提供的日志规约
二、方案
- 定义控制台输出打印器:引用此打印器的路径包,所有日志级别(TRACE DEBUG INFO WARN ERROR)都要打印到控制台
- 定义文件输出打印器:引用此打印器的路径包,比 DEBUG 严重的级别(INFO WARN ERROR)日志需持久化到文件
- 定义可执行的日志规约,让研发遵循更好地排查 BUG
- 定义工程所有包,默认打印 INFO 日志
三、实例
3.1 日志库
这里使用 logback,最简单的依赖只需要引入:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
在工程的 resources 目录下写 logback.xml,使用 ThresholdFilter 特性,用于级别过滤
<configuration>
<property name="logbase" value="/var/log/project/trace" />
<!-- LOG LEVEL: TRACE < DEBUG < INFO < WARN < ERROR -->
<!-- 控制台输出打印器-STDOUT: LOG ALL LEVEL -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%method] [%line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 文件输出打印器-file: LOG INFO WARN ERROR -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%method] [%line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${logbase}/web.%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<maxFileSize>20MB</maxFileSize>
<maxHistory>15</maxHistory>
<totalSizeCap>500MB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- 工程所有包默认打印 INFO 日志 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="file" />
</root>
<!-- 定义业务代码包,开启 DEBUG 日志 -->
<logger name="io.jalr.blog" level="DEBUG" additivity="true">
</logger>
</configuration>
3.2 业务代码
如下调用,即可实现日志打印:
@Slf4j
public class Main {
public static void main(String[] args) {
log.warn("This is jalr4ever");
}
}
四、日志规约
4.1 跨网络服务日志
【强制】跨网络的服务调用,服务接收方接口打印 DEBUG 入参,服务请求方打印 DEBUG 响应参数,两方异常栈 ERROR 都需要打印
4.2 日志信息
【强制】info 日志带上当前执行逻辑相关的业务信息,不打业务无关字符串。业务信息举例:业务 name、业务 id、业务过程参数等。
4.3 日志级别
【强制】打日志区分好 info 、error、warning 级别。
- FETAL:系统进入某种程度的不可用
- ERROR:需要马上被处理
- WARN:表示可能出现问题的操作
- INFO:系统正常运行的状态
- 扩展阅读:When to use the different log levels