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.atatus:
      if (shouldInjectHeaders) {
        addHeader(
          AtatusHttpTracingHeaders.traceId,
          context.traceId.asString(TracingIdRepresentation.hex32Chars),
        );
        addHeader(
          AtatusHttpTracingHeaders.parentId,
          context.spanId.asString(TracingIdRepresentation.hex16Chars),
        );
        addHeader(AtatusHttpTracingHeaders.origin, 'rum');
        addHeader(AtatusHttpTracingHeaders.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);
        // ATCHG - Change dd to atatus
        addHeader(W3CTracingHeaders.tracestate, 'atatus=$stateHeaderValue');
        // ATCHG - End

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

  if (kDebugMode && shouldInjectHeaders) {
    // print('⚡ [Atatus Agent] Injecting Tracing Headers: $headersType -> ${headers.entries.where((e) => e.key.toLowerCase().contains('atatus') || e.key.toLowerCase().contains('trace') || e.key.toLowerCase().contains('b3')).map((e) => '${e.key}: ${e.value}').join(', ')}');
  }
}