src/libraries/System.Diagnostics.DiagnosticSource/src/FlatRequestId.md
Starting with System.Diagnostics.DiagnosticSource 4.6.0 (that ships with .Net Core 3.0), we are moving towards W3C Trace-Context standard. We still support Request-Id (hierarchical version) and it is still the default format for System.Diagnostics.Activity.
This specification for Flat Request-Id is deprecated.
There is no corresponding implementation in .NET and if you are looking into 'flat' correlation protocol - we recommend following W3C Trace-Context.
This document provide guidance for implementations of HTTP Correlation Protocol without Hierarchical Request-Id support or interoperability with services that do not support it.
We strongly recommend every implementation to support Hierarchical Request-Id wherever possible. If implementation do not support it, it still MUST ensure essential requirements are met:
Request-Id uniquely identifies every HTTP request involved in operation processing and MUST be generated for every incoming and outgoing requestCorrelation-Context has Id property serving as single unique identifier of the whole operation and implementation MUST generate one if it is missing.It is important to log Request-Id received from the upstream service along with the incoming request. It ensures that parent-child relationships between requests are retained and the whole tree of the requests could be restored.
Therefore implementations MUST provide access to the 'parent' Request-Id for logging system.
Root Request Id requirements and generation considerations must be used for flat Request-Id
Many applications and tracing systems use single correlation/trace id to identify whole operation through all services and client applications. In case of heterogeneous environment (where some services generate hierarchical Request-Ids and others generate flat Ids) having single identifier, common for all requests, helps to make telemetry query simple and efficient.
If implementation generates flat Request-Id, it MUST ensure Id is present in Correlation-Context or generate new one and add to the Correlation-Context.
If implementation needs to add Id property to Correlation-Context:
abcId=123Request-Id: abc, Correlation-Context: Id=123Request-Id: defRequest-Id: def, Correlation-Context: Id=123Request-Id: ghi, Correlation-Context: Id=123Request-Id: ghi, Correlation-Context: Id=123Request-Id: def, Correlation-Context: Id=123As a result log records may look like:
| Message | Component Name | Context |
|---|---|---|
| user starts request to service-a | user | |
| incoming request | service-a | Request-Id=abc; Parent-Request-Id=; Id=123 |
| request to service-b | service-a | Request-Id=def; Parent-Request-Id=abc, Id=123 |
| incoming request | service-b | Request-Id=ghi; Parent-Request-Id=def; Id=123 |
| response | service-b | Request-Id=ghi; Parent-Request-Id=def; Id=123 |
| response from service-b | service-a | Request-Id=def; Parent-Request-Id=abc; Id=123 |
| response | service-a | Request-Id=abc; Parent-Request-Id=; Id=123 |
| response from service-a | user |
Id=123 match, logs for particular request may be queried by exact Request-Id matchIn heterogeneous environment, some services may support hierarchical Request-Id generation and others may not.
Requirements listed Request-Id help to ensure all telemetry for the operation still is accessible:
Correlation-Context and MAY add Id if missingCorrelation-Context and MUST add Id if missingLet's imagine service-a supports hierarchical Request-Id and service-b does not:
Request-Id.|Guid.Request-Id: |Guid.Request-Id: |Guid.1_Request-Id: |Guid.1_defCorrelation-Context. It parses parent Request-Id, extracts root node: Guid and adds Id property to CorrelationContext : Id=abcRequest-Id: |Guid.1_As a result log records may look like:
| Message | Component Name | Context |
|---|---|---|
| incoming request | service-a | `Request-Id= |
| request to service-b | service-a | `Request-Id= |
| incoming request | service-b | `Request-Id=def; Parent-Request-Id= |
| response | service-b | `Request-Id=def; Parent-Request-Id= |
| response from service-b | service-a | `Request-Id= |
| response | service-a | `Request-Id= |
Correlation-Context: Id to the root node of Request-IdId == Guid || RequestId.startsWith('|Guid')Correlation-Context: Id immediately and it's propagated further and still may be used to query all logs.