@@ -10,65 +10,88 @@ export class SNSSQSEventTraceExtractor implements EventTraceExtractor {
1010 constructor ( private tracerWrapper : TracerWrapper , private config : TraceConfig ) { }
1111
1212 extract ( event : SQSEvent ) : SpanContextWrapper | null {
13- logDebug ( "SNS-SQS Extractor Being Used" ) ;
14-
15- let context : SpanContextWrapper | null = null ;
16- for ( const record of event ?. Records || [ ] ) {
17- try {
18- // If we already have a context and dsm is not enabled, we can break out of the loop early
19- if ( ! this . config . dataStreamsEnabled && context ) {
20- break ;
21- }
22-
23- let headers = null ;
24- // Try to extract trace context from SNS wrapped in SQS
25- const body = record . body ;
26- if ( body ) {
27- const parsedBody = JSON . parse ( body ) ;
28- const snsMessageAttribute = parsedBody ?. MessageAttributes ?. _datadog ;
29- if ( snsMessageAttribute ?. Value ) {
30- if ( snsMessageAttribute . Type === "String" ) {
31- headers = JSON . parse ( snsMessageAttribute . Value ) ;
32- } else {
33- // Try decoding base64 values
34- const decodedValue = Buffer . from ( snsMessageAttribute . Value , "base64" ) . toString ( "ascii" ) ;
35- headers = JSON . parse ( decodedValue ) ;
13+ // Set DSM consume checkpoints if enabled
14+ if ( this . config . dataStreamsEnabled ) {
15+ for ( const record of event ?. Records || [ ] ) {
16+ try {
17+ let headers = null ;
18+ // Try to extract trace context from SNS wrapped in SQS
19+ const body = record . body ;
20+ if ( body ) {
21+ const parsedBody = JSON . parse ( body ) ;
22+ const snsMessageAttribute = parsedBody ?. MessageAttributes ?. _datadog ;
23+ if ( snsMessageAttribute ?. Value ) {
24+ if ( snsMessageAttribute . Type === "String" ) {
25+ headers = JSON . parse ( snsMessageAttribute . Value ) ;
26+ } else {
27+ // Try decoding base64 values
28+ const decodedValue = Buffer . from ( snsMessageAttribute . Value , "base64" ) . toString ( "ascii" ) ;
29+ headers = JSON . parse ( decodedValue ) ;
30+ }
3631 }
3732 }
38- }
3933
40- // Check SQS message attributes as a fallback
41- if ( ! headers ) {
42- const sqsMessageAttribute = record . messageAttributes ?. _datadog ;
43- if ( sqsMessageAttribute ?. stringValue ) {
44- headers = JSON . parse ( sqsMessageAttribute . stringValue ) ;
34+ // Check SQS message attributes as a fallback
35+ if ( ! headers ) {
36+ const sqsMessageAttribute = record . messageAttributes ?. _datadog ;
37+ if ( sqsMessageAttribute ?. stringValue ) {
38+ headers = JSON . parse ( sqsMessageAttribute . stringValue ) ;
39+ }
4540 }
46- }
4741
48- // Set a checkpoint for the record, even if we don't have headers
49- this . tracerWrapper . setConsumeCheckpoint ( headers , "sqs" , record . eventSourceARN ) ;
42+ // Set a checkpoint for the record, even if we don't have headers
43+ this . tracerWrapper . setConsumeCheckpoint ( headers , "sqs" , record . eventSourceARN ) ;
44+ } catch ( error ) {
45+ handleExtractionError ( error , "SQS DSM checkpoint" ) ;
46+ }
47+ }
48+ }
5049
51- // if we already have a context, no need to extract again
52- if ( context ) continue ;
50+ logDebug ( "SNS-SQS Extractor Being Used" ) ;
51+ try {
52+ // Try to extract trace context from SNS wrapped in SQS
53+ const body = event ?. Records ?. [ 0 ] ?. body ;
54+ if ( body ) {
55+ const parsedBody = JSON . parse ( body ) ;
56+ const snsMessageAttribute = parsedBody ?. MessageAttributes ?. _datadog ;
57+ if ( snsMessageAttribute ?. Value ) {
58+ let headers ;
59+ if ( snsMessageAttribute . Type === "String" ) {
60+ headers = JSON . parse ( snsMessageAttribute . Value ) ;
61+ } else {
62+ // Try decoding base64 values
63+ const decodedValue = Buffer . from ( snsMessageAttribute . Value , "base64" ) . toString ( "ascii" ) ;
64+ headers = JSON . parse ( decodedValue ) ;
65+ }
5366
54- // Try to extract trace context from headers
55- if ( headers ) {
56- context = extractTraceContext ( headers , this . tracerWrapper ) ;
57- } else {
67+ const traceContext = extractTraceContext ( headers , this . tracerWrapper ) ;
68+ if ( traceContext ) {
69+ return traceContext ;
70+ }
5871 logDebug ( "Failed to extract trace context from SNS-SQS event" ) ;
72+ }
73+ }
5974
60- // Else try to extract trace context from attributes.AWSTraceHeader
61- // (Upstream Java apps can pass down Datadog trace context in the attributes.AWSTraceHeader in SQS case)
62- const awsTraceHeader = record . attributes ?. AWSTraceHeader ;
63- if ( awsTraceHeader !== undefined ) {
64- context = extractFromAWSTraceHeader ( awsTraceHeader , "SNS-SQS" ) ;
65- }
75+ // Check SQS message attributes as a fallback
76+ const sqsMessageAttribute = event ?. Records ?. [ 0 ] ?. messageAttributes ?. _datadog ;
77+ if ( sqsMessageAttribute ?. stringValue ) {
78+ const headers = JSON . parse ( sqsMessageAttribute . stringValue ) ;
79+ const traceContext = extractTraceContext ( headers , this . tracerWrapper ) ;
80+ if ( traceContext ) {
81+ return traceContext ;
6682 }
67- } catch ( error ) {
68- handleExtractionError ( error , "SQS" ) ;
6983 }
84+
85+ // Else try to extract trace context from attributes.AWSTraceHeader
86+ // (Upstream Java apps can pass down Datadog trace context in the attributes.AWSTraceHeader in SQS case)
87+ const awsTraceHeader = event ?. Records ?. [ 0 ] ?. attributes ?. AWSTraceHeader ;
88+ if ( awsTraceHeader !== undefined ) {
89+ return extractFromAWSTraceHeader ( awsTraceHeader , "SNS-SQS" ) ;
90+ }
91+ } catch ( error ) {
92+ handleExtractionError ( error , "SQS" ) ;
7093 }
7194
72- return context ;
95+ return null ;
7396 }
7497}
0 commit comments