|
| 1 | +'use strict' |
| 2 | + |
| 3 | +const assert = require('node:assert/strict') |
| 4 | + |
| 5 | +const id = require('../../../packages/dd-trace/src/id') |
| 6 | +const SpanContext = require('../../../packages/dd-trace/src/opentracing/span_context') |
| 7 | +const TextMapPropagator = require('../../../packages/dd-trace/src/opentracing/propagation/text_map') |
| 8 | + |
| 9 | +const { VARIANT } = process.env |
| 10 | + |
| 11 | +const ITERATIONS = 300_000 |
| 12 | + |
| 13 | +// Duck-typed config keeps the bench out of the full `Config` singleton (telemetry |
| 14 | +// registration, env reads). The propagator only reads the fields below. |
| 15 | +const propagator = new TextMapPropagator({ |
| 16 | + tracePropagationStyle: { |
| 17 | + extract: ['datadog', 'tracecontext', 'baggage'], |
| 18 | + inject: ['datadog', 'tracecontext', 'baggage'], |
| 19 | + }, |
| 20 | + legacyBaggageEnabled: false, |
| 21 | + baggageMaxItems: 64, |
| 22 | + baggageMaxBytes: 8192, |
| 23 | + tagsHeaderMaxLength: 512, |
| 24 | + tracePropagationExtractFirst: false, |
| 25 | + tracePropagationBehaviorExtract: 'continue', |
| 26 | + baggageTagKeys: ['user.id', 'session.id', 'account.id'], |
| 27 | +}) |
| 28 | + |
| 29 | +// Realistic incoming carrier: traceparent + 4-vendor tracestate + 4-key baggage. Most |
| 30 | +// production baggage is plain ASCII (tenant / user / session / locale); the percent |
| 31 | +// variant lives below for the slow-path no-regression check. |
| 32 | +const EXTRACT_CARRIER_ASCII = { |
| 33 | + traceparent: '00-1234567890abcdef1234567890abcdef-1234567890abcdef-01', |
| 34 | + tracestate: 'dd=s:2;p:abc,vendor1=k1:v1,vendor2=k1:v1;k2:v2,foo=bar', |
| 35 | + baggage: 'tenant=acme,user=ada,session=abcdef0123456789,locale=en-US', |
| 36 | +} |
| 37 | + |
| 38 | +const EXTRACT_CARRIER_PERCENT = { |
| 39 | + ...EXTRACT_CARRIER_ASCII, |
| 40 | + baggage: 'tenant=acme%20corp,path=%2Forders%2Fnew,note=hello%20world', |
| 41 | +} |
| 42 | + |
| 43 | +const injectContext = new SpanContext({ |
| 44 | + traceId: id('1234567890abcdef'), |
| 45 | + spanId: id('abcdef1234567890'), |
| 46 | + sampling: { priority: 1 }, |
| 47 | + baggageItems: { tenant: 'acme', user: 'ada', session: 'abcdef0123456789' }, |
| 48 | + trace: { |
| 49 | + tags: { '_dd.p.dm': '-1', '_dd.p.tid': '1234567890abcdef' }, |
| 50 | + started: [], |
| 51 | + finished: [], |
| 52 | + }, |
| 53 | +}) |
| 54 | + |
| 55 | +// Pre-flight: confirm extract / inject are doing real work; catches a silent |
| 56 | +// breakage where the duck-typed config is missing a field the propagator now reads. |
| 57 | +const sanityExtract = propagator.extract(EXTRACT_CARRIER_ASCII) |
| 58 | +assert.ok(sanityExtract?._traceId, 'extract returned no trace id') |
| 59 | + |
| 60 | +const sanityInjected = {} |
| 61 | +propagator.inject(injectContext, sanityInjected) |
| 62 | +assert.ok(sanityInjected.traceparent && sanityInjected['x-datadog-trace-id'], 'inject populated no headers') |
| 63 | + |
| 64 | +if (VARIANT === 'extract' || VARIANT === 'extract-baggage-ascii') { |
| 65 | + for (let iteration = 0; iteration < ITERATIONS; iteration++) { |
| 66 | + propagator.extract(EXTRACT_CARRIER_ASCII) |
| 67 | + } |
| 68 | +} else if (VARIANT === 'extract-baggage-percent') { |
| 69 | + for (let iteration = 0; iteration < ITERATIONS; iteration++) { |
| 70 | + propagator.extract(EXTRACT_CARRIER_PERCENT) |
| 71 | + } |
| 72 | +} else if (VARIANT === 'inject') { |
| 73 | + for (let iteration = 0; iteration < ITERATIONS; iteration++) { |
| 74 | + propagator.inject(injectContext, {}) |
| 75 | + } |
| 76 | +} else if (VARIANT === 'extract-inject') { |
| 77 | + for (let iteration = 0; iteration < ITERATIONS; iteration++) { |
| 78 | + const extracted = propagator.extract(EXTRACT_CARRIER_ASCII) |
| 79 | + propagator.inject(extracted, {}) |
| 80 | + } |
| 81 | +} |
0 commit comments