Requirements: In microservice architecture, when encountering problems, it is often very difficult to troubleshoot, not knowing whether it is an exception thrown by the service, it may be that the service writes a bug, or there is a problem with the information transmitted by the service that calls the service. If the context of all requests can be recorded, that is, the link to the entire full transaction request, it is critical to troubleshoot and analyze the problem.
Review:
Exception stack traces are ideal for applications that target a single process, such as a monolithic application system. But on the other hand, for dealing with distributed applications, such as microservices architectures, stack traces are not enough to show the overall message trace. This is why distributed tracing tools and standards become necessary. The W3C defines a standard for this type of trace called Trace Context.
Trace Context standard
W3C Trace Context documentation:The hyperlink login is visible.
The W3C Trace Context specification defines standards and formats for HTTP headers to propagate distributed trace context information. It defines 2 fields that are used to propagate the trace flow in the HTTP request header. Let's take a look at these 2 fields in the standard definition:
- traceparent: 用来描述在追踪图谱中到达请求的位置。它表示在追踪系统中到达请求的通用格式,被所有的 vendor 所理解。
- tracestate: 使用 vendor 特定的数据表示形式来扩展 traceparent,使用 name/value 对形式。在 tracestate 中保存信息是可选的。
traceparent field
The specification for the traceparent field is defined in the form of the Extended Baccos Paradigm (ABNF) and consists of 4 parts:
version - traceid - parentid/spanid - traceflags For example:
00-480e22a2781fe54d992d878662248d94-b4b37b64bb3f6141-00
- version: 8 位,系统适配的追踪上下文版本,当前位 00
- trace-id: 16 字节,追踪整体的标识。用于在系统中标识一个分布式追踪整体,The value is exactly the same in the same link。
- parent-id/span-id: 8 bytes to express the parent of the current span in an inbound request or an outbound request.
- trace-flags: 8 位,调用者的建议标志,可以考虑为调用者的建议,限制为 3 个原因:信息或是滥用,调用方的错误,或者在调用方与被调用方的不同负载。
All fields are encoded in hexadecimal, as shown in the image below:
.NET distributed tracing
Distributed tracing is a diagnostic technique that helps engineers localize failures and performance issues in applications, especially those that may be distributed across multiple computers or processes. This technique correlates the work done by different application components together through request tracking in the application and separates it from other work that the application might perform when handling concurrent requests. For example, a load balancer might first receive a request for a typical web service, then forward it to a web server process, and then issue multiple queries to the database. With distributed tracing, engineers can distinguish whether these steps failed, how long each step takes, and what messages may be logged when each step runs.
In .NET, the System.Diagnostics.Activity library has been configured to use the W3C standard. The W3C-style traceparent header Request-Id header was added in ASP.NET Core 2.0. To change it to a traceparent header that conforms to the W3C Trace Context, set the Activity.DefaultIdFormat static property to W3C when you start the program. The code is as follows:
test process,Browser -> A service (/http, backend uses HttpClient to request B service) interface -> B service (/test) interface, Service A outputs its own Trace Context and Service B's Trace Context, the code is as follows:
Start services A and B, as shown in the following figure:
The browser opens Service A, as shown in the following figure:
Id: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: bd06e8d507a43f42
ParentId:
Response content:{"id":"00-9891603e6c4921598951f425d98e4df7-8874f9b2f9c0702e-00","traceId":"9891603e6c4921598951f425d98e4df7","spanId":"8874f9b2f9c0702e","parentId": "00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00","traceFlags":"None","isSampled":false}
--------------------------------------------------
Name: HttpHandlerDiagnosticListener
DateTime: 2025/12/22 9:37:22
Id: 00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00
TraceId: 9891603e6c4921598951f425d98e4df7
SpanId: e0336cc56a4f2150
ParentId: 00-9891603e6c4921598951f425d98e4df7-bd06e8d507a43f42-00
Key: System.Net.Http.HttpRequestOut.Stop, Value: { Response = StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{ Date: Mon, 22 Dec 2025 01:37:21 GMT Server: Kestrel Transfer-Encoding: chunked Connection: keep-alive Content-Type: application/json; charset=utf-8 }, Request = Method: GET, RequestUri: 'http://localhost.charlesproxy.com:5551/test', Version: 1.1, Content: <null>, Headers:
{ traceparent: 00-9891603e6c4921598951f425d98e4df7-e0336cc56a4f2150-00 }, RequestTaskStatus = RanToCompletion } -------------------------------------------------- Using the Charles Proxy packet capture tool, the request and response are as follows:
If you want to disable the HttpClient from passing traceparent, the environment variables are set as follows:
Reference:
The hyperlink login is visible.
The hyperlink login is visible.
The hyperlink login is visible.
The hyperlink login is visible.
The hyperlink login is visible.
The hyperlink login is visible. |