文章目录
- 前言
- 一、准备
- 1. 引入依赖
- 二、日志配置
- 1. 打印追踪ID
- 2. gRPC 导出
- 三、完整日志配置
- 四、日志展示
- 1. 前端
- 2. 后端
- 总结
前言
前面已经完成了请求的链路追踪,这里我们通过SkyWalking来处理分布式日志;
场景描述:我们有三个服务消费者,提供者和用户服务,三个服务都有自己的日志文件,但是我一个请求会贯穿三个服务,不能说我一个服务的日志文件挨个去找,这太麻烦了,如果有更多的服务呢,这时候代价会更大;
SkyWalking为我们解决了这个问题,每当请求进来的时候会生成一个追踪ID(TID)
一、准备
1. 引入依赖
我们首先引入skywalking整合logback的工具包
<!-- https://mvnrepository.com/artifact/org.apache.skywalking/apm-toolkit-logback-1.x -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>9.3.0</version>
</dependency>
二、日志配置
以下内容基于
logback-spring.xml
日志配置文件
1. 打印追踪ID
<property name="CONSOLE_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr([%tid]) %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%applicationName[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}:%L) %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LOG_THRESHOLD}</level>
</filter>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${CONSOLE_PATTERN}</Pattern>
<charset>${CONSOLE_LOG_CHARSET}</charset>
</layout>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
主要是[%tid]
2. gRPC 导出
<appender name="GRPC-LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%applicationName[%15.15t]] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="GRPC-LOG"/>
</root>
三、完整日志配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 引入Spring Boot的默认logback配置 -->
<property name="CONSOLE_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr([%tid]) %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%applicationName[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}:%L) %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } %applicationName[%t] ${LOG_CORRELATION_PATTERN:-}%-40.40logger{39}:%L : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- 自定义控制台输出模板 -->
<property name="LOG_HOME" value="../logs/consumer/"/>
<property name="LOG_FILE" value="consumer"/>
<property name="LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START" value="false"/>
<property name="LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE" value="10MB"/>
<property name="LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP" value="0"/>
<property name="LOGBACK_ROLLINGPOLICY_MAX_HISTORY" value="7"/>
<appender name="GRPC-LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%applicationName[%15.15t]] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LOG_THRESHOLD}</level>
</filter>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<Pattern>${CONSOLE_PATTERN}</Pattern>
<charset>${CONSOLE_LOG_CHARSET}</charset>
</layout>
</encoder>
</appender>
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<pattern>${FILE_PATTERN}</pattern>
<charset>${FILE_LOG_CHARSET}</charset>
</encoder>
<file>${LOG_HOME}${LOG_FILE}_debug.log</file>
<!--大小和时间基于滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}${LOG_FILE}_debug.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-7}</maxHistory>
</rollingPolicy>
</appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>${FILE_PATTERN}</pattern>
<charset>${FILE_LOG_CHARSET}</charset>
</encoder>
<file>${LOG_HOME}${LOG_FILE}_info.log</file>
<!--大小和时间基于滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}${LOG_FILE}_info.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-7}</maxHistory>
</rollingPolicy>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>${FILE_PATTERN}</pattern>
<charset>${FILE_LOG_CHARSET}</charset>
</encoder>
<file>${LOG_HOME}${LOG_FILE}_error.log</file>
<!--大小和时间基于滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}${LOG_FILE}_error.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-7}</maxHistory>
</rollingPolicy>
</appender>
<!-- 设置特定包的日志级别 -->
<logger name="org.springframework" level="INFO"/>
<logger name="org.hibernate" level="INFO"/>
<logger name="com.alibaba" level="INFO"/>
<logger name="io.netty" level="INFO"/>
<logger name="reactor.netty" level="INFO"/>
<logger name="com.github.xiaoymin.knife4j.spring.gateway.discover" level="INFO"/>
<logger name="de.codecentric.boot.admin" level="INFO"/>
<!-- Root Logger -->
<root level="DEBUG">
<appender-ref ref="GRPC-LOG"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</configuration>
四、日志展示
1. 前端
其他地方都有ALL
,唯独服务这里是个单选,我们需要根据追踪ID一个服务一个服务的找,如果能直接根据这个追踪ID去找就好了,不过这样也够用了,就是没那么直观。
2. 后端
2024-09-08 20:50:31.453 [TID:a7f970f0b12c411aa2b064304a353602.90.17257998314490001] DEBUG 9752 [consumer-service] [nio-9003-exec-3] o.e.n.c.controller.TestController :38 : 消费者服务 RestTemplate
2024-09-08 20:50:31.458 [TID:a7f970f0b12c411aa2b064304a353602.90.17257998314490001] DEBUG 3348 [provider-service] [nio-9000-exec-8] o.e.n.p.controller.TestController :26 : 提供者服务 RestTemplate
2024-09-08 20:50:31.463 [TID:a7f970f0b12c411aa2b064304a353602.90.17257998314490001] DEBUG 2888 [user-service] [nio-9007-exec-1] o.e.user.controller.UserController :31 : 用户服务 admin
总结
回到顶部
2024已过了大半,回望今年博客数量和质量突飞猛进,感觉学到了很多,也不算虚度吧。
2024-09-08记。