当前位置: 首页 > 知识库问答 >
问题:

使用@Newspan创建跨度时,不发送时间戳和持续时间

唐繁
2023-03-14

我正在使用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 Boot1.5.9和Spring Cloud Edgware SR2运行相同的代码时,它的行为与预期的一样。

下面是在Zipkin端收到的JSON。名为“child-span-with-annotation”的span是使用@newspan创建的,而span“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个答案

蓬弘
2023-03-14

这是一个bug-https://github.com/spring-cloud/spring-cloud-sleuth/issues/855。我把它修好了。一种解决方法是在每个使用@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()

 类似资料:
  • 问题内容: 对于某些Hibernate实体,我们需要存储其创建时间和上次更新时间。你将如何设计? 你将在数据库中使用什么数据类型(假设使用MySQL,可能与JVM时区不同)?数据类型是否支持时区? 你会在Java中使用什么数据类型(Date,Calendar,long,…)? 你将由谁负责设置时间戳(数据库,ORM框架(hibernate)或应用程序程序员)? 你将使用哪些注释进行映射(例如@Te

  • 对于我的项目,我必须读取在CSV文件中提供给我们的数据并以某种格式将其写出。我几乎完成了,但我遇到的问题是我的程序没有完全读取给定的时间。从这里开始,我的程序只是读取所有给定的时间。 我试图将<code>字符串时间。 这应该会回来 [芝麻街|埃尔莫之最1240:28:11] 但它返回 [Elmo的最佳|芝麻街124;2:29,1:30,2:09,1:46,1:55,2:02,1:42,2:40,1

  • null null 线程组用于登录事务,有57个示例。当我点击Run时,整个线程不是运行1800秒,而是运行84秒 运行前有什么需要检查或配置的吗?

  • 我们有一个应用程序,我们在其中对REST API进行一些内部超文本传输协议调用来获取数据。但是有些请求花费的时间比预期的要长,所以我尝试增加超时持续时间。我尝试了以下操作: RequestConfig RequestConfig=RequestConfig.custom()。setConnectTimeout(30*1000)。build();HttpClient HttpClient=HttpC

  • 在我的应用程序中,用户需要能够输入持续时间,包括分钟和秒。 我正在考虑使用Windows中的控件来更改时间,虽然我只需要几分钟和几秒钟,而且箭头也很好,但不是必需的。 JavaFX 2中是否已经有此控件 如果没有,我如何创建这样的控件 上述Windows控件的屏幕截图: 谢谢你的提示!

  • 我需要使用API V3获取YouTube内容长度。我的应用程序在API V3上运行良好,但现在不起作用了。 我发现了一个可行的例子,它确实有效: 学分: Youtube API v3 ,如何获取视频时长? 这将返回类似如下的时间格式。 我怎样才能把这个时间缩短到一个可读的时间呢。比如24:30?