使用@NewSpan创建范围时,不会发送时间戳和持续时间

时间:2018-02-13 04:26:08

标签: zipkin spring-cloud-sleuth

我正在使用Spring Cloud Sleuth和Zipkin(通过HTTP),将spring-cloud-starter-zipkin版本2.0.0.M6添加到我的依赖项中(基于Spring Boot 2.0.0.RC1和Spring Cloud Finchley M6)

我正在使用@Newspan注释来标记一个(昂贵的)操作周围的子项。当跨度信息发送到Zipkin时,我注意到子跨度的时间戳和持续时间丢失。这导致Zipking方面的奇怪渲染。但是,当我通过调用tracer#newChild创建子跨度时,它按预期工作。

我错过了什么吗?这是Sleuth 2.0.0.M6的问题吗?

当我使用Spring Boot 1.5.9和Spring Cloud Edgware SR2运行相同的代码时,它的行为符合预期。

这是Zipkin方面收到的JSON。名为“child-span-with-annotation”的范围是使用@NewSpan创建的范围,而范围“childspanwithnewchild”是使用跟踪器#newChild创建的。

[
  {
    "traceId": "b1c2636366c919be",
    "id": "b1c2636366c919be",
    "name": "get",
    "timestamp": 1518495271073166,
    "duration": 862032,
    "annotations": [
      {
        "timestamp": 1518495271073166,
        "value": "sr",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      },
      {
        "timestamp": 1518495271935198,
        "value": "ss",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      }
    ],
    "binaryAnnotations": [
      {
        "key": "ca",
        "value": true,
        "endpoint": {
          "serviceName": "",
          "ipv6": "::1",
          "port": 51982
        }
      },
      {
        "key": "http.path",
        "value": "/hello",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      },
      {
        "key": "mvc.controller.class",
        "value": "MyRestController",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      },
      {
        "key": "mvc.controller.method",
        "value": "sayHello",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      }
    ]
  },
  {
    "traceId": "b1c2636366c919be",
    "id": "14be7ac6eafb0e01",
    "name": "child-span-with-annotation",
    "parentId": "b1c2636366c919be",
    "binaryAnnotations": [
      {
        "key": "class",
        "value": "MyService",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      },
      {
        "key": "method",
        "value": "expensiveOperation1",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      }
    ]
  },
  {
    "traceId": "b1c2636366c919be",
    "id": "b34a4f910f27fdb4",
    "name": "childspanwithnewchild",
    "parentId": "b1c2636366c919be",
    "timestamp": 1518495271479040,
    "duration": 453747,
    "binaryAnnotations": [
      {
        "key": "lc",
        "value": "",
        "endpoint": {
          "serviceName": "sample-sleuth-app",
          "ipv4": "---.---.---.---"
        }
      }
    ]
  }
]

1 个答案:

答案 0 :(得分:1)

这是一个错误 - https://github.com/spring-cloud/spring-cloud-sleuth/issues/855。我已经修好了ATM。解决方法是在每个使用@NewSpan的方法中手动启动它,方法是在当前范围内调用start()方法(不能很好地扩展)

@Autowired SpanCustomizer customizer;

@NewSpan
void foo() {
    this.customizer.start();
}

您还可以创建SpanCreator的bean(您可以在此处查看固定版本https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/DefaultSpanCreator.java

class MySpanCreator implements SpanCreator {

    private static final Log log = LogFactory.getLog(MySpanCreator.class);

    private final Tracing tracer;

    MySpanCreator(Tracing tracer) {
        this.tracer = tracer;
    }

    @Override public Span createSpan(MethodInvocation pjp, NewSpan newSpanAnnotation) {
        String name = StringUtils.isEmpty(newSpanAnnotation.name()) ?
                pjp.getMethod().getName() : newSpanAnnotation.name();
        String changedName = SpanNameUtil.toLowerHyphen(name);
        if (log.isDebugEnabled()) {
            log.debug("For the class [" + pjp.getThis().getClass() + "] method "
                    + "[" + pjp.getMethod().getName() + "] will name the span [" + changedName + "]");
        }
        return this.tracer.tracer().nextSpan().name(changedName).start();
    }

}

注意方法末尾的.start()