Sleuth+logback 設(shè)置traceid 及自定義信息方式
Sleuth+logback 設(shè)置traceid及自定義信息
背景:
分布式系統(tǒng)中,如何快速定位某個用戶的請求日志?
使用Sleuth生成的traceid可以跟蹤某個請求,但是很多時候我們需要知道traceid 與某個用戶的映射關(guān)系,方便定位某個用戶的日志
方案:
@Component
@Order(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER + 1)
public class CustomHttpSpanExtractor extends GenericFilterBean {
private final Tracer tracer;
CustomHttpSpanExtractor(Tracer tracer) {
this.tracer = tracer;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Span currentSpan = this.tracer.currentSpan();
if (currentSpan == null) {
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
try {
// mdc(httpRequest,currentSpan.context().traceIdString());
MDC.put(MdcConstant.USER_ID,"userid-12345");
} catch (Exception e) {
e.printStackTrace();
}
try {
chain.doFilter(request, response);
} finally {
MDC.clear();//must be,threadLocal
}
}}
logback 配置
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}[${applicationName},%X{X-B3-TraceId:-},%X{userId:-}] [%thread] %-5level %logger{50} - %msg%n</pattern>

logback簡單使用,自定義key
1.logback的pom依賴
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.11</version>
</dependency>
2.配置文件: logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="5000" debug="false">
<springProperty scope="context" name="springAppName" source="spring.application.name" defaultValue="defaultAppName"/>
<timestamp key="bySecond" datePattern="yyyy-MM-dd HH:mm:ss"/>
<appender name="STASH-REDIS" class="com.jlb.yts.common.util.aop.RedisAppender">
<key>${springAppName:-}</key>
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ALL</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter> -->
<layout>
<pattern>
{
"time": "%d{yyyy-MM-dd HH:mm:ss}",
"application":"tech_cloud",
"subapplication":"${springAppName:-}",
"level": "%level",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"parent": "%X{X-B3-ParentSpanId:-}",
"classname": "%logger{100}",
"msg": "%message"
}
</pattern>
</layout>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丟失日志.默認(rèn)的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默認(rèn)的隊列的深度,該值會影響性能.默認(rèn)值為256 -->
<queueSize>5120</queueSize>
<appender-ref ref="STASH-REDIS" />
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{40} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.jlb.yts" additivity="true" level="ERROR">
<appender-ref ref="ASYNC" />
</logger>
<logger name="com.jlb.yts" additivity="true" level="INFO">
<appender-ref ref="ASYNC" />
</logger>
<!-- mongodb打印語句 -->
<logger name="org.springframework.data.mongodb.core" level="DEBUG"/>
<logger name="com.jlb.yts" additivity="true" level="DEBUG">
<appender-ref ref="ASYNC" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3.自定義appender
package com.jlb.yts.common.util.aop;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.filter.Filter;
import com.jlb.yts.common.util.redis.RedisHandle;
import com.jlb.yts.common.util.redis.ReidsConnect;
import net.logstash.logback.layout.LoggingEventCompositeJsonLayout;
import java.lang.reflect.Field;
public class RedisAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
public static String service;
Layout<ILoggingEvent> layout;
public void setFilter(Filter<ILoggingEvent> filter) {
if(filter != null){
this.addFilter(filter);
}
}
String key = null;
public RedisAppender() {
layout = new LoggingEventCompositeJsonLayout();
}
private final static RedisHandle redisHandle = ReidsConnect.init("redis-log.properties","redis-log.properties");
@Override
protected void append(ILoggingEvent event) {
try {
LoggingEvent loggingEvent = (LoggingEvent) event;
String json = layout.doLayout(loggingEvent);
redisHandle.addList(key,json);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
String prefix = (System.getenv("APPLICATION_ENV") == null)?"dev":System.getenv("APPLICATION_ENV");
key = prefix + "-" + key;
this.key = key;
}
public Layout<ILoggingEvent> getLayout() {
return layout;
}
public void setLayout(Layout<ILoggingEvent> layout) {
this.layout = layout;
}
}
4.代碼實例
//注意導(dǎo)入的包都是slf4j的包
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackTest {
private static final Logger LOGGER = LoggerFactory.getLogger(LogbackTest.class);
public static void main(String[] args) {
LOGGER.trace("logback的--trace日志--輸出了");
LOGGER.debug("logback的--debug日志--輸出了");
LOGGER.info("logback的--info日志--輸出了");
LOGGER.warn("logback的--warn日志--輸出了");
LOGGER.error("logback的--error日志--輸出了");
}
}
5.日志添加自定義KEY
import org.slf4j.MDC; MDC.put(key, value);
logback.xml 配置
"key":"%X{key:-}"
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java與Python之間使用jython工具類實現(xiàn)數(shù)據(jù)交互
今天小編就為大家分享一篇關(guān)于Java與Python之間使用jython工具類實現(xiàn)數(shù)據(jù)交互,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
SpringBoot項目 文件上傳臨時目標(biāo)被刪除異常的處理方案
這篇文章主要介紹了SpringBoot項目 文件上傳臨時目標(biāo)被刪除異常的處理方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
使用JPA主鍵@Id,@IdClass,@Embeddable,@EmbeddedId問題
這篇文章主要介紹了使用JPA主鍵@Id,@IdClass,@Embeddable,@EmbeddedId問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
關(guān)于設(shè)置Mybatis打印調(diào)試sql的兩種方式
這篇文章主要介紹了關(guān)于設(shè)置Mybatis打印調(diào)試sql的兩種方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
springboot項目讀取resources目錄下的文件的9種方式
本文主要介紹了springboot項目讀取resources目錄下的文件的9種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
spring boot實現(xiàn)在request里解密參數(shù)返回
這篇文章主要介紹了Spring Boot實現(xiàn)在request里解密參數(shù)返回操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

