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 + "]";
        String osName = System.getProperties().get("os.name").toString().toLowerCase(Locale.ROOT);
        return osName.startsWith("win") ? original.replaceAll("\r\n\t", traceId + "\r\n\t") : original.replaceAll("\n\t", traceId + "\n\t");
    }
}

此时的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在堆栈信息以及主日志中都打印了出来

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lllllLiangjia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值