手把手教你skywalking二开之扩展logback日志%tid

2023-12-20 13:04

本文主要是介绍手把手教你skywalking二开之扩展logback日志%tid,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党

skywalking 版本

  • 9.4.0

背景

目前系统服务全链路透传使用的是skywalking,大家都知道接入skywalking会再log里面添加一个tid的打印

比如这样。那么如果我们想新增一个我们自定义的标签怎么处理呢?比如我想新增一个uid
变成

2023-12-19 22:07:01.361  INFO  10 [TID:8e3374d0c5394da58fa58b12f1a8c6ae.163.17029696213611565] [Uid:234]

tid的实现原理分析

apm-toolkit-logback-1.x 修改

这里我们以logback为例

一般我们在log.xml里面都会新增一个占位符,比如

    <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(%X{tl:-}){yellow} %clr(${PID:- }){magenta} %clr([%tid]){faint}  %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"><pattern>${CONSOLE_LOG_PATTERN}</pattern></layout><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder></appender>

这里我们就加了tid。如果要实现我们自定义的uid的话,我们肯定也是要加一个占位符比如uid

我们首先看看skywalking是如何实现的

首先在LogbackPatternConverter类实现ClassicConverter给一个默认值

public class LogbackPatternConverter extends ClassicConverter {/*** As default, return "TID: N/A" to the output message, if SkyWalking agent in active mode, return the real traceId* in the recent Context, if existed.** @param iLoggingEvent the event* @return the traceId: N/A, empty String, or the real traceId.*/@Overridepublic String convert(ILoggingEvent iLoggingEvent) {return "TID: N/A";}
}

之后将LogbackPatternConverter添加到PatternLayoutdefaultConverterMap

public class TraceIdPatternLogbackLayout extends PatternLayout {static {defaultConverterMap.put("tid", LogbackPatternConverter.class.getName());}
}

可以看到到此为止都只是给默认值。

这一快的代码都是在apm-toolkit-logback-1.x 这个sdk实现的。

增强定义(agent)

接下来真正的实现当然是放在agent里面去做的首先去继承ClassInstanceMethodsEnhancePluginDefine

/*** Active the toolkit class "org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter". Should not* dependency or import any class in "skywalking-toolkit-logback-1.x" module. Activation's classloader is diff from* "org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter", using direct will trigger classloader* issue.* <p>*/
public class LogbackPatternConverterActivation extends ClassInstanceMethodsEnhancePluginDefine {public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.PrintTraceIdInterceptor";public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter";public static final String ENHANCE_METHOD = "convert";/*** @return the target class, which needs active.*/@Overrideprotected ClassMatch enhanceClass() {return byName(ENHANCE_CLASS);}/*** @return null, no need to intercept constructor of enhance class.*/@Overridepublic ConstructorInterceptPoint[] getConstructorsInterceptPoints() {return null;}/*** @return the collection of {@link StaticMethodsInterceptPoint}, represent the intercepted methods and their* interceptors.*/@Overridepublic InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {return new InstanceMethodsInterceptPoint[] {new InstanceMethodsInterceptPoint() {@Overridepublic ElementMatcher<MethodDescription> getMethodsMatcher() {return named(ENHANCE_METHOD).and(takesArgumentWithType(0, "ch.qos.logback.classic.spi.ILoggingEvent"));}@Overridepublic String getMethodsInterceptor() {return INTERCEPT_CLASS;}@Overridepublic boolean isOverrideArgs() {return false;}}};}
}

这里主要定义agent要增强哪个类、哪个方法。比如这里就通过ENHANCE_CLASS定义增强类,ENHANCE_METHOD定义增强的方法

之后再skywalking-plugin.def配置类中添加这个类

INTERCEPT_CLASS拦截class就是配置我们下面要写的也就是真正的实现类

拦截器(agent)

之后再写一个真正实现增强的拦截器

public class PrintTraceIdInterceptor implements InstanceMethodsAroundInterceptor {@Overridepublic void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,MethodInterceptResult result) throws Throwable {}@Overridepublic Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,Object ret) throws Throwable {if (!ContextManager.isActive()) {if (allArguments[0] instanceof EnhancedInstance) {SkyWalkingContext skyWalkingContext = (SkyWalkingContext) ((EnhancedInstance) allArguments[0]).getSkyWalkingDynamicField();if (skyWalkingContext != null) {return "TID:" + skyWalkingContext.getTraceId();}}}return "TID:" + ContextManager.getGlobalTraceId();}@Overridepublic void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,Class<?>[] argumentsTypes, Throwable t) {}
}

可以看到这个类也是比较简单,实现InstanceMethodsAroundInterceptor即可。

然后有方法执行前,执行后,执行异常的各个增强点,和AOP优点类似。
看名字就知道这个方法是干嘛的,名字取得非常好

如何增加uid打印

通过上面的分析我们就知道如果我们要实现增加一个uid的打印我们需要如何开发

  1. apm-toolkit-logback-1.x中继承ClassicConverter添加默认值处理类比如LogbackUidPatternConverter
public class LogbackUidPatternConverter extends ClassicConverter {/*** As default, return "TID: N/A" to the output message, if SkyWalking agent in active mode, return the real traceId* in the recent Context, if existed.** @param iLoggingEvent the event* @return the traceId: N/A, empty String, or the real traceId.*/@Overridepublic String convert(ILoggingEvent iLoggingEvent) {return "Uid:null";}
}
  1. LogbackUidPatternConverter添加到TraceIdPatternLogbackLayout
public class TraceIdPatternLogbackLayout extends PatternLayout {static {defaultConverterMap.put("tid", LogbackPatternConverter.class.getName());defaultConverterMap.put("uid", LogbackUidPatternConverter.class.getName());}
}
  1. apm-toolkit-logback-1.x默认sdk打包,其他项目升级到这个打包出来的新版本

  2. agent中apm-toolkit-logback-1.x-activation新增拦截器PrintUidInterceptor

public class PrintUidInterceptor implements InstanceMethodsAroundInterceptor {@Overridepublic void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,MethodInterceptResult result) throws Throwable {}@Overridepublic Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,Object ret) throws Throwable {if (!ContextManager.isActive()) {if (allArguments[0] instanceof EnhancedInstance) {SkyWalkingContext skyWalkingContext = (SkyWalkingContext) ((EnhancedInstance) allArguments[0]).getSkyWalkingDynamicField();if (skyWalkingContext != null) {return "Uid:null";}}}if (Objects.nonNull(ContextManager.getCorrelationContext())) {return "Uid:" + ContextManager.getCorrelationContext().get("x-xiazou-uid").orElse(null);}return "Uid:null";}@Overridepublic void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,Class<?>[] argumentsTypes, Throwable t) {}
}
  1. 新增LogbackUidConverterActivation继承ClassInstanceMethodsEnhancePluginDefine定义增强点
public class LogbackUidConverterActivation extends ClassInstanceMethodsEnhancePluginDefine {public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.PrintUidInterceptor";public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackUidPatternConverter";public static final String ENHANCE_METHOD = "convert";/*** @return the target class, which needs active.*/@Overrideprotected ClassMatch enhanceClass() {return byName(ENHANCE_CLASS);}/*** @return null, no need to intercept constructor of enhance class.*/@Overridepublic ConstructorInterceptPoint[] getConstructorsInterceptPoints() {return null;}/*** @return the collection of {@link StaticMethodsInterceptPoint}, represent the intercepted methods and their* interceptors.*/@Overridepublic InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {return new InstanceMethodsInterceptPoint[] {new InstanceMethodsInterceptPoint() {@Overridepublic ElementMatcher<MethodDescription> getMethodsMatcher() {return named(ENHANCE_METHOD).and(takesArgumentWithType(0, "ch.qos.logback.classic.spi.ILoggingEvent"));}@Overridepublic String getMethodsInterceptor() {return INTERCEPT_CLASS;}@Overridepublic boolean isOverrideArgs() {return false;}}};}}
  1. LogbackUidConverterActivation添加到skywalking-plugin.def配置中

  2. 打包agent升级agent即可

总结

总的来说修改起来还是比较简单的,主要是skywalking这一套都高度封装了。我们只需要实现或者继承对应的接口(类)即可

这篇关于手把手教你skywalking二开之扩展logback日志%tid的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/516152

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[

PHP7扩展开发之字符串处理

前言 这次,我们来看看字符串在PHP扩展里面如何处理。 示例代码如下: <?phpfunction str_concat($prefix, $string) {$len = strlen($prefix);$substr = substr($string, 0, $len);if ($substr != $prefix) {return $prefix." ".$string;} else

PHP7扩展开发之类型处理

前言 这次,我们将演示如何在PHP扩展中如何对类型进行一些操作。如,判断变量类型。要实现的PHP代码如下: <?phpfunction get_size ($value) {if (is_string($value)) {return "string size is ". strlen($value);} else if (is_array($value)) {return "array si

PHP7扩展开发之依赖其他扩展

前言 有的时候,我们的扩展要依赖其他扩展。比如,我们PHP的mysqli扩展就依赖mysqlnd扩展。这中情况下,我们怎么使用其他扩展呢?这个就是本文讲述的内容。 我们新建立一个扩展,名字叫 demo_dep , 依赖之前的say扩展。 在demo_dep扩展中,我们实现demo_say方法。这个方法调用say扩展的say方法。 代码 基础代码 确保say扩展的头文件正确安装到了php