概念
AttributesExtractor 是对 Span 的 setAttribute 方法进行业务的一种抽象封装
业务属性跟踪方式
使用 Span 的 setAttribute
1 2 3 4 5 6 7 8 9 10 11 12
| private static void doLogic() { User user=new User(); user.setId(1L); user.setName("curryzxh"); user.setPhone("10010"); UserService service=new UserService(); Span.current().setAttribute(AttributeKey.longKey("uid"),user.getId()); Span.current().setAttribute(AttributeKey.stringKey("name"),user.getName()); boolean bSave=service.saveUser(user); Span.current().setAttribute(AttributeKey.booleanKey("result"),bSave); }
|
AttributesExtractor 是 instrumentation 中非常重要的概念,每个组件基本都需要自定义实现 AttributesExtractor
接口定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public interface AttributesExtractor<REQUEST, RESPONSE> {
void onStart(AttributesBuilder attributes, REQUEST request);
void onEnd( AttributesBuilder attributes, REQUEST request, @Nullable RESPONSE response, @Nullable Throwable error);
default <T> void set(AttributesBuilder attributes, AttributeKey<T> key, @Nullable T value) { if (value != null) { attributes.put(key, value); } }
|
接口实现
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class UserAttributesExtractor implements AttributesExtractor<User,Boolean> {
@Override public void onStart(AttributesBuilder attributes, User user) { set(attributes, AttributeKey.longKey("uid"),user.getId()); set(attributes, AttributeKey.stringKey("name"),user.getName()); }
@Override public void onEnd(AttributesBuilder attributes, User user, @Nullable Boolean aBoolean, @Nullable Throwable error) { set(attributes,AttributeKey.booleanKey("result"),aBoolean); } }
|
调用方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class UserService {
UserAttributesExtractor extractor=new UserAttributesExtractor();
public Boolean saveUser(User user) { AttributesBuilder attributes = Attributes.builder();
extractor.onStart(attributes, user);
Boolean bSave = internalSaveUser(user); extractor.onEnd(attributes, user, bSave, null); Span.current().setAllAttributes(attributes.build()); return bSave; }
private Boolean internalSaveUser(User user) { return true; } }
|
切面对象定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| final class JoinPointRequest { private final JoinPoint joinPoint; private final Method method; private final WithSpan annotation;
JoinPointRequest(JoinPoint joinPoint) { this.joinPoint = joinPoint; MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); this.method = methodSignature.getMethod(); this.annotation = this.method.getDeclaredAnnotation(WithSpan.class); }
Method method() { return method; }
WithSpan annotation() { return annotation; }
Object[] args() { return joinPoint.getArgs(); } }
|
其有 3 个入参
- MethodExtractor:获取对象要调用的方法
- ParameterAttributeNamesExtractor:获取方法调用的参数名称
- MethodArgumentsExtractor:获取方法的参数值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public final class MethodSpanAttributesExtractor<REQUEST, RESPONSE> implements AttributesExtractor<REQUEST, RESPONSE> {
private final MethodExtractor<REQUEST> methodExtractor; private final MethodArgumentsExtractor<REQUEST> methodArgumentsExtractor; private final ParameterAttributeNamesExtractor parameterAttributeNamesExtractor;
public static <REQUEST, RESPONSE> MethodSpanAttributesExtractor<REQUEST, RESPONSE> newInstance( MethodExtractor<REQUEST> methodExtractor, ParameterAttributeNamesExtractor parameterAttributeNamesExtractor, MethodArgumentsExtractor<REQUEST> methodArgumentsExtractor) {
return new MethodSpanAttributesExtractor<>( methodExtractor, parameterAttributeNamesExtractor, methodArgumentsExtractor); }
@Override public void onStart(AttributesBuilder attributes, REQUEST request) { Method method = methodExtractor.extract(request); AttributeBindings bindings = cache.computeIfAbsent(method, this::bind); if (!bindings.isEmpty()) { Object[] args = methodArgumentsExtractor.extract(request); bindings.apply(attributes::put, args); } }
@Override public void onEnd( AttributesBuilder attributes, REQUEST request, @Nullable RESPONSE response, @Nullable Throwable error) {}
|
调用示例
1 2 3 4
| MethodSpanAttributesExtractor.newInstance( JoinPointRequest::method, new WithSpanAspectParameterAttributeNamesExtractor(), JoinPointRequest::args))
|