Shuzheng
Shuzheng

Reputation: 14018

What's the correct format for the Request-Id header, so that's recognized by the Azure Monitor OpenTelemetry package and used as the trace ID?

I want to send a Request-Id header, so that it's used by the Azure Monitor OpenTelemetry package for the operation ID.

I have made several attempts, including:

'Request-Id: |9e74f0e5-efc4-41b5-86d1-3524a43bd891.'

and

'Correlation-Context: Id=9e74f0e5-efc4-41b5-86d1-3524a43bd891'

However, none of these is recognized by ASP.NET Core.

The LegacyPropagator : DistributedContextPropagator in System.Diagnostics is responsible for parsing the trace ID from the Request-Id header with:

getter(carrier, RequestId, out traceId, out _);

I don't understand from this code how I supply the trace ID via the Request-Id header.

The correlation HTTP protocol, also called Request-Id, is being deprecated. This protocol defines two headers:

  • Request-Id: Carries the globally unique ID of the call.
  • Correlation-Context: Carries the name-value pairs collection of the distributed trace properties.

https://learn.microsoft.com/en-us/azure/azure-monitor/app/distributed-trace-data#correlation-headers-using-w3c-tracecontext

Upvotes: -1

Views: 79

Answers (1)

Suresh Chikkam
Suresh Chikkam

Reputation: 3448

To make the Request-Id header work properly, you need to follow the hierarchical request ID format specified by the deprecated correlation protocol. Specifically,

Format of Request-Id: |<root-id>.<local-id1>.<local-id2>.

  • Root Request ID : Request-Id: |9e74f0e5efc441b586d13524a43bd891.

  • Hierarchical Request ID with Span : Request-Id: |9e74f0e5efc441b586d13524a43bd891.1d2f3e4g5h6i7j8k.

| (vertical bar), . (dot), and _ (underscore) are reserved for hierarchical structure. These characters cannot be part of node values. hyphen - is allowed in node values.

This above format checks compatibility with the LegacyPropagator, which recognizes and parses the Request-Id header.

If you are only aiming to pass a custom trace ID for backward compatibility with legacy systems, the Request-Id format described above will suffice. But for full tracing capabilities, transitioning to the W3C Trace Context is recommended.

Here is the code for creating and managing Request-Id headers.

public static string GenerateRequestId(string traceId = null, string spanId = null)
{
    // Use provided traceId, or generate a new one (UUID without hyphens)
    var rootId = traceId ?? Guid.NewGuid().ToString("N");

    // Generate a unique local ID (span)
    var localId = spanId ?? Guid.NewGuid().ToString("N").Substring(0, 8); // Optional short span

    // Combine root and local IDs into a hierarchical Request-Id
    return $"|{rootId}.{localId}.";
}

You can also parse incoming headers and adjust their format.

public static string MapTraceparentToRequestId(string traceparent)
{
    // Example traceparent: "00-9e74f0e5efc441b586d13524a43bd891-1b2f3c4d5e6f7g8h-01"
    var parts = traceparent.Split('-');
    if (parts.Length < 2) return null;

    var traceId = parts[1]; // Extract <trace-id>
    var spanId = parts[2];  // Extract <span-id>
    return $"|{traceId}.{spanId}.";
}

Upvotes: 1

Related Questions