sschmeck
sschmeck

Reputation: 7715

Get operation_Id/operation_ParentId in inbound section of APIM policy

I setup an Azure API Management service with Correlation protocol set to W3C. It uses the header traceparent for context propagation. If the API client sets traceparent header, the APIM service maps its content to the Azure Application Insights attributes operation_Id and operation_ParentId.

If the the traceparent header isn't set by the client, both attributes are generated by the service and provided via context.Request.Headers after the backend processing, which means also after the inbound processing. As a result, all <send-request> calls of the inbound section (e.g. authentication/validation logic) aren't able to propagate the tracing context correctly via the traceparent header.

Is there any support for accessing generated tracing context in the inbound section of an APIM policy?

  1. As workaround I tried to set the traceparent header with manually generated values, but it's not considered/used by the service (e.g. for <trace> or backend calls).
  2. I checked RequestId from the Context variable, but it contains a different value than operation_id.

Alternatively, it there a solution to aggregate all telemetry data with same trace context?

Upvotes: 1

Views: 422

Answers (1)

sschmeck
sschmeck

Reputation: 7715

I implemented a workaround using the Request Id as custom trace-id values in addition with a complex Kusto query.

  1. If no traceparent is provided by the API client, set a custom header following Get traceparent generated by APIM and return from response header.
    <set-header name="traceparent" exists-action="skip">
      <value>@($"00-{context.RequestId.ToString("N")}-0000000000000000-01")</value>
    </set-header>
    
  2. Extend the Kusto query according to the custom trace-id/operation_Id.
    let operationId="<APIM operation_Id value>";
    let customOperationIds=toscalar(requests
    | where operation_Id  == operationId
    | where customDimensions['Service Type'] == 'API Management'
    | extend customOperationId=replace_string(tostring(customDimensions['Request Id']), '-', '')
    | where customOperationId != operation_Id
    | summarize requestId=make_set(customOperationId, 1000));
    union *
    | where operation_Id in (operationId, customOperationIds)
    | order by timestamp asc
    

Upvotes: 0

Related Questions