当前位置 : 主页 > 编程语言 > java >

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

来源:互联网 收集:自由互联 发布时间:2022-10-15
源码角度了解Skywalking之@Trace注解的原理 @Trace要解决的问题是收集一些关键业务的Trace信息,使用方法就是在需要收集Trace信息的方法上添加@Trace注解就可以了。 使用 @Trace(operationName =

源码角度了解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子模块下,和其他插件一样,模块的内容主要包括三部分:

  • def文件
  • 切入点的定义类
  • 对应切入点的拦截器
  • 模块下的类的关系图如下:

    @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); }
  • 获取方法的Trace注解的操作名称,如果为空就生成操作名:类名+方法名
  • 创建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的一些方法,记录日志信息。

    ❤️ 感谢大家

    如果你觉得这篇内容对你挺有有帮助的话:

  • 欢迎关注我❤️,点赞
  • 上一篇:源码角度了解Skywalking之Trace可以跨线程吗
    下一篇:没有了
    网友评论