11. 使用注释管理跨度

您可以使用各种注释来管理跨度。spring-doc.cadn.net.cn

11.1. 基本原理

使用注释管理跨度有很多充分的理由,包括:spring-doc.cadn.net.cn

  • 与 API 无关的意味着与跨度协作。使用注释允许用户添加到对 span api 没有库依赖关系的 span。 这样做可以让 Sleuth 更改其核心 API,以减少对用户代码的影响。spring-doc.cadn.net.cn

  • 减少基本跨度作的表面积。如果没有此功能,则必须使用 span api,该 API 具有可能使用不正确的生命周期命令。 通过仅公开范围、标记和日志功能,您可以进行协作而不会意外中断跨度生命周期。spring-doc.cadn.net.cn

  • 与运行时生成的代码协作。使用 Spring Data 和 Feign 等库,接口的实现是在运行时生成的。 因此,对象的跨度包装很乏味。 现在,您可以为接口和这些接口的参数提供注释。spring-doc.cadn.net.cn

11.2. 创建新跨度

如果您不想手动创建本地范围,可以使用@NewSpan注解。 此外,我们还提供@SpanTag注释以自动方式添加标签。spring-doc.cadn.net.cn

现在我们可以考虑一些用法示例。spring-doc.cadn.net.cn

@NewSpan
void testMethod();

在没有任何参数的情况下对方法进行注释会导致创建一个新范围,其名称等于带注释的方法名称。spring-doc.cadn.net.cn

@NewSpan("customNameOnTestMethod4")
void testMethod4();

如果您在注释中提供值(直接或通过将name参数),创建的 span 具有提供的值作为名称。spring-doc.cadn.net.cn

// method declaration
@NewSpan(name = "customNameOnTestMethod5")
void testMethod5(@SpanTag("testTag") String param);

// and method execution
this.testBean.testMethod5("test");

您可以组合名称和标签。让我们关注后者。 在这种情况下,带注释的方法的参数运行时值的值将成为标记的值。 在我们的示例中,标记键是testTag,标签值为test.spring-doc.cadn.net.cn

@NewSpan(name = "customNameOnTestMethod3")
@Override
public void testMethod3() {
}

您可以将@NewSpan类和接口上的注释。 如果您覆盖接口的方法并为@NewSpan注释,最 具体的获胜(在这种情况下customNameOnTestMethod3已设置)。spring-doc.cadn.net.cn

11.3. 连续跨度

如果要向现有范围添加标记和注释,可以使用@ContinueSpan注释,如以下示例所示:spring-doc.cadn.net.cn

// method declaration
@ContinueSpan(log = "testMethod11")
void testMethod11(@SpanTag("testTag11") String param);

// method execution
this.testBean.testMethod11("test");
this.testBean.testMethod13();

(请注意,与@NewSpan注释,您还可以使用log参数。spring-doc.cadn.net.cn

这样,跨度就会继续下去,并且:spring-doc.cadn.net.cn

11.4. 高级标签设置

有 3 种不同的方法可以向跨度添加标签。所有这些都由SpanTag注解。 优先顺序如下:spring-doc.cadn.net.cn

  1. 尝试用TagValueResolvertype 和提供的名称。spring-doc.cadn.net.cn

  2. 如果尚未提供 bean 名称,请尝试计算表达式。 我们搜索一个TagValueExpressionResolver豆。 缺省实现使用 SPEL 表达式解析。重要只能从 SPEL 表达式中引用属性。由于安全限制,不允许执行方法。spring-doc.cadn.net.cn

  3. 如果我们没有找到任何要计算的表达式,则返回toString()参数的值。spring-doc.cadn.net.cn

11.4.1. 自定义提取器

以下方法的标记值由TagValueResolver接口。 它的类名必须作为resolver属性。spring-doc.cadn.net.cn

考虑以下带注释的方法:spring-doc.cadn.net.cn

@NewSpan
public void getAnnotationForTagValueResolver(
        @SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
}

现在进一步考虑以下内容TagValueResolverbean 实现:spring-doc.cadn.net.cn

@Bean(name = "myCustomTagValueResolver")
public TagValueResolver tagValueResolver() {
    return parameter -> "Value from myCustomTagValueResolver";
}

前面两个示例导致将标记值设置为Value from myCustomTagValueResolver.spring-doc.cadn.net.cn

11.4.2. 解析值的表达式

考虑以下带注释的方法:spring-doc.cadn.net.cn

@NewSpan
public void getAnnotationForTagValueExpression(@SpanTag(key = "test",
        expression = "'hello' + ' characters'") String test) {
}

没有自定义实现TagValueExpressionResolver导致对 SPEL 表达式的评估,并且值为4 characters设置在跨度上。 如果要使用其他表达式解析机制,可以创建自己的 bean 实现。spring-doc.cadn.net.cn

11.4.3. 使用toString()方法

考虑以下带注释的方法:spring-doc.cadn.net.cn

@NewSpan
public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
}

运行值为15导致设置 String 值为"15".spring-doc.cadn.net.cn