Correlation with Activity with Application Insights (3) W3C TraceContext
I post two blogs. Please read these if you haven’t read these, yet.
In this post, I’ll write about the W3C TraceContext correlation with Activity.
What is the W3C TraceContext?
W3C TraceContext is the different protocol of the distributed tracing compared with HTTP correlation protocol which is implemented by Activity. You can refer the details on the following document. It is currently the public working draft. In the near feature, this protocol can be mainstream. Microsoft also contributes to the Distributed Tracing Working Group.
Overview
Let’s see the overview of the protocol. The protocol has two headers like this.
Field traceparent
identifies the request in a tracing system.
The tracestate
HTTP header field conveys information about request position in multiple distributed tracing graphs.
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
tracestate: congo=BleGNlZWRzIHRohbCBwbGVhc3VyZS4
Traceparent
If you are using Application Insights, You can create correlation only using traceparent field. Traceparent can be divided into four parts. For the correlation of the Application Insights, focus on traceid
and spanid
traceid
is very similar with RootId. and traceid
+ spanid
is like Id.
The version
is the version for TraceContext spec. Currently, it is fixed with 00. traceflags
are the flags. Currently, it can be 00 or 01. However, shortly, it might be expanded. Now we don’t need care that.
Value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
base16(<version>) = 00
base16(<traceid>) = 4bf92f3577b34da6a3ce929d0e0e4736
base16(<spanid>) = 00f067aa0ba902b7
base16(<traceflags>) = 01
Tracestate
Currently, Application Insights doesn’t care that. You can make it null. However, I’d like to explain the overview. This field used for controlling the correlation among the different system include a 3rd party. If you use congo system, the tracestate
is like this.
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
tracestate: congo=BleGNlZWRzIHRohbCBwbGVhc3VyZS4
Then congo send message to rojo. As you can see, the format of the tracestate
can be different. The first trace is current one.
traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
tracestate: rojo=00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01,congo=BleGNlZWRzIHRohbCBwbGVhc3VyZS4
rojo send a message to the congo again. As you can see the congo state comes first. Currently, I can’t find the specific rule for Application Insights or ASP.NET or Azure Functions; I can’t find the spec for these resources. Now, Application Insights only seems to care the traceparent
for correlation. However, I recommend passing the tracestate
without a change in your application.
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01
tracestate: congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
Activity provides the extension methods to support the W3C TraceContext. I want to explain how to use it.
You can find some info for the W3C TraceContext with SDK.
Implementation
Activity can handle both on HTTP correlation protocol and W3C TraceContext. However, you need to pick one for a single request.
Ignore the warning
Before starting writing code, you need to ignore the warning. W3C implementation is still under construction. It is not publicly used until now. However, you can ignore the warning and use it by this #pragma . The interface can be changed in the future.
#pragma warning disable 618
Create a new Activity
If you want to create a new Activity, You can do like this.
var activity = new Activity("HttpTrigger Request");
activity.GenerateW3CContext();
activity.Start();
This will create the first correlation info.
SetTraceparent/Tracestate (SetParentId equivalent for W3C TraceContext)
If you want to set the parent, you can use SetTraceparent
and SetTracestate
adds the parent activity’s Traceparent and Tracestate.
activity.SetTraceparent(parent.GetTraceparent());
activity.SetTracestate(parent.GetTracestate());
activity.Start();
The behavior of the activity.Start() is the same as the HTTP Correlation protocol. Which means they don’t care the W3C spec. You don’t need to care about the activity.Id, activity.ParentId, and activity.RootId for the W3C scenario. Activity has W3C TraceContext on the Tags.
The behavior of the SetTraceparent is
- Set the ParentSpanId with Activity which is passed as a parameter.
- GenerateSpanId
Create Request/DependencyTelemetry with W3C Activity
Let’s see how to setActivity to the Request/DependencyTelemetry.
var telemetry = new RequestTelemetry {Name = activity.OperationName};
telemetry.Id = $"|{activity.GetTraceId()}.{activity.GetSpanId()}";
telemetry.Context.Operation.Id = activity.GetTraceId();"
telemetry.Context.Operation.ParentId = $"|{activity.GetTraceId()}.{activity.GetParentSpanId()}";
We use the same the same correlation property with HTTP correlation protocol. For W3C TraceContext, we only use TraceId and SpanId which is on the Traceparent.
Comparison
Working sample
I create a sample with actual trace context. I’m implementing on the Azure Functions. Http can automatically be tracked. However, I wrote everything manually to understand the behavior. The sample code starts with; it sends queue to the orchestrator. Then the orchestrator sends queue to Activity; the Activity sends back a queue to the orchestrator. Note the Orchestrator is called twice. Although it is using a queue, it is the same as Orchestrator calls an Activity Function and get the results then finish the orchestration.
NOTE: Activity is not the Activity class. It is Azure Function’s name.
As you can see,
Result
You can see the Operation Id = traceid
, ParentId = traceId.parentSpanId
, RequestId = traceId.SpanId
. All successfully emitted and correlated.
It works!
Code Sample
TelemetryClient’s Extension methods don’t support W3C TraceContext currently. You need to use Activity with Request/Dependency Telemetry.
You can see the whole source code here.
Conclusion
I explain all about the detail of the Activity. I hope you enjoy this.