11. 使用注释管理跨度
您可以使用各种注释来管理跨度。
11.1. 基本原理
使用注释管理跨度有很多充分的理由,包括:
-
与 API 无关的意味着与跨度协作。使用注释允许用户添加到对 span api 没有库依赖关系的 span。 这样做可以让 Sleuth 更改其核心 API,以减少对用户代码的影响。
-
减少基本跨度作的表面积。如果没有此功能,则必须使用 span api,该 API 具有可能使用不正确的生命周期命令。 通过仅公开范围、标记和日志功能,您可以进行协作而不会意外中断跨度生命周期。
-
与运行时生成的代码协作。使用 Spring Data 和 Feign 等库,接口的实现是在运行时生成的。 因此,对象的跨度包装很乏味。 现在,您可以为接口和这些接口的参数提供注释。
11.2. 创建新跨度
如果您不想手动创建本地范围,可以使用@NewSpan
注解。
此外,我们还提供@SpanTag
注释以自动方式添加标签。
现在我们可以考虑一些用法示例。
@NewSpan
void testMethod();
在没有任何参数的情况下对方法进行注释会导致创建一个新范围,其名称等于带注释的方法名称。
@NewSpan("customNameOnTestMethod4")
void testMethod4();
如果您在注释中提供值(直接或通过将name
参数),创建的 span 具有提供的值作为名称。
// method declaration
@NewSpan(name = "customNameOnTestMethod5")
void testMethod5(@SpanTag("testTag") String param);
// and method execution
this.testBean.testMethod5("test");
您可以组合名称和标签。让我们关注后者。
在这种情况下,带注释的方法的参数运行时值的值将成为标记的值。
在我们的示例中,标记键是testTag
,标签值为test
.
@NewSpan(name = "customNameOnTestMethod3")
@Override
public void testMethod3() {
}
您可以将@NewSpan
类和接口上的注释。
如果您覆盖接口的方法并为@NewSpan
注释,最
具体的获胜(在这种情况下customNameOnTestMethod3
已设置)。
11.3. 连续跨度
如果要向现有范围添加标记和注释,可以使用@ContinueSpan
注释,如以下示例所示:
// 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 种不同的方法可以向跨度添加标签。所有这些都由SpanTag
注解。
优先顺序如下:
-
尝试用
TagValueResolver
type 和提供的名称。 -
如果尚未提供 bean 名称,请尝试计算表达式。 我们搜索一个
TagValueExpressionResolver
豆。 缺省实现使用 SPEL 表达式解析。重要只能从 SPEL 表达式中引用属性。由于安全限制,不允许执行方法。 -
如果我们没有找到任何要计算的表达式,则返回
toString()
参数的值。
11.4.1. 自定义提取器
以下方法的标记值由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";
}
前面两个示例导致将标记值设置为Value from myCustomTagValueResolver
.
11.4.2. 解析值的表达式
考虑以下带注释的方法:
@NewSpan
public void getAnnotationForTagValueExpression(@SpanTag(key = "test",
expression = "'hello' + ' characters'") String test) {
}
没有自定义实现TagValueExpressionResolver
导致对 SPEL 表达式的评估,并且值为4 characters
设置在跨度上。
如果要使用其他表达式解析机制,可以创建自己的 bean 实现。
11.4.3. 使用toString()
方法
考虑以下带注释的方法:
@NewSpan
public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
}
运行值为15
导致设置 String 值为"15"
.