java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > logback和log4j日志框架堆栈信息添加TraceId

logback和log4j日志框架堆栈信息添加TraceId方式

作者:lllllLiangjia

这篇文章主要介绍了logback和log4j日志框架堆栈信息添加TraceId方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

背景

TraceId是我在项目上自定义的,作为链路追踪来使用。至于为什么没有用市面上skywalking此类现成的链路追踪,是因为目前这个项目是boot单体,也不是分布式,不想引入过多比较复杂的依赖项,造成不必要的维护麻烦。

使用traceId只是来准确定位某个请求的日志信息,自己实现的话比较轻量化,也能够满足项目的开发和维护需求。

当请求访问时,被过滤器拦截到,生成一个唯一的traceId存放在MDC中(分布式项目可以通过请求头获取上游服务传过来的traceId),MDC是ThreadLocal类型线程安全的。

日志xml配置写上traceId会自动读取MDC。

logback日志框架

由于之前项目是使用的logback日志框架,如果只在xml日志文件中配置traceId的话,当报错时候输出的堆栈信息内不会保存traceId。

到时候线上排查问题,无法通过grep命令筛选出来报错的堆栈信息,也就不能快速定位代码中的报错位置。

堆栈信息不携带traceId

xml配置文件中的配置

堆栈信息携带traceId

logback想要在堆栈信息中添加traceId需要继承ThrowableProxyConverter,重写里面的方法。

import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
import ch.qos.logback.classic.spi.IThrowableProxy;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
public class CompressedStackTraceConverter extends ThrowableProxyConverter {
    public CompressedStackTraceConverter() {
    }
    @Override
    protected String throwableProxyToString(IThrowableProxy tp) {
        String original = super.throwableProxyToString(tp);
        String traceId = MDC.get("traceId");
        if (StringUtils.isBlank(traceId)) {
            traceId = "";
        }
        traceId = "\t[ably-stack]\t[" + traceId + "]";
        return original.replaceAll("\n", traceId + "\n");
    }
}

此时的xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <conversionRule conversionWord="ex"
                    converterClass="com.example.springbootdemo.configuration.httpglobal.CompressedStackTraceConverter"/>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern xml:space="preserve">
                %d{yyyy-MM-dd HH:mm:ss.SSS}|-|%lsn|-|%thread|-|%X{traceType}|-|%X{traceId}|-|%logger{80}:%L|-|%msg|-|%ex|-|%n
            </pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

这样logback框架就可以打印堆栈信息的时候携带traceId了

log4j日志框架

目前这个新项目使用的log4j这个框架,这里的traceId也是放在MDC中。

堆栈信息不携带traceId

堆栈信息携带traceId

当我配置好traceId后,开始配置堆栈信息中的traceId,发现ThrowableProxyConverter是logback包下面的,无法使用它来添加。

于是我在网上找是否log4j有对应的像logback这种接口可以操作堆栈信息的。无果!(也有可能我没找到)。

后来偶然查到%throwable可以支持更改单个堆栈跟踪元素,我就想可不可以使用它来添加traceId。

通过了解%throwable的常用方法,看到了配合{suffix(pattern)}使用,可以在每个堆栈帧的末尾添加模式输出。

于是抱着试一试的态度就打印traceId,结果是可以的。

对应的traceId在堆栈信息以及主日志中都打印了出来

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文