Previously, SOFATracer only supported component-level instrumentation. This made it difficult to add instrumentation to business code or add custom tags to monitor trace information. To address this issue, SOFATracer introduced manual and annotation-based instrumentation in versions 2.4.1 and 3.0.6.
You can implement custom instrumentation in two ways: manual instrumentation and annotation-based instrumentation.
Manual instrumentation
Manual instrumentation follows the OpenTracing specification. In SOFATracer, the beforeInvoke and afterInvoke functions encapsulate the span lifecycle.
The following code provides an example:
// Inject the tracer
@Autowired
Tracer tracer;
private void testManual() {
try {
// Start with beforeInvoke
SofaTracerSpan sofaTracerSpan = ((FlexibleTracer) tracer).beforeInvoke("testManual");
sofaTracerSpan.setTag("manualKey", "glmapper");
// do your biz
} catch (Throwable t) {
// End upon an exception
((FlexibleTracer) tracer).afterInvoke(t.getMessage());
} finally {
// End normally
((FlexibleTracer) tracer).afterInvoke();
}
}This method is less convenient than using annotations, but it provides a clear view of the span lifecycle. Manual instrumentation also complements annotation-based instrumentation.
Annotation-based instrumentation
SOFATracer provides the @Tracer annotation, which applies at the method level.
The following code provides an example:
// Use the @Tracer annotation on the hello method for instrumentation
@Tracer
public String hello(String word) {
// Custom tag data
SpanTags.putTags("author", "glmapper");
// Ineffective
helloInner(word);
return "glmapper : hello " + word;
}
// Use the @Tracer annotation on the hello method for instrumentation
@Tracer
private String helloInner(String word) {
return "glmapper : hello " + word;
}@Tracer is implemented based on Spring AOP and therefore relies on the proxy mechanism in Spring. As shown in the code snippet, the annotation-based instrumentation for the helloInner method fails. This happens because the method is executed using this instead of a proxy object. In this case, you can use manual instrumentation as a workaround.
SpanTags is a utility class that SOFATracer provides. When using annotation-based or manual instrumentation, you can use the static methods in this class to set tags.
Log format
JSON format
{"time":"2019-09-05 10:23:53.549","local.app":"flexible-sample","traceId":"0a0fe9291567650233504100130712","spanId":"0.2","span.kind":"client","result.code":"","current.thread.name":"http-nio-8080-exec-1","time.cost.milliseconds":"4ms","method":"hello","param.types":"java.lang.String","author":"glmapper","sys.baggage":"","biz.baggage":""}Non-JSON format
2019-09-0510:25:50.992,flexible-sample,0a0fe9291567650350953100130778,0.2,client,,http-nio-8080-exec-1,4ms,hello,param.types=java.lang.String&author=glmapper&,,