injectTracingHeaders function

void injectTracingHeaders(
  1. TracingContext context,
  2. TracingHeaderType headersType,
  3. Map<String, dynamic> headers, {
  4. TraceContextInjection contextInjection = TraceContextInjection.sampled,
})

Implementation

void injectTracingHeaders(
  TracingContext context,
  TracingHeaderType headersType,
  Map<String, dynamic> headers, {
  TraceContextInjection contextInjection = TraceContextInjection.sampled,
}) {
  const String baggageHeaderName = 'baggage';

  final sampledString = context.sampled ? '1' : '0';
  bool shouldInjectHeaders =
      context.sampled || contextInjection == TraceContextInjection.all;

  void addHeader(String key, String value) {
    if (!headers.containsKey(key)) {
      headers[key] = value;
    }
  }

  switch (headersType) {
    case TracingHeaderType.datadog:
      if (shouldInjectHeaders) {
        addHeader(
          DatadogHttpTracingHeaders.traceId,
          context.traceId.asString(TracingIdRepresentation.lowDecimal),
        );
        addHeader(
          DatadogHttpTracingHeaders.tags,
          '${DatadogHttpTracingHeaders.traceIdTag}=${context.traceId.asString(TracingIdRepresentation.highHex16Chars)}',
        );
        addHeader(
          DatadogHttpTracingHeaders.parentId,
          context.spanId.asString(TracingIdRepresentation.decimal),
        );
        addHeader(DatadogHttpTracingHeaders.origin, 'rum');
        addHeader(DatadogHttpTracingHeaders.samplingPriority, sampledString);

        headers[baggageHeaderName] = mergeW3CBaggageHeader(
          context,
          headers[baggageHeaderName],
        );
      }
      break;
    case TracingHeaderType.b3:
      if (context.sampled) {
        final headerValue = [
          context.traceId.asString(TracingIdRepresentation.hex32Chars),
          context.spanId.asString(TracingIdRepresentation.hex16Chars),
          sampledString,
          context.parentSpanId?.asString(TracingIdRepresentation.hex16Chars),
        ].whereType<String>().join('-');
        addHeader(OTelHttpTracingHeaders.singleB3, headerValue);
      } else if (contextInjection == TraceContextInjection.all) {
        addHeader(OTelHttpTracingHeaders.singleB3, sampledString);
      }
      break;
    case TracingHeaderType.b3multi:
      if (shouldInjectHeaders) {
        addHeader(OTelHttpTracingHeaders.multipleSampled, sampledString);
      }

      if (context.sampled) {
        addHeader(
          OTelHttpTracingHeaders.multipleTraceId,
          context.traceId.asString(TracingIdRepresentation.hex32Chars),
        );
        addHeader(
          OTelHttpTracingHeaders.multipleSpanId,
          context.spanId.asString(TracingIdRepresentation.hex16Chars),
        );
        if (context.parentSpanId != null) {
          addHeader(
            OTelHttpTracingHeaders.multipleParentId,
            context.parentSpanId!.asString(TracingIdRepresentation.hex16Chars),
          );
        }
      }
      break;
    case TracingHeaderType.tracecontext:
      if (shouldInjectHeaders) {
        final spanString = context.spanId.asString(
          TracingIdRepresentation.hex16Chars,
        );
        final parentHeaderValue = [
          '00', // Version Code
          context.traceId.asString(TracingIdRepresentation.hex32Chars),
          spanString,
          context.sampled ? '01' : '00',
        ].join('-');
        final stateHeaderValue = [
          's:$sampledString',
          'o:rum',
          'p:$spanString',
        ].join(';');
        addHeader(W3CTracingHeaders.traceparent, parentHeaderValue);
        addHeader(W3CTracingHeaders.tracestate, 'dd=$stateHeaderValue');

        headers[baggageHeaderName] = mergeW3CBaggageHeader(
          context,
          headers[baggageHeaderName],
        );
      }
      break;
  }
}