From 875afc3b9a69971a5845cbbe6b978d04768bb58f Mon Sep 17 00:00:00 2001 From: Sergio Prada Date: Mon, 16 Nov 2020 12:04:32 -0500 Subject: [PATCH 1/5] extract trace from sqs source --- src/trace/context.spec.ts | 137 ++++++++++++++++++++++++++++++++++++++ src/trace/context.ts | 45 ++++++++++++- 2 files changed, 181 insertions(+), 1 deletion(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index e547851f..b753f5e9 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -16,6 +16,7 @@ import { readTraceContextFromXray, readTraceFromEvent, readStepFunctionContextFromEvent, + readTraceFromSQSEvent, } from "./context"; let sentSegment: any; @@ -193,6 +194,39 @@ describe("readTraceFromEvent", () => { source: Source.Event, }); }); + it("can read from sqs source", () => { + const result = readTraceFromEvent({ + Records: [ + { + body: "Hello world", + attributes: { + ApproximateReceiveCount: "1", + SentTimestamp: "1605544528092", + SenderId: "AROAYYB64AB3JHSRKO6XR:sqs-trace-dev-producer", + ApproximateFirstReceiveTimestamp: "1605544528094", + }, + messageAttributes: { + _datadog: { + stringValue: + '{"x-datadog-trace-id":"4555236104497098341","x-datadog-parent-id":"3369753143434738315","x-datadog-sampled":"1","x-datadog-sampling-priority":"1"}', + stringListValues: [], + binaryListValues: [], + dataType: "String", + }, + }, + eventSource: "aws:sqs", + eventSourceARN: "arn:aws:sqs:sa-east-1:601427279990:metal-queue", + awsRegion: "sa-east-1", + }, + ], + }); + expect(result).toEqual({ + parentID: "3369753143434738315", + sampleMode: SampleMode.AUTO_KEEP, + traceID: "4555236104497098341", + source: Source.Event, + }); + }); it("can read well formed headers with mixed casing", () => { const result = readTraceFromEvent({ headers: { @@ -249,6 +283,74 @@ describe("readTraceFromEvent", () => { }); }); +describe("readTraceFromSQSEvent", () => { + it("can read from sqs source", () => { + const result = readTraceFromSQSEvent({ + Records: [ + { + body: "Hello world", + attributes: { + ApproximateReceiveCount: "1", + SentTimestamp: "1605544528092", + SenderId: "AROAYYB64AB3JHSRKO6XR:sqs-trace-dev-producer", + ApproximateFirstReceiveTimestamp: "1605544528094", + }, + messageAttributes: { + _datadog: { + stringValue: + '{"x-datadog-trace-id":"4555236104497098341","x-datadog-parent-id":"3369753143434738315","x-datadog-sampled":"1","x-datadog-sampling-priority":"1"}', + stringListValues: [], + binaryListValues: [], + dataType: "String", + }, + }, + eventSource: "aws:sqs", + eventSourceARN: "arn:aws:sqs:sa-east-1:601427279990:metal-queue", + awsRegion: "sa-east-1", + }, + ], + }); + expect(result).toEqual({ + parentID: "3369753143434738315", + sampleMode: SampleMode.AUTO_KEEP, + traceID: "4555236104497098341", + source: Source.Event, + }); + }); + it("can handle badformed JSON", () => { + const result = readTraceFromSQSEvent({ + Records: [ + { + body: "Hello world", + attributes: { + ApproximateReceiveCount: "1", + SentTimestamp: "1605544528092", + SenderId: "AROAYYB64AB3JHSRKO6XR:sqs-trace-dev-producer", + ApproximateFirstReceiveTimestamp: "1605544528094", + }, + messageAttributes: { + _datadog: { + stringValue: + '{asdasdasd"x-datadog-trace-id":"4555236104497098341","x-datadog-parent-id":"3369753143434738315","x-datadog-sampled":"1","x-datadog-sampling-priority":"1"}', + stringListValues: [], + binaryListValues: [], + dataType: "String", + }, + }, + eventSource: "aws:sqs", + eventSourceARN: "arn:aws:sqs:sa-east-1:601427279990:metal-queue", + awsRegion: "sa-east-1", + }, + ], + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when event isn't object", () => { + const result = readTraceFromSQSEvent("some-value"); + expect(result).toBeUndefined(); + }); +}); + describe("readStepFunctionContextFromEvent", () => { const stepFunctionEvent = { dd: { @@ -401,6 +503,41 @@ describe("extractTraceContext", () => { source: Source.Event, }); }); + it("returns trace read from SQS metadata as second highest priority", () => { + process.env["_X_AMZN_TRACE_ID"] = "Root=1-5ce31dc2-2c779014b90ce44db5e03875;Parent=0b11cc4230d3e09e;Sampled=1"; + + const result = extractTraceContext({ + Records: [ + { + body: "Hello world", + attributes: { + ApproximateReceiveCount: "1", + SentTimestamp: "1605544528092", + SenderId: "AROAYYB64AB3JHSRKO6XR:sqs-trace-dev-producer", + ApproximateFirstReceiveTimestamp: "1605544528094", + }, + messageAttributes: { + _datadog: { + stringValue: + '{"x-datadog-trace-id":"4555236104497098341","x-datadog-parent-id":"3369753143434738315","x-datadog-sampled":"1","x-datadog-sampling-priority":"1"}', + stringListValues: [], + binaryListValues: [], + dataType: "String", + }, + }, + eventSource: "aws:sqs", + eventSourceARN: "arn:aws:sqs:sa-east-1:601427279990:metal-queue", + awsRegion: "sa-east-1", + }, + ], + }); + expect(result).toEqual({ + parentID: "3369753143434738315", + sampleMode: SampleMode.AUTO_KEEP, + traceID: "4555236104497098341", + source: Source.Event, + }); + }); it("returns trace read from env if no headers present", () => { process.env["_X_AMZN_TRACE_ID"] = "Root=1-5ce31dc2-2c779014b90ce44db5e03875;Parent=0b11cc4230d3e09e;Sampled=1"; diff --git a/src/trace/context.ts b/src/trace/context.ts index c73d6e0b..f39cf063 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -144,6 +144,49 @@ export function sendXraySubsegment(segment: string) { } } +export function readTraceFromSQSEvent(event: any): TraceContext | undefined { + if ( + event && + event.Records && + event.Records[0] && + event.Records[0].eventSource === "aws:sqs" && + event.Records[0].messageAttributes && + event.Records[0].messageAttributes._datadog && + event.Records[0].messageAttributes._datadog.stringValue + ) { + const traceHeaders = event.Records[0].messageAttributes._datadog.stringValue; + + try { + const traceData = JSON.parse(traceHeaders); + const traceID = traceData[traceIDHeader]; + if (typeof traceID !== "string") { + return; + } + const parentID = traceData[parentIDHeader]; + if (typeof parentID !== "string") { + return; + } + const sampledHeader = traceData[samplingPriorityHeader]; + if (typeof sampledHeader !== "string") { + return; + } + const sampleMode = parseInt(sampledHeader, 10); + + return { + parentID, + sampleMode, + source: Source.Event, + traceID, + }; + } catch (err) { + logError("Error parsing SQS message trace data", err); + return; + } + } + + return; +} + export function readTraceFromEvent(event: any): TraceContext | undefined { if (typeof event !== "object") { return; @@ -152,7 +195,7 @@ export function readTraceFromEvent(event: any): TraceContext | undefined { // e.g. When lambda is invoked synchronously, headers can be set to null by the caller if (!headers || typeof headers !== "object") { - return; + return readTraceFromSQSEvent(event); } const lowerCaseHeaders: { [key: string]: string } = {}; From b582f3dca8591eae4311663c52614196bb3c56e9 Mon Sep 17 00:00:00 2001 From: Sergio Prada Date: Mon, 16 Nov 2020 13:26:20 -0500 Subject: [PATCH 2/5] refactor+ int tests updates --- .../snapshots/logs/async-metrics_node12.log | 2 +- .../logs/async-metrics_node12_with_plugin.log | 2 +- .../logs/http-requests_node10_with_plugin.log | 6 +-- .../logs/http-requests_node12_with_plugin.log | 6 +-- .../snapshots/logs/sync-metrics_node12.log | 2 +- .../throw-error-traced_node12_with_plugin.log | 2 +- src/trace/context.spec.ts | 38 +++++++++++++++++-- src/trace/context.ts | 33 ++++++++-------- 8 files changed, 62 insertions(+), 29 deletions(-) diff --git a/integration_tests/snapshots/logs/async-metrics_node12.log b/integration_tests/snapshots/logs/async-metrics_node12.log index 6a2aecff..e6b3cad7 100644 --- a/integration_tests/snapshots/logs/async-metrics_node12.log +++ b/integration_tests/snapshots/logs/async-metrics_node12.log @@ -18,10 +18,10 @@ XRAY TraceId: XXXX SegmentId: XXXX Sampled: true START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-dev-async-metrics_node12","resource:integration-dev-async-metrics_node12","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} +XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["tagkey:tagvalue","eventsource:SQS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["tagkey:tagvalue","eventsource:SQS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["tagkey:tagvalue","eventsource:SQS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} -XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log b/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log index 1525ca0d..3d365463 100644 --- a/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log +++ b/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log @@ -11,8 +11,8 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-async-metrics_node12_with_plugin","resource:integration-plugin-dev-async-metrics_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["tagkey:tagvalue","eventsource:SNS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["tagkey:tagvalue","eventsource:SNS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} -XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SNS request {"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-async-metrics_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-async-metrics_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-async-metrics_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SNS request END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/integration_tests/snapshots/logs/http-requests_node10_with_plugin.log b/integration_tests/snapshots/logs/http-requests_node10_with_plugin.log index 05d9c64b..5f829def 100644 --- a/integration_tests/snapshots/logs/http-requests_node10_with_plugin.log +++ b/integration_tests/snapshots/logs/http-requests_node10_with_plugin.log @@ -2,7 +2,7 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-http-requests_node10_with_plugin","resource:integration-plugin-dev-http-requests_node10_with_plugin","cold_start:true","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs10.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["function:http-request","dd_lambda_layer:datadog-nodev10.XX.X"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Snapshot test http requests successfully made to URLs: https://ip-ranges.datadoghq.com,https://ip-ranges.datadoghq.eu -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node10_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","cold_start":"true","function_arn":"XXXX_node10_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node10_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":1,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"http://127.0.0.1:8124/lambda/hello","error.type":"Error","error.msg":"connect ECONNREFUSED 127.0.0.1:8124","error.stack":"Error: connect ECONNREFUSED 127.0.0.1:8124\n at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.com/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.eu/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node10_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","cold_start":"true","function_arn":"XXXX_node10_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node10_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms XRAY TraceId: XXXX SegmentId: XXXX Sampled: true @@ -11,7 +11,7 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-http-requests_node10_with_plugin","resource:integration-plugin-dev-http-requests_node10_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs10.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["function:http-request","dd_lambda_layer:datadog-nodev10.XX.X"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Snapshot test http requests successfully made to URLs: https://ip-ranges.datadoghq.com,https://ip-ranges.datadoghq.eu -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node10_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","cold_start":"false","function_arn":"XXXX_node10_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node10_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.com/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.eu/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node10_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","cold_start":"false","function_arn":"XXXX_node10_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node10_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true @@ -20,7 +20,7 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-http-requests_node10_with_plugin","resource:integration-plugin-dev-http-requests_node10_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs10.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["function:http-request","dd_lambda_layer:datadog-nodev10.XX.X"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Snapshot test http requests successfully made to URLs: https://ip-ranges.datadoghq.com,https://ip-ranges.datadoghq.eu -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node10_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","cold_start":"false","function_arn":"XXXX_node10_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node10_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.com/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.eu/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node10_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node10_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node10_with_plugin","cold_start":"false","function_arn":"XXXX_node10_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node10_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/integration_tests/snapshots/logs/http-requests_node12_with_plugin.log b/integration_tests/snapshots/logs/http-requests_node12_with_plugin.log index c27a8926..cf54659c 100644 --- a/integration_tests/snapshots/logs/http-requests_node12_with_plugin.log +++ b/integration_tests/snapshots/logs/http-requests_node12_with_plugin.log @@ -2,7 +2,7 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-http-requests_node12_with_plugin","resource:integration-plugin-dev-http-requests_node12_with_plugin","cold_start:true","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["function:http-request","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Snapshot test http requests successfully made to URLs: https://ip-ranges.datadoghq.com,https://ip-ranges.datadoghq.eu -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","cold_start":"true","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":1,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"http://127.0.0.1:8124/lambda/hello","error.type":"Error","error.msg":"connect ECONNREFUSED 127.0.0.1:8124","error.stack":"Error: connect ECONNREFUSED 127.0.0.1:8124\n at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)\n at TCPConnectWrap.callbackTrampoline (internal/async_hooks.js:120:14)"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.com/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.eu/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","cold_start":"true","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB Init Duration: XXXX ms XRAY TraceId: XXXX SegmentId: XXXX Sampled: true @@ -11,7 +11,7 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-http-requests_node12_with_plugin","resource:integration-plugin-dev-http-requests_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["function:http-request","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Snapshot test http requests successfully made to URLs: https://ip-ranges.datadoghq.com,https://ip-ranges.datadoghq.eu -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.com/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.eu/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true @@ -20,7 +20,7 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-http-requests_node12_with_plugin","resource:integration-plugin-dev-http-requests_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["function:http-request","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Snapshot test http requests successfully made to URLs: https://ip-ranges.datadoghq.com,https://ip-ranges.datadoghq.eu -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.com/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"http.request","resource":"GET","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","span.kind":"client","http.method":"GET","http.url":"https://ip-ranges.datadoghq.eu/","http.status_code":"200"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"integration-plugin-dev-http-requests_node12_with_plugin-http-client","type":"http"},{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-http-requests_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-http-requests_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-http-requests_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/integration_tests/snapshots/logs/sync-metrics_node12.log b/integration_tests/snapshots/logs/sync-metrics_node12.log index 2e82dd25..8fabd339 100644 --- a/integration_tests/snapshots/logs/sync-metrics_node12.log +++ b/integration_tests/snapshots/logs/sync-metrics_node12.log @@ -16,8 +16,8 @@ REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1 XRAY TraceId: XXXX SegmentId: XXXX Sampled: true START RequestId: XXXX Version: $LATEST -{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-dev-sync-metrics_node12","resource:integration-dev-sync-metrics_node12","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request +{"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-dev-sync-metrics_node12","resource:integration-dev-sync-metrics_node12","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["content-type:application/json","x-datadog-parent-id:XXXX","x-datadog-sampling-priority:2","x-datadog-trace-id:XXXX"] END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB diff --git a/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log b/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log index 9b17f51c..1774800f 100644 --- a/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log +++ b/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log @@ -17,10 +17,10 @@ REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1 XRAY TraceId: XXXX SegmentId: XXXX Sampled: true START RequestId: XXXX Version: $LATEST +XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX ERROR [dd.trace_id=XXXX dd.span_id=XXXX] Invoke Error {"errorType":"Error","errorMessage":"Hello","stack":["Error: Hello"," at handle (/var/task/throw-error-traced.js:4:11)"," at /var/task/node_modules/datadog-lambda-js/dist/utils/handler.js:150:25"," at Object. (/var/task/node_modules/datadog-lambda-js/dist/index.js:156:62)"," at step (/var/task/node_modules/datadog-lambda-js/dist/index.js:44:23)"," at Object.next (/var/task/node_modules/datadog-lambda-js/dist/index.js:25:53)"," at fulfilled (/var/task/node_modules/datadog-lambda-js/dist/index.js:16:58)"]} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-throw-error-traced_node12_with_plugin","resource:integration-plugin-dev-throw-error-traced_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.errors","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-throw-error-traced_node12_with_plugin","resource:integration-plugin-dev-throw-error-traced_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-throw-error-traced_node12_with_plugin","error":1,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-throw-error-traced_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-throw-error-traced_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray","error.type":"Error","error.msg":"Hello","error.stack":"Error: Hello\n at handle (/var/task/throw-error-traced.js:4:11)\n at /var/task/node_modules/datadog-lambda-js/dist/utils/handler.js:150:25\n at Object. (/var/task/node_modules/datadog-lambda-js/dist/index.js:156:62)\n at step (/var/task/node_modules/datadog-lambda-js/dist/index.js:44:23)\n at Object.next (/var/task/node_modules/datadog-lambda-js/dist/index.js:25:53)\n at fulfilled (/var/task/node_modules/datadog-lambda-js/dist/index.js:16:58)"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} -XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX ERROR [dd.trace_id=XXXX dd.span_id=XXXX] Invoke Error {"errorType":"Error","errorMessage":"Hello","stack":["Error: Hello"," at handle (/var/task/throw-error-traced.js:4:11)"," at /var/task/node_modules/datadog-lambda-js/dist/utils/handler.js:150:25"," at Object. (/var/task/node_modules/datadog-lambda-js/dist/index.js:156:62)"," at step (/var/task/node_modules/datadog-lambda-js/dist/index.js:44:23)"," at Object.next (/var/task/node_modules/datadog-lambda-js/dist/index.js:25:53)"," at fulfilled (/var/task/node_modules/datadog-lambda-js/dist/index.js:16:58)"]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index b753f5e9..4508714f 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -17,6 +17,7 @@ import { readTraceFromEvent, readStepFunctionContextFromEvent, readTraceFromSQSEvent, + readTraceFromHTTPEvent, } from "./context"; let sentSegment: any; @@ -283,6 +284,39 @@ describe("readTraceFromEvent", () => { }); }); +describe("readTraceFromHTTPEvent", () => { + it("can read well formed event with headers", () => { + const result = readTraceFromHTTPEvent({ + headers: { + "x-datadog-parent-id": "797643193680388254", + "x-datadog-sampling-priority": "2", + "x-datadog-trace-id": "4110911582297405557", + }, + }); + expect(result).toEqual({ + parentID: "797643193680388254", + sampleMode: SampleMode.USER_KEEP, + traceID: "4110911582297405557", + source: Source.Event, + }); + }); + it("can read well formed headers with mixed casing", () => { + const result = readTraceFromHTTPEvent({ + headers: { + "X-Datadog-Parent-Id": "797643193680388254", + "X-Datadog-Sampling-Priority": "2", + "X-Datadog-Trace-Id": "4110911582297405557", + }, + }); + expect(result).toEqual({ + parentID: "797643193680388254", + sampleMode: SampleMode.USER_KEEP, + traceID: "4110911582297405557", + source: Source.Event, + }); + }); +}); + describe("readTraceFromSQSEvent", () => { it("can read from sqs source", () => { const result = readTraceFromSQSEvent({ @@ -345,10 +379,6 @@ describe("readTraceFromSQSEvent", () => { }); expect(result).toBeUndefined(); }); - it("returns undefined when event isn't object", () => { - const result = readTraceFromSQSEvent("some-value"); - expect(result).toBeUndefined(); - }); }); describe("readStepFunctionContextFromEvent", () => { diff --git a/src/trace/context.ts b/src/trace/context.ts index f39cf063..808a2dc8 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -146,10 +146,6 @@ export function sendXraySubsegment(segment: string) { export function readTraceFromSQSEvent(event: any): TraceContext | undefined { if ( - event && - event.Records && - event.Records[0] && - event.Records[0].eventSource === "aws:sqs" && event.Records[0].messageAttributes && event.Records[0].messageAttributes._datadog && event.Records[0].messageAttributes._datadog.stringValue @@ -187,21 +183,12 @@ export function readTraceFromSQSEvent(event: any): TraceContext | undefined { return; } -export function readTraceFromEvent(event: any): TraceContext | undefined { - if (typeof event !== "object") { - return; - } +export function readTraceFromHTTPEvent(event: any): TraceContext | undefined { const headers = event.headers; - - // e.g. When lambda is invoked synchronously, headers can be set to null by the caller - if (!headers || typeof headers !== "object") { - return readTraceFromSQSEvent(event); - } - const lowerCaseHeaders: { [key: string]: string } = {}; for (const key of Object.keys(headers)) { - lowerCaseHeaders[key.toLocaleLowerCase()] = headers[key]; + lowerCaseHeaders[key.toLowerCase()] = headers[key]; } const traceID = lowerCaseHeaders[traceIDHeader]; @@ -226,6 +213,22 @@ export function readTraceFromEvent(event: any): TraceContext | undefined { }; } +export function readTraceFromEvent(event: any): TraceContext | undefined { + if (typeof event !== "object") { + return; + } + + if (event.headers && typeof event.headers === "object") { + return readTraceFromHTTPEvent(event); + } + + if (event.Records && event.Records[0] && event.Records[0].eventSource === "aws:sqs") { + return readTraceFromSQSEvent(event); + } + + return; +} + export function readTraceContextFromXray(): TraceContext | undefined { const header = process.env[xrayTraceEnvVar]; if (header === undefined) { From 515a1039cb8c1c970dc3112d97884f097e94fcf6 Mon Sep 17 00:00:00 2001 From: Sergio Prada Date: Mon, 16 Nov 2020 18:15:03 -0500 Subject: [PATCH 3/5] Update src/trace/context.spec.ts Co-authored-by: Darcy Rayner <50632605+DarcyRaynerDD@users.noreply.github.com> --- src/trace/context.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index 4508714f..0ca67e53 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -351,7 +351,7 @@ describe("readTraceFromSQSEvent", () => { source: Source.Event, }); }); - it("can handle badformed JSON", () => { + it("can handle malformed JSON", () => { const result = readTraceFromSQSEvent({ Records: [ { From f8f843bdec2a1234a5bb2cf2256cec5c3fa908e8 Mon Sep 17 00:00:00 2001 From: Sergio Prada Date: Tue, 17 Nov 2020 08:19:39 -0500 Subject: [PATCH 4/5] pr feedback --- .../snapshots/logs/async-metrics_node12.log | 2 +- .../logs/async-metrics_node12_with_plugin.log | 2 +- .../snapshots/logs/sync-metrics_node12.log | 2 +- .../logs/throw-error-traced_node12_with_plugin.log | 2 +- src/trace/context.ts | 11 ++++++++--- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/integration_tests/snapshots/logs/async-metrics_node12.log b/integration_tests/snapshots/logs/async-metrics_node12.log index e6b3cad7..6a2aecff 100644 --- a/integration_tests/snapshots/logs/async-metrics_node12.log +++ b/integration_tests/snapshots/logs/async-metrics_node12.log @@ -18,10 +18,10 @@ XRAY TraceId: XXXX SegmentId: XXXX Sampled: true START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-dev-async-metrics_node12","resource:integration-dev-async-metrics_node12","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} -XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["tagkey:tagvalue","eventsource:SQS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["tagkey:tagvalue","eventsource:SQS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["tagkey:tagvalue","eventsource:SQS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} +XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log b/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log index 3d365463..1525ca0d 100644 --- a/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log +++ b/integration_tests/snapshots/logs/async-metrics_node12_with_plugin.log @@ -11,8 +11,8 @@ START RequestId: XXXX Version: $LATEST {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-async-metrics_node12_with_plugin","resource:integration-plugin-dev-async-metrics_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"serverless.integration_test.records_processed","t":["tagkey:tagvalue","eventsource:SNS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} {"e":XXXX,"m":"serverless.integration_test.execution","t":["tagkey:tagvalue","eventsource:SNS","dd_lambda_layer:datadog-nodev12.XX.X"],"v":1} -{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-async-metrics_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-async-metrics_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-async-metrics_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SNS request +{"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-async-metrics_node12_with_plugin","error":0,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-async-metrics_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-async-metrics_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/integration_tests/snapshots/logs/sync-metrics_node12.log b/integration_tests/snapshots/logs/sync-metrics_node12.log index 8fabd339..2e82dd25 100644 --- a/integration_tests/snapshots/logs/sync-metrics_node12.log +++ b/integration_tests/snapshots/logs/sync-metrics_node12.log @@ -16,8 +16,8 @@ REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1 XRAY TraceId: XXXX SegmentId: XXXX Sampled: true START RequestId: XXXX Version: $LATEST -XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-dev-sync-metrics_node12","resource:integration-dev-sync-metrics_node12","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} +XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX INFO [dd.trace_id=XXXX dd.span_id=XXXX] Processed SQS request HTTP POST https://api.datadoghq.com/api/v1/distribution_points?api_key=XXXX Headers: ["content-type:application/json","x-datadog-parent-id:XXXX","x-datadog-sampling-priority:2","x-datadog-trace-id:XXXX"] END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB diff --git a/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log b/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log index 1774800f..9b17f51c 100644 --- a/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log +++ b/integration_tests/snapshots/logs/throw-error-traced_node12_with_plugin.log @@ -17,10 +17,10 @@ REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1 XRAY TraceId: XXXX SegmentId: XXXX Sampled: true START RequestId: XXXX Version: $LATEST -XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX ERROR [dd.trace_id=XXXX dd.span_id=XXXX] Invoke Error {"errorType":"Error","errorMessage":"Hello","stack":["Error: Hello"," at handle (/var/task/throw-error-traced.js:4:11)"," at /var/task/node_modules/datadog-lambda-js/dist/utils/handler.js:150:25"," at Object. (/var/task/node_modules/datadog-lambda-js/dist/index.js:156:62)"," at step (/var/task/node_modules/datadog-lambda-js/dist/index.js:44:23)"," at Object.next (/var/task/node_modules/datadog-lambda-js/dist/index.js:25:53)"," at fulfilled (/var/task/node_modules/datadog-lambda-js/dist/index.js:16:58)"]} {"e":XXXX,"m":"aws.lambda.enhanced.invocations","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-throw-error-traced_node12_with_plugin","resource:integration-plugin-dev-throw-error-traced_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"e":XXXX,"m":"aws.lambda.enhanced.errors","t":["region:us-east-1","account_id:XXXX","functionname:integration-plugin-dev-throw-error-traced_node12_with_plugin","resource:integration-plugin-dev-throw-error-traced_node12_with_plugin","cold_start:false","memorysize:1024","datadog_lambda:vX.X.X","runtime:nodejs12.x"],"v":1} {"traces":[[{"trace_id":"XXXX","span_id":"XXXX","parent_id":"XXXX","name":"aws.lambda","resource":"integration-plugin-dev-throw-error-traced_node12_with_plugin","error":1,"meta":{"_dd.origin":"lambda","service":"integration-plugin-dev-throw-error-traced_node12_with_plugin","cold_start":"false","function_arn":"XXXX_node12_with_plugin","function_version":"$LATEST","request_id":"XXXX","resource_names":"integration-plugin-dev-throw-error-traced_node12_with_plugin","datadog_lambda":"XXXX","dd_trace":"XXXX","_dd.parent_source":"xray","error.type":"Error","error.msg":"Hello","error.stack":"Error: Hello\n at handle (/var/task/throw-error-traced.js:4:11)\n at /var/task/node_modules/datadog-lambda-js/dist/utils/handler.js:150:25\n at Object. (/var/task/node_modules/datadog-lambda-js/dist/index.js:156:62)\n at step (/var/task/node_modules/datadog-lambda-js/dist/index.js:44:23)\n at Object.next (/var/task/node_modules/datadog-lambda-js/dist/index.js:25:53)\n at fulfilled (/var/task/node_modules/datadog-lambda-js/dist/index.js:16:58)"},"metrics":{"_sample_rate":1,"_sampling_priority_v1":2},"start":XXXX,"duration":XXXX,"service":"aws.lambda","type":"serverless"}]]} +XXXX-XX-XX XX:XX:XX.XXX XXXX-XXXX-XXXX-XXXX-XXXX ERROR [dd.trace_id=XXXX dd.span_id=XXXX] Invoke Error {"errorType":"Error","errorMessage":"Hello","stack":["Error: Hello"," at handle (/var/task/throw-error-traced.js:4:11)"," at /var/task/node_modules/datadog-lambda-js/dist/utils/handler.js:150:25"," at Object. (/var/task/node_modules/datadog-lambda-js/dist/index.js:156:62)"," at step (/var/task/node_modules/datadog-lambda-js/dist/index.js:44:23)"," at Object.next (/var/task/node_modules/datadog-lambda-js/dist/index.js:25:53)"," at fulfilled (/var/task/node_modules/datadog-lambda-js/dist/index.js:16:58)"]} END RequestId: XXXX REPORT RequestId: XXXX Duration: XXXX ms Billed Duration: XXXX ms Memory Size: 1024 MB Max Memory Used: XXXX MB XRAY TraceId: XXXX SegmentId: XXXX Sampled: true diff --git a/src/trace/context.ts b/src/trace/context.ts index 808a2dc8..99247823 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -1,6 +1,7 @@ import { BigNumber } from "bignumber.js"; import { randomBytes } from "crypto"; import { createSocket, Socket } from "dgram"; +import { SQSEvent } from "aws-lambda"; import { logDebug, logError } from "../utils"; import { @@ -38,6 +39,10 @@ export interface StepFunctionContext { "step_function.step_name": string; } +function isSQSEvent(event: any): event is SQSEvent { + return Array.isArray(event.Records) && event.Records.length > 0 && event.Records[0].eventSource === "aws:sqs"; +} + /** * Reads the trace context from either an incoming lambda event, or the current xray segment. * @param event An incoming lambda event. This must have incoming trace headers in order to be read. @@ -144,7 +149,7 @@ export function sendXraySubsegment(segment: string) { } } -export function readTraceFromSQSEvent(event: any): TraceContext | undefined { +export function readTraceFromSQSEvent(event: SQSEvent): TraceContext | undefined { if ( event.Records[0].messageAttributes && event.Records[0].messageAttributes._datadog && @@ -218,11 +223,11 @@ export function readTraceFromEvent(event: any): TraceContext | undefined { return; } - if (event.headers && typeof event.headers === "object") { + if (typeof event.headers === "object") { return readTraceFromHTTPEvent(event); } - if (event.Records && event.Records[0] && event.Records[0].eventSource === "aws:sqs") { + if (isSQSEvent(event)) { return readTraceFromSQSEvent(event); } From 0a9c6a0079d3ee6eba61e32146ac8a6033995fb2 Mon Sep 17 00:00:00 2001 From: Sergio Prada Date: Tue, 17 Nov 2020 09:00:06 -0500 Subject: [PATCH 5/5] fix types --- src/trace/context.spec.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index 0ca67e53..fcfcc386 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -1,3 +1,4 @@ +import { SQSEvent } from "aws-lambda"; import { LogLevel, setLogLevel } from "../utils"; import { SampleMode, @@ -319,7 +320,7 @@ describe("readTraceFromHTTPEvent", () => { describe("readTraceFromSQSEvent", () => { it("can read from sqs source", () => { - const result = readTraceFromSQSEvent({ + const result = readTraceFromSQSEvent(({ Records: [ { body: "Hello world", @@ -333,17 +334,20 @@ describe("readTraceFromSQSEvent", () => { _datadog: { stringValue: '{"x-datadog-trace-id":"4555236104497098341","x-datadog-parent-id":"3369753143434738315","x-datadog-sampled":"1","x-datadog-sampling-priority":"1"}', - stringListValues: [], - binaryListValues: [], + stringListValues: undefined, + binaryListValues: undefined, dataType: "String", }, }, eventSource: "aws:sqs", eventSourceARN: "arn:aws:sqs:sa-east-1:601427279990:metal-queue", awsRegion: "sa-east-1", + messageId: "foo", + md5OfBody: "x", + receiptHandle: "x", }, ], - }); + } as unknown) as SQSEvent); expect(result).toEqual({ parentID: "3369753143434738315", sampleMode: SampleMode.AUTO_KEEP, @@ -352,7 +356,7 @@ describe("readTraceFromSQSEvent", () => { }); }); it("can handle malformed JSON", () => { - const result = readTraceFromSQSEvent({ + const result = readTraceFromSQSEvent(({ Records: [ { body: "Hello world", @@ -366,17 +370,20 @@ describe("readTraceFromSQSEvent", () => { _datadog: { stringValue: '{asdasdasd"x-datadog-trace-id":"4555236104497098341","x-datadog-parent-id":"3369753143434738315","x-datadog-sampled":"1","x-datadog-sampling-priority":"1"}', - stringListValues: [], - binaryListValues: [], + stringListValues: undefined, + binaryListValues: undefined, dataType: "String", }, }, eventSource: "aws:sqs", eventSourceARN: "arn:aws:sqs:sa-east-1:601427279990:metal-queue", awsRegion: "sa-east-1", + messageId: "foo", + md5OfBody: "x", + receiptHandle: "x", }, ], - }); + } as unknown) as SQSEvent); expect(result).toBeUndefined(); }); });