11. 使用 Comments 管理 Span
您可以使用各种注释来管理 span。
11.1. 基本原理
使用 Comments 管理 span 有很多充分的理由,包括:
-
API 不可知的意思是与 span 协作。使用注释允许用户添加到 span,而无需依赖于 span api。 这样做可以让 Sleuth 更改其核心 API,以减少对用户代码的影响。
-
减少了基本跨度作的表面积。如果没有此功能,您必须使用 span api,该 api 包含可能被错误使用的生命周期命令。 通过仅公开范围、标签和日志功能,您可以进行协作,而不会意外中断 span 生命周期。
-
与运行时生成的代码协作。使用 Spring Data 和 Feign 等库,接口的实现是在运行时生成的。 因此,对象的 span 包装很繁琐。 现在,你可以通过接口和这些接口的参数提供注释。
11.2. 创建新的 Span
如果您不想手动创建本地 span,可以使用@NewSpan
注解。
此外,我们还提供@SpanTag
annotation 以自动方式添加标记。
现在我们可以考虑一些用法示例。
@NewSpan
void testMethod();
在没有任何参数的情况下对方法进行注释会导致创建一个名称等于带注释的方法名称的新 span。
@NewSpan("customNameOnTestMethod4")
void testMethod4();
如果您在注解中提供值(直接或通过设置name
参数),则创建的 span 将提供的值作为名称。
// method declaration
@NewSpan(name = "customNameOnTestMethod5")
void testMethod5(@SpanTag("testTag") String param);
// and method execution
this.testBean.testMethod5("test");
您可以组合名称和标签。让我们专注于后者。
在这种情况下,带注释方法的参数 runtime value 的值将成为 tag 的值。
在我们的示例中,标签键是testTag
,tag 值为test
.
@NewSpan(name = "customNameOnTestMethod3")
@Override
public void testMethod3() {
}
您可以将@NewSpan
注解。
如果您覆盖接口的方法并为@NewSpan
annotation 中,最
具体者获胜(在这种情况下customNameOnTestMethod3
已设置)。
11.3. 连续跨度
如果要向现有 span 添加标签和注释,可以使用@ContinueSpan
annotation 中,如以下示例所示:
// method declaration
@ContinueSpan(log = "testMethod11")
void testMethod11(@SpanTag("testTag11") String param);
// method execution
this.testBean.testMethod11("test");
this.testBean.testMethod13();
(请注意,与@NewSpan
注解,你也可以使用log
参数。
这样,跨度就会继续,并且:
-
名为
testMethod11.before
和testMethod11.after
创建。 -
如果引发异常,则名为
testMethod11.afterFailure
。 -
键为
testTag11
和值test
已创建。
11.4. 高级标签设置
有 3 种不同的方法可以向 Span 添加标签。它们都由SpanTag
注解。
优先级如下:
-
尝试使用 bean 的
TagValueResolver
type 和提供的名称。 -
如果未提供 bean 名称,请尝试计算表达式。 我们搜索
TagValueExpressionResolver
豆。 默认实现使用 SPEL 表达式解析。重要您只能从 SPEL 表达式中引用属性。由于安全约束,不允许执行方法。 -
如果找不到任何要计算的表达式,则返回
toString()
值。
11.4.1. 自定义提取器
以下方法的 tag 值由TagValueResolver
接口。
它的类名必须作为resolver
属性。
请考虑以下带注释的方法:
@NewSpan
public void getAnnotationForTagValueResolver(
@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
}
现在进一步考虑以下内容TagValueResolver
bean 实现:
@Bean(name = "myCustomTagValueResolver")
public TagValueResolver tagValueResolver() {
return parameter -> "Value from myCustomTagValueResolver";
}
前面的两个示例导致将 tag 值设置为等于Value from myCustomTagValueResolver
.
11.4.2. 解析值的表达式
请考虑以下带注释的方法:
@NewSpan
public void getAnnotationForTagValueExpression(@SpanTag(key = "test",
expression = "'hello' + ' characters'") String test) {
}
没有TagValueExpressionResolver
导致对 SPEL 表达式进行求值,并且值为4 characters
设置在 span 上。
如果要使用其他表达式解析机制,则可以创建自己的 bean 实现。
11.4.3. 使用toString()
方法
请考虑以下带注释的方法:
@NewSpan
public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
}
运行上述值为15
导致设置 String 值为"15"
.