源码角度了解Skywalking之@Trace注解的原理

举报
周杰伦本人 发表于 2022/10/30 18:11:37 2022/10/30
【摘要】 源码角度了解Skywalking之@Trace注解的原理 使用 实现原理 @Trace注解的拦截 TraceAnnotationActivation TraceAnnotationMethodInterceptor TraceContext.traceId()的拦截 ActiveSpan方法的拦截 总结 源码角度了解Skywalking之@Trace注解的原理@Trace要解决的问题是收集...

源码角度了解Skywalking之@Trace注解的原理

@Trace要解决的问题是收集一些关键业务的Trace信息,使用方法就是在需要收集Trace信息的方法上添加@Trace注解就可以了。

使用

@Trace(operationName = "default-trace-method")
public void traceMethod() throws Exception {
    ActiveSpan.tag("trace-method", 
         String.valueOf(System.currentTimeMillis()));
    ActiveSpan.info("traceMethod info Message");
    System.out.println(TraceContext.traceId()); 
}

使用 @Trace 注释的方法,代理会创建localSpan。span操作名称的值将由operationName() 获取。如果 operationName()的值为空字符串,操作名将设置类名+方法名

方法中设置的tag,日志在Skywalking提供的前台界面中都能看到

实现原理

注解@Trace 的逻辑实现在apm-sniffer模块的apm-toolkit-activation子模块下,和其他插件一样,模块的内容主要包括三部分:

  1. def文件
  2. 切入点的定义类
  3. 对应切入点的拦截器

模块下的类的关系图如下:

@Trace注解的拦截

TraceAnnotationActivation

TraceAnnotationActivation实例方法切入点定义拦截标记Trace注解的方法,对应拦截器为TraceAnnotationMethodInterceptor拦截器

TraceAnnotationMethodInterceptor

TraceAnnotationMethodInterceptor的beforeMethod()

public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
    MethodInterceptResult result) throws Throwable {
    Trace trace = method.getAnnotation(Trace.class);
    String operationName = trace.operationName();
    if (operationName.length() == 0 || Config.Plugin.Toolkit.USE_QUALIFIED_NAME_AS_OPERATION_NAME) {
        operationName = MethodUtil.generateOperationName(method);
    }

    ContextManager.createLocalSpan(operationName);
}
  1. 获取方法的Trace注解的操作名称,如果为空就生成操作名:类名+方法名
  2. 创建LocalSpan

afterMethod()方法关闭span

handleMethodException()方法中向span中添加错误的log日志

TraceContext.traceId()的拦截

TraceContextActivation定义了拦截TraceContext类的traceId()方法,对应拦截器为TraceContextInterceptor

TraceContextInterceptor的beforeMethod()方法调用ContextManager.getGlobalTraceId()方法获取traceId来替换原来的traceId

ActiveSpan方法的拦截

ActiveSpan提供为当前活动跨度设置标签的自定义 api

ActiveSpanActivation拦截ActiveSpan的tag()方法,拦截器为ActiveSpanTagInterceptor,拦截器的beforeMethod()方法获取当前span,调用tag()添加tag信息

拦截ActiveSpan的debug()方法,拦截器为ActiveSpanDebugInterceptor,拦截器的beforeMethod()方法获取当前span,调用log()添加当前时间等debug级别日志信息

拦截ActiveSpan的info()方法,拦截器为ActiveSpanInfoInterceptor,拦截器的beforeMethod()方法获取当前span,调用info()添加当前时间等info级别日志信息

拦截ActiveSpan的error()方法,拦截器为ActiveSpanErrorInterceptor,拦截器的beforeMethod()方法获取当前span,调用errorOccurred()标记发生错误

拦截ActiveSpan的error(String errorMsg)方法,拦截器为ActiveSpanErrorMsgInterceptor,拦截器的beforeMethod()方法获取当前span,调用log()记录错误日志

拦截ActiveSpan的error(Throwable throwable)方法,拦截器为ActiveSpanErrorThrowableInteceptor,拦截器的beforeMethod()方法获取当前span,调用log()记录错误日志

总结

这篇文章主要讲了Skywalking的@Trace如何使用和它的原理,以及对TraceContext.traceId()的拦截和对ActiveSpan方法的拦截实现原理。@Trace注解可以让用户自定义需要记录trace信息的方法。TraceAnnotationActivation拦截带有@Trace注解的方法,然后通过TraceAnnotationMethodInterceptor增强拦截,具体就是创建LocalSpan记录Trace信息,TraceContextActivation拦截TraceContext.traceId()方法,拦截器替换之前的traceId

ActiveSpanActivation拦截ActiveSpan的一些方法,记录日志信息。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。