关于后端:项目中引入这玩意排查日志又快又准

10次阅读

共计 5259 个字符,预计需要花费 14 分钟才能阅读完成。

背景随着微服务流行,很多公司都把零碎依照业务边界拆成了很多微服务,在排错查日志的时候,因为业务链路贯通着很多微服务节点,导致定位某个申请的日志以及上下游业务的日志会变得有些艰难。这时候可能有的小伙伴就会想到应用 SkyWalking,Pinpoint 等分布式追踪零碎来解决,并且这些零碎通常都是无侵入性的,同时也会提供绝对敌对的治理界面来进行链路 Span 的查问,然而搭建分布式追踪零碎还是须要肯定的老本的,所以本文要说的并不是这些分布式追踪零碎,而是一款简略、易用、简直零侵入、适宜中小型公司应用的日志追踪框架 TLog。TLog 简介 TLog 提供了一种最简略的形式来解决日志追踪问题,TLog 会主动的对你的日志进行打标签,帮你主动生成 traceId 贯通你微服务的一整条链路,在排查日志的时候,能够依据 traceId 来疾速定位申请解决的链路。TLog 不收集日志,只在对你原来打印的日志上加强,将申请链路信息 traceId 绑定到你打印的日志上。当呈现微服务中那么多节点的状况,官网举荐应用 TLog+ 日志收集计划来解决。当然分布式追踪零碎其实是链路追踪一个最终的解决方案,如果我的项目中曾经上了分布式追踪零碎,那 TLog 并不实用。如下图,是 ELK 配合 TLog,疾速定位申请解决的链路的示例。

TLog 接入 1、接入步骤 1.1、引入依赖 <dependency>
    <groupId>com.yomahub</groupId>
    <artifactId>tlog-all-spring-boot-starter</artifactId>
    <version>1.5.0</version>
</dependency>1.2、替换 logback 配置项

到这其实就曾经实现了配置。1.3、测试

这里是通过 slf4j 的 LoggerFactory 获取 Logger 对象,因为 logback 适配了 slf4j,最终会通过 logback 来输入日志。

从这能够看出,11794076298070144 就是本次日志输入的时候生成的一个申请的 traceId,在排查日志的时候就能够通过这个 traceId 去搜寻出整个申请的链路日志。2、TLog 接入形式 TLog 总共提供了三种形式接入我的项目 Javaagent 接入形式字节码注入形式日志框架适配器形式下面案例的接入形式其实是属于日志框架适配器形式,并且是对于 Logback 框架的适配。TLog 除了适配了 Logback 框架,还适配了 Log4j 框架和 Log4j2 框架,我的项目中可自行抉择。Javaagent 接入形式和字节码注入形式相比与日志框架适配器形式对代码的入侵性更小,然而这两种形式仅仅只反对 SpringBoot 我的项目,并且相较于日志框架适配器的形式,MDC 和异步日志性能并不反对,所以要想残缺体验 TLog 的性能,还是倡议抉择日志框架适配器形式,日志框架适配器形式其实接入也很快,其实也就是批改一下配置文件的事。

我的项目环境兼容比照

个性反对比照 TLog 的基本原理 1、日志标签后面在介绍 TLog 的时候,提到 TLog 会主动的对你的日志进行打标签,这个标签就是日志标签,一个日志标签最多能够蕴含如下信息:preApp:接口调用方服务名 preHost:接口调用方 HostpreIp:接口调用方 ipcurrIp:以后服务 iptraceId:链路 id,调用方如果传递就是传递的值,不传递就会从新生成 spanId:链路 spanId 默认是依照如下 labelPattern 进行数据拼接生成日志标签,所以默认只打出 spanId 和 traceId。

这也就是下面为什么示例中会输入 <0><11794076298070144> 这种格局的起因,后面的 0 其实就是 spanId。如果你想扭转日志标签输入其它信息或者输入的程序,只须要在 SpringBoot 配置文件中配置日志标签的生成款式就行。tlog.pattern=$preApp][$preIp2、TLogContext

TLogContext 是 TLog 是一个外围的组件,这个组件外部是应用了 TransmittableThreadLocal 来传递 traceId、preApp 等信息。当有一个申请过去的时候,会从解析出 traceId、preApp 等信息,而后设置到 TransmittableThreadLocal 中,之后就能够在整个调用链路中从 TLogContext 中获取到 traceId 等信息。3、TLogRPCHandler

这个组件是用来解决调用方传递的 traceId、preApp 等信息,设置到 TLogContext 和 MDC 中,同时依据日志标签的格局生成日志标签。第三方框架的适配在理论我的项目中,一个申请处理过程可能会呈现以下状况异步线程解决跨服务调用 MQ 调用那么对于这些状况来说,traceId 应该须要在异步线程、跨服务、MQ 等中传递,以便更好地排查一个申请的解决链路。而 TLog 对于以上可能呈现的状况都做了大量的适配,保障 traceId 可能在异步线程、微服务间、MQ 等中可能正确传递。1、异步线程 1.1 个别异步线程所谓的个别异步线程就是指间接通过 new Thread 的办法来创立异步线程,而后来执行,这种形式 TLog 是人造反对携带 traceId 的,如图。

执行后果

从这能够看出这种异步形式确实胜利传递了 traceId。1.2 线程池对于线程池来说,其实默认也是反对传递 traceId,然而因为线程池中的线程是能够复用了,为了保障线程间的数据互不烦扰,须要应用 TLogInheritableTask 将提交的工作进行包装。ThreadPoolExecutor pool =
        new ThreadPoolExecutor(1, 2, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
pool.execute(new TLogInheritableTask() {
    @Override
    public void runTask() {
      logger.info(“ 异步执行 ”);
    }
}); 上述代码的写法会有点耦合,每次提交工作都须要创立一个 TLogInheritableTask,比拟麻烦,能够按如下写法进行简化。

TLogThreadPoolExecutor 本人写个 TLogThreadPoolExecutor 继承 ThreadPoolExecutor,重写 execute 办法 (submit 最终也会调用 execute 办法执行),而后将提交的工作对立包装成 TLogInheritableTask,这样须要应用线程池的中央间接创立 TLogThreadPoolExecutor 就能够了,就不须要在提交工作的时候创立 TLogInheritableTask 了。ThreadPoolExecutor pool =
        new TLogThreadPoolExecutor(1, 2, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
pool.execute(() -> logger.info(“ 异步执行 ”));2、对 RPC 框架的反对除了对异步线程的反对,TLog 也反对常见的 Dubbo,Dubbox,OpenFeign 三大 RPC 框架,在 SpringBoot 我的项目中不须要任何配置,只须要引入依赖就能够实现 traceId 在服务之间的传递 2.1 对 Dubbo 和 Dubbox 的反对对于 Dubbo 和 Dubbox 的反对是基于 Dubbo 的 Filter 扩大点来的

TLog 通过 SPI 机制扩大 Filter,在消费者发送申请前从 TLogContext 获取到 traceId,而后将 traceId 和其它调用者数据设置申请数据中,服务提供者在解决申请的时候,也会通过 Filter,从申请中获取到 traceId 等信息,而后设置到 TLogContext 中,从而实现了 traceId 在 dubbo 的消费者和提供者之间的传递。2.2 对 OpenFeign 的反对对于 OpenFeign 的反对其实也是通过 Feign 提供的扩大点 RequestInterceptor 来实现的

发送申请之前,从 TLogContext 获取到 traceId,将 traceId 等信息增加到申请头中,而后就能够通过 Http 申请将 traceId 等信息传递。当被调用方接管到申请之后,会通过 TLogWebInterceptor 这个拦截器进行拦挡,从申请头中获取到这些参数,设置到 TLogContext 中。

3、对罕用 Http 框架的反对除了一些 RPC 框架,TLog 也对一些 Http 框架进行了适配,比方 HttpClientOkhttphutool-httpRestTemplateforest 应用这些 Http 框架也能够实现 traceId 的传递其实这些框架的适配跟 Feign 的适配都是大同小异,都是基于这些 Http 框架各自提供的扩大点进行适配的,将 traceId 等信息放到申请头中,这里都不举例了,具体的应用办法能够在官网查看。4、对 SpringCloud Gateway 的反对同样的,TLog 也适配了 SpringCloud Gateway

原理也是一样的,就是适配了 Gateway 的 GlobalFilter,从申请头中获取 traceId 等信息。除了适配了 Gateway 网关,TLog 也适配了 Soul 网关。5、对 MQ 的反对对于 MQ 的反对跟异步线程差不多,须要将你发送的音讯包装成 TLogMqWrapBean 对象

TLogMqWrapBean 发送的时候间接发送 TLogMqWrapBean 对象过来 TLogMqWrapBean<BizBean> tLogMqWrap = new TLogMqWrapBean(bizBean);
mqClient.send(tLogMqWrap);TLogMqWrapBean 会将 traceId 等信息携带,消费者承受到 TLogMqWrapBean,而后通过 TLogMqConsumerProcessor 解决业务音讯。TLogMqConsumerProcessor.process(tLogMqWrapBean, new TLogMqRunner<BizBean>() {
    @Override
    public void mqConsume(BizBean o) {
     // 业务操作
    }
}); 如此就实现了 traceId 通过 MQ 传递。在理论应用中,依据不同的 MQ 的类型,能够将音讯包装成 TLogMqWrapBean 对象的过程和解决音讯的过程做对立的封装解决,以缩小发送音讯和解决音讯对于 TLog 的耦合。6、对工作框架的反对 TLog 次要是反对一下四种工作框架 JDK TimerQuartz 框架 spring-scheduledXXL-JOB 框架其中,spring-scheduled 和 XXL-JOB 在 SpringBoot 环境底下是无需工作配置的,只须要引入依赖即可。Timer 在应用的时候须要将工作包装成 TLogTimerTask,Quartz 须要把 QuartzJobBean 替换成 TLogQuartzJobBean 就能够了。小总结其实从下面的各种适配能够看出,其实实质都是一样的,就是依据具体框架的扩大点,在发送申请之前从 TLogContext 获取到 traceId,将 traceId 等调用者的信息在申请中携带,而后被调用方解析申请,取出 traceId 和调用者信息,设置到被调用方服务中的 TLogContext 中。所以,如果一旦须要遇到官网还未适配的框架或者组件,能够参照上述适配过程进行适配即可。最初总的来说,TLog 是一款十分优良的日志追踪的框架,很适宜中小公司应用。这里来总结一下 TLog 的个性通过对日志打标签实现轻量级微服务日志追踪提供三种接入形式:javaagent 齐全无侵入接入,字节码一行代码接入,基于配置文件的接入对业务代码无侵入式设计,应用简略,10 分钟即可接入反对常见的 log4j,log4j2,logback 三大日志框架,并提供自动检测,实现适配反对 dubbo,dubbox,feign 三大 RPC 框架反对 Spring Cloud Gateway 和 Soul 网关反对 HttpClient 和 Okhttp 等 http 调用框架标签传递反对多种工作框架,JDK 的 TimerTask,Quartz,XXL-JOB,spring-scheduled 反对日志标签的自定义模板的配置,提供多个零碎级埋点标签的抉择反对异步线程的追踪,包含线程池,多级异步线程等场景简直无性能损耗,疾速稳固,通过压测,损耗在 0.01% 因为本文篇幅无限,无奈全面对 TLog 进行解说,如果想深刻理解该框架,可自行浏览官网或者源码。官网:tlog.yomahub.comgithub 地址:github.com/dromara/TLo…

正文完
 0