通过开源链路追踪客户端获取异常信息

本文介绍如何使用开源链路追踪客户端进行异常埋点,并在可观测链路 OpenTelemetry 版中进行异常分析。

前提条件

您已通过开源客户端接入可观测链路 OpenTelemetry 版,具体操作,请参见接入指南

设置Span的异常信息

OpenTelemetry异常规范

此规范适用于通过OpenTelemetry协议上报方式。

根据OpenTelemetry协议的异常规范,Span的异常信息存储在event属性中,当eventattributes中包含exception.type字段时,可观测链路 OpenTelemetry 版将认为该Span发生了异常并会展示在异常分析页面;如果能够获取到异常堆栈,可以添加至attributesexception.stacktrace字段中,那么异常分析页面即可查看对应的异常堆栈。

通过OpenTelemetry SDK,您无需手动在eventattributes中添加exception.type字段与exception.stacktrace字段,SDK提供了相关方法记录异常,下面以Java SDK为例展示如何为Span记录异常:

Span span = myTracer.startSpan("spanName");
try {
  // 执行业务代码
} catch (Throwable e) {
  span.recordException(e);
  throw e;
} finally {
  span.end();
}
说明

当使用OpenTelemetry自动埋点方式时,探针或框架会自动捕捉异常信息,并上报至服务端,可观测链路 OpenTelemetry 版将识别OpenTelemetry Span中的异常信息并展示在异常分析页面。

OpenTracing异常规范

此规范适用于通过Jaeger、SkywalkingZipkin协议上报方式。

根据OpenTracing协议的异常规范,Span的异常信息存储在log属性中,当log属性的tags中包含event字段为"error"且包含error.kind字段时,可观测链路 OpenTelemetry 版将认为该Span发生了异常并会展示在异常分析页面;如果能够获取到异常堆栈,可以添加至tagsstack字段中,那么异常分析页面可以查看对应的异常堆栈。

  • OpenTracing SDK异常埋点

    Java OpenTracing SDK为例,下面展示如何为Span记录异常:

    public static void test() {
      Tracer tracer = GlobalTracer.get();
      Span span = tracer.buildSpan("spanName").start();
    
      try (Scope scope = tracer.activateSpan(span)) {
        // ... 执行业务代码
      } catch (Exception e) {
          onException(e, span);
      } finally {
          span.finish();
      }
    }
    
    public static void onException(Throwable throwable, Span span) {
      if (span != null) {
        Tags.ERROR.set(span, Boolean.TRUE);
        if (throwable != null) {
          span.log(errorLogs(throwable));
        }
      }
    }
    
    private static Map<String, Object>  errorLogs(Throwable throwable) {
      Map<String, Object> errorLogs = new HashMap<>();
      errorLogs.put("event", Tags.ERROR.getKey());
      errorLogs.put("error.object", throwable);
      errorLogs.put("error.kind", throwable.getClass().getName());
      String message = throwable.getCause() != null ? throwable.getCause().getMessage() : throwable.getMessage();
      if (message != null) {
          errorLogs.put("message", message);
      }
      StringWriter sw = new StringWriter();
      throwable.printStackTrace(new PrintWriter(sw));
      errorLogs.put("stack", sw.toString());
      return errorLogs;
    }
  • Skywalking异常埋点

    Skywalking提供了大量无侵入式探针接入,通常探针埋点均会记录异常信息上报至服务端,可观测链路 OpenTelemetry 版将识别SkyWalking Span中的异常信息并展示在异常分析页面。

通过可观测链路 OpenTelemetry 版进行异常分析

在端侧埋点设置Span的异常信息后,可观测链路 OpenTelemetry 版将生成异常信息的统计数据,您可以前往可观测链路 OpenTelemetry 版控制台的异常分析页面查看,详细信息可参见异常分析