22// SPDX-License-Identifier: Apache-2.0
33
44import { AWSCloudWatchEMFExporter } from '../src/exporter/aws/metrics/aws-cloudwatch-emf-exporter' ;
5- import { Span , TraceFlags , Tracer } from '@opentelemetry/api' ;
5+ import { propagation , ROOT_CONTEXT , Span , TextMapGetter , trace , TraceFlags , Tracer } from '@opentelemetry/api' ;
66import { OTLPMetricExporter as OTLPGrpcOTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc' ;
77import { OTLPMetricExporter as OTLPHttpOTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http' ;
88import { OTLPTraceExporter as OTLPGrpcTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc' ;
@@ -90,6 +90,12 @@ describe('AwsOpenTelemetryConfiguratorTest', () => {
9090 ( awsOtelConfigurator as any ) . spanProcessors . forEach ( ( spanProcessor : SpanProcessor ) => {
9191 spanProcessor . shutdown ( ) ;
9292 } ) ;
93+
94+ delete process . env . OTEL_TRACES_EXPORTER ;
95+ delete process . env . OTEL_METRICS_EXPORTER ;
96+ delete process . env . OTEL_LOGS_EXPORTER ;
97+ delete process . env . OTEL_TRACES_SAMPLER ;
98+ delete process . env . OTEL_TRACES_SAMPLER_ARG ;
9399 } ) ;
94100
95101 // The probability of this passing once without correct IDs is low, 20 times is inconceivable.
@@ -110,6 +116,107 @@ describe('AwsOpenTelemetryConfiguratorTest', () => {
110116 }
111117 } ) ;
112118
119+ describe ( 'Propagator Extraction' , ( ) => {
120+ const envVarsToRestore : NodeJS . ProcessEnv = { } ;
121+ beforeEach ( ( ) => {
122+ for ( const [ key , value ] of Object . entries ( process . env ) ) {
123+ if ( key . startsWith ( 'OTEL_' ) ) {
124+ envVarsToRestore [ key ] = value ;
125+ delete process . env [ key ] ;
126+ }
127+ }
128+ } ) ;
129+
130+ afterEach ( ( ) => {
131+ // Clean-up
132+ for ( const [ key , value ] of Object . entries ( envVarsToRestore ) ) {
133+ process . env [ key ] = value ;
134+ }
135+ } ) ;
136+
137+ it ( 'Default Propagator extraction of Trace Context works if only X-Ray Trace Header is set' , ( ) => {
138+ const carrier : Record < string , string > = {
139+ 'X-Amzn-Trace-Id' :
140+ 'Root=1-5759e988-bd862e3fe1bf46a994270000;Parent=53945c3f42cd0000;Sampled=1;Lineage=a87bd80c:1|68fd508a:5|c512fbe3:2' ,
141+ } ;
142+ const textMapGetter : TextMapGetter = {
143+ keys : ( carrier : Record < string , string > ) : string [ ] => {
144+ return Object . keys ( carrier ) ;
145+ } ,
146+ get : ( carrier : Record < string , string > , key : string ) => {
147+ return carrier ?. [ key ] ;
148+ } ,
149+ } ;
150+
151+ // Create configurator with default settings and AgentObservability enabled for this test case
152+ setAwsDefaultEnvironmentVariables ( ) ;
153+ const customAwsOtelConfigurator = new AwsOpentelemetryConfigurator ( [ ] ) ;
154+ const customAwsOtelConfiguration = customAwsOtelConfigurator . configure ( ) ;
155+
156+ const tracerProvider : NodeTracerProvider = new NodeTracerProvider ( customAwsOtelConfiguration ) ;
157+ const tracer : Tracer = tracerProvider . getTracer ( 'test' ) ;
158+
159+ const contextAfterExtraction = customAwsOtelConfiguration . textMapPropagator ?. extract (
160+ ROOT_CONTEXT ,
161+ carrier ,
162+ textMapGetter
163+ ) ;
164+
165+ // Test Trace Context extraction directly
166+ const spanContextAfterExtraction = trace . getSpanContext ( contextAfterExtraction ! ) ;
167+ expect ( spanContextAfterExtraction ?. traceId ) . toEqual ( '5759e988bd862e3fe1bf46a994270000' ) ;
168+ expect ( spanContextAfterExtraction ?. spanId ) . toEqual ( '53945c3f42cd0000' ) ;
169+ expect ( spanContextAfterExtraction ?. traceFlags ) . toEqual ( 1 ) ;
170+
171+ // Test Trace Context extraction indirectly through span creation
172+ const span : Span = tracer . startSpan ( 'test' , undefined , contextAfterExtraction ) ;
173+ span . end ( ) ;
174+ const spanContext = span . spanContext ( ) ;
175+
176+ expect ( spanContext . traceId ) . toEqual ( '5759e988bd862e3fe1bf46a994270000' ) ;
177+ expect ( ( span as any ) . parentSpanId ) . toEqual ( '53945c3f42cd0000' ) ;
178+ expect ( spanContext . traceFlags ) . toEqual ( 1 ) ;
179+ } ) ;
180+
181+ it ( 'Propagator extracts session.id baggage header attribute into to span attributes when Agent Observability is enabled' , ( ) => {
182+ // Create configurator with default settings and AgentObservability enabled for this test case
183+ setAwsDefaultEnvironmentVariables ( ) ;
184+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
185+ const customAwsOtelConfigurator = new AwsOpentelemetryConfigurator ( [ ] ) ;
186+ const customAwsOtelConfiguration = customAwsOtelConfigurator . configure ( ) ;
187+
188+ const tracerProvider : NodeTracerProvider = new NodeTracerProvider ( customAwsOtelConfiguration ) ;
189+ const tracer : Tracer = tracerProvider . getTracer ( 'test' ) ;
190+
191+ const carrier : Record < string , string > = {
192+ baggage : 'session.id=test-adot-js-dev' ,
193+ } ;
194+ const textMapGetter : TextMapGetter = {
195+ keys : ( carrier : Record < string , string > ) : string [ ] => {
196+ return Object . keys ( carrier ) ;
197+ } ,
198+ get : ( carrier : Record < string , string > , key : string ) => {
199+ return carrier ?. [ key ] ;
200+ } ,
201+ } ;
202+ const contextAfterExtraction = customAwsOtelConfiguration . textMapPropagator ?. extract (
203+ ROOT_CONTEXT ,
204+ carrier ,
205+ textMapGetter
206+ ) ;
207+
208+ // Test baggage is set directly
209+ const baggageAfterExtraction = propagation . getBaggage ( contextAfterExtraction ! ) ;
210+ expect ( baggageAfterExtraction ?. getAllEntries ( ) . length ) . toEqual ( 1 ) ;
211+ expect ( baggageAfterExtraction ?. getEntry ( 'session.id' ) ?. value ) . toEqual ( 'test-adot-js-dev' ) ;
212+
213+ // Test baggage is set indirectly through span creation
214+ const span : Span = tracer . startSpan ( 'test' , undefined , contextAfterExtraction ) ;
215+ span . end ( ) ;
216+ expect ( ( span as any ) . attributes [ 'session.id' ] ) . toEqual ( 'test-adot-js-dev' ) ;
217+ } ) ;
218+ } ) ;
219+
113220 // Sanity check that the trace ID ratio sampler works fine with the x-ray generator.
114221 it ( 'TraceIdRatioSamplerTest' , ( ) => {
115222 process . env . OTEL_AWS_APPLICATION_SIGNALS_ENABLED = 'True' ;
@@ -604,14 +711,14 @@ describe('AwsOpenTelemetryConfiguratorTest', () => {
604711
605712 function validateConfiguratorEnviron ( ) {
606713 // Set by register.ts
607- expect ( 'http/protobuf' ) . toEqual ( process . env . OTEL_EXPORTER_OTLP_PROTOCOL ) ;
608- expect ( 'xray,tracecontext' ) . toEqual ( process . env . OTEL_PROPAGATORS ) ;
714+ expect ( process . env ) . toHaveProperty ( ' OTEL_EXPORTER_OTLP_PROTOCOL' , 'http/protobuf' ) ;
715+ expect ( process . env ) . toHaveProperty ( ' OTEL_PROPAGATORS' , 'tracecontext,baggage,xray' ) ;
609716
610717 // Not set
611- expect ( undefined ) . toEqual ( process . env . OTEL_TRACES_SAMPLER ) ;
612- expect ( undefined ) . toEqual ( process . env . OTEL_TRACES_SAMPLER_ARG ) ;
613- expect ( undefined ) . toEqual ( process . env . OTEL_TRACES_EXPORTER ) ;
614- expect ( undefined ) . toEqual ( process . env . OTEL_METRICS_EXPORTER ) ;
718+ expect ( process . env ) . not . toHaveProperty ( ' OTEL_TRACES_SAMPLER' ) ;
719+ expect ( process . env ) . not . toHaveProperty ( ' OTEL_TRACES_SAMPLER_ARG' ) ;
720+ expect ( process . env ) . not . toHaveProperty ( ' OTEL_TRACES_EXPORTER' ) ;
721+ expect ( process . env ) . not . toHaveProperty ( ' OTEL_METRICS_EXPORTER' ) ;
615722 }
616723
617724 it ( 'OtelTracesSamplerInputValidationTest' , ( ) => {
0 commit comments