@@ -42,6 +42,8 @@ import { setAwsDefaultEnvironmentVariables } from '../src/register';
4242import { AwsXRayRemoteSampler } from '../src/sampler/aws-xray-remote-sampler' ;
4343import { AwsXraySamplingClient } from '../src/sampler/aws-xray-sampling-client' ;
4444import { GetSamplingRulesResponse } from '../src/sampler/remote-sampler.types' ;
45+ import { OTLPAwsSpanExporter } from '../src/otlp-aws-span-exporter' ;
46+ import { BaggageSpanProcessor } from '@opentelemetry/baggage-span-processor' ;
4547
4648// Tests AwsOpenTelemetryConfigurator after running Environment Variable setup in register.ts
4749describe ( 'AwsOpenTelemetryConfiguratorTest' , ( ) => {
@@ -276,7 +278,10 @@ describe('AwsOpenTelemetryConfiguratorTest', () => {
276278
277279 it ( 'CustomizeSpanProcessorsTest' , ( ) => {
278280 delete process . env . OTEL_AWS_APPLICATION_SIGNALS_ENABLED ;
279- const spanProcessors : SpanProcessor [ ] = [ ] ;
281+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
282+
283+ // Test application signals only
284+ let spanProcessors : SpanProcessor [ ] = [ ] ;
280285 AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessors , Resource . empty ( ) ) ;
281286 expect ( spanProcessors . length ) . toEqual ( 0 ) ;
282287
@@ -310,6 +315,81 @@ describe('AwsOpenTelemetryConfiguratorTest', () => {
310315 spanProcessors . forEach ( spanProcessor => {
311316 spanProcessor . shutdown ( ) ;
312317 } ) ;
318+
319+ // Reset spanProcessors list for next set of tests
320+ spanProcessors = [ ] ;
321+
322+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
323+ process . env . OTEL_AWS_APPLICATION_SIGNALS_ENABLED = 'True' ;
324+ AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessors , Resource . empty ( ) ) ;
325+ expect ( spanProcessors . length ) . toEqual ( 3 ) ;
326+
327+ // Verify processors are added in the expected order
328+ expect ( spanProcessors [ 0 ] ) . toBeInstanceOf ( BaggageSpanProcessor ) ;
329+ expect ( spanProcessors [ 1 ] ) . toBeInstanceOf ( AttributePropagatingSpanProcessor ) ;
330+ expect ( spanProcessors [ 2 ] ) . toBeInstanceOf ( AwsSpanMetricsProcessor ) ;
331+
332+ // shut down exporters for test cleanup
333+ spanProcessors . forEach ( spanProcessor => {
334+ spanProcessor . shutdown ( ) ;
335+ } ) ;
336+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
337+ delete process . env . OTEL_AWS_APPLICATION_SIGNALS_ENABLED ;
338+ } ) ;
339+
340+ it ( 'CustomizeSpanProcessorsWithAgentObservabilityTest' , ( ) => {
341+ const spanProcessorsToTest : SpanProcessor [ ] = [ ] ;
342+
343+ // Test that BaggageSpanProcessor is not added when agent observability is disabled
344+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
345+ AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessorsToTest , Resource . empty ( ) ) ;
346+ expect ( spanProcessorsToTest ) . toEqual ( [ ] ) ;
347+
348+ // Test that BaggageSpanProcessor is added when agent observability is enabled
349+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
350+ AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessorsToTest , Resource . empty ( ) ) ;
351+ expect ( spanProcessorsToTest . length ) . toEqual ( 1 ) ;
352+
353+ // Verify the added processor is BaggageSpanProcessor
354+ const addedProcessor = spanProcessorsToTest [ 0 ] ;
355+ expect ( addedProcessor ) . toBeInstanceOf ( BaggageSpanProcessor ) ;
356+
357+ // Clean up
358+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
359+ } ) ;
360+
361+ it ( 'BaggageSpanProcessorSessionIdFilteringTest' , ( ) => {
362+ // Set up agent observability
363+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
364+
365+ // Create a SpanProcessor list for this test
366+ const spanProcessorsToTest : SpanProcessor [ ] = [ ] ;
367+
368+ // Add our span processors
369+ AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessorsToTest , Resource . empty ( ) ) ;
370+
371+ // Verify that the BaggageSpanProcessor was added
372+ const baggageProcessors = spanProcessorsToTest . filter (
373+ processor => processor . constructor . name === 'BaggageSpanProcessor'
374+ ) ;
375+ expect ( baggageProcessors . length ) . toBe ( 1 ) ;
376+
377+ // Verify the predicate function only accepts session.id
378+ const baggageProcessor = baggageProcessors [ 0 ] ;
379+ expect ( baggageProcessor ) . toBeInstanceOf ( BaggageSpanProcessor ) ;
380+ const predicate = ( baggageProcessor as BaggageSpanProcessor ) [ '_keyPredicate' ] . bind ( baggageProcessor ) ;
381+
382+ // Test the predicate function directly
383+ expect ( predicate ( 'session.id' ) ) . toBeTruthy ( ) ;
384+ expect ( predicate ( 'user.id' ) ) . toBeFalsy ( ) ;
385+ expect ( predicate ( 'request.id' ) ) . toBeFalsy ( ) ;
386+ expect ( predicate ( 'other.key' ) ) . toBeFalsy ( ) ;
387+ expect ( predicate ( '' ) ) . toBeFalsy ( ) ;
388+ expect ( predicate ( 'session' ) ) . toBeFalsy ( ) ;
389+ expect ( predicate ( 'id' ) ) . toBeFalsy ( ) ;
390+
391+ // Clean up
392+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
313393 } ) ;
314394
315395 it ( 'ApplicationSignalsExporterProviderTest' , ( ) => {
@@ -667,4 +747,75 @@ describe('AwsOpenTelemetryConfiguratorTest', () => {
667747 // Cleanup
668748 delete process . env . OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ;
669749 } ) ;
750+
751+ it ( 'ExportUnsampledSpanForAgentObservabilityTest' , ( ) => {
752+ const spanProcessorsToTest : SpanProcessor [ ] = [ ] ;
753+
754+ // Test with agent observability disabled
755+ AwsOpentelemetryConfigurator . exportUnsampledSpanForAgentObservability ( spanProcessorsToTest , Resource . empty ( ) ) ;
756+ expect ( spanProcessorsToTest ) . toEqual ( [ ] ) ;
757+
758+ // Test with agent observability enabled
759+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
760+ process . env . OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'https://xray.us-east-1.amazonaws.com/v1/traces' ;
761+
762+ AwsOpentelemetryConfigurator . exportUnsampledSpanForAgentObservability ( spanProcessorsToTest , Resource . empty ( ) ) ;
763+ expect ( spanProcessorsToTest . length ) . toEqual ( 1 ) ;
764+
765+ const processor = spanProcessorsToTest [ 0 ] ;
766+ expect ( processor ) . toBeInstanceOf ( AwsBatchUnsampledSpanProcessor ) ;
767+
768+ // Cleanup
769+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
770+ delete process . env . OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ;
771+ } ) ;
772+
773+ it ( 'ExportUnsampledSpanForAgentObservabilityUsesOtlpAwsSpanExporterTest' , ( ) => {
774+ const spanProcessorsToTest : SpanProcessor [ ] = [ ] ;
775+
776+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
777+ process . env . OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'https://xray.us-east-1.amazonaws.com/v1/traces' ;
778+
779+ AwsOpentelemetryConfigurator . exportUnsampledSpanForAgentObservability ( spanProcessorsToTest , Resource . empty ( ) ) ;
780+
781+ // Verify AwsBatchUnsampledSpanProcessor was created with the AWS exporter
782+ expect ( spanProcessorsToTest [ 0 ] ) . toBeInstanceOf ( AwsBatchUnsampledSpanProcessor ) ;
783+ const otlpAwsSpanExporter = ( spanProcessorsToTest [ 0 ] as AwsBatchUnsampledSpanProcessor ) [ '_exporter' ] ;
784+
785+ // Verify OTLPAwsSpanExporter was created with correct parameters
786+ expect ( otlpAwsSpanExporter ) . toBeInstanceOf ( OTLPAwsSpanExporter ) ;
787+ expect ( otlpAwsSpanExporter [ 'endpoint' ] ) . toEqual ( 'https://xray.us-east-1.amazonaws.com/v1/traces' ) ;
788+ expect ( otlpAwsSpanExporter [ 'loggerProvider' ] ) . toBeDefined ( ) ;
789+
790+ // Cleanup environment variables
791+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
792+ delete process . env . OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ;
793+ } ) ;
794+
795+ it ( 'CustomizeSpanProcessorsCallsExportUnsampledSpanTest' , ( ) => {
796+ const spanProcessorsToTest : SpanProcessor [ ] = [ ] ;
797+
798+ // Create spy for exportUnsampledSpanForAgentObservability
799+ const exportUnsampledSpanSpy = sinon . spy ( AwsOpentelemetryConfigurator , 'exportUnsampledSpanForAgentObservability' ) ;
800+
801+ try {
802+ // Test that function is NOT called when agent observability is disabled
803+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
804+ AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessorsToTest , Resource . empty ( ) ) ;
805+ expect ( exportUnsampledSpanSpy . called ) . toBeFalsy ( ) ;
806+
807+ // Test that function is called when agent observability is enabled
808+ exportUnsampledSpanSpy . resetHistory ( ) ;
809+ process . env . AGENT_OBSERVABILITY_ENABLED = 'true' ;
810+ AwsOpentelemetryConfigurator . customizeSpanProcessors ( spanProcessorsToTest , Resource . empty ( ) ) ;
811+ expect ( exportUnsampledSpanSpy . calledOnce ) . toBeTruthy ( ) ;
812+ expect ( exportUnsampledSpanSpy . calledWith ( spanProcessorsToTest , Resource . empty ( ) ) ) . toBeTruthy ( ) ;
813+ } finally {
814+ // Restore original implementation
815+ exportUnsampledSpanSpy . restore ( ) ;
816+
817+ // Cleanup
818+ delete process . env . AGENT_OBSERVABILITY_ENABLED ;
819+ }
820+ } ) ;
670821} ) ;
0 commit comments