From 58eaccbf183bb96e25de3e96604a76c3f296198f Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Thu, 3 Oct 2019 10:54:20 -0400 Subject: [PATCH 1/8] Extract step function context from trace --- src/trace/context.spec.ts | 99 +++++++++++++++++++++++++++++++++++++++ src/trace/context.ts | 55 +++++++++++++++++++++- 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index 9445345e..f9dfb67c 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -8,6 +8,8 @@ import { extractTraceContext, readTraceContextFromXray, readTraceFromEvent, + convertExecutionIDToAPMTraceID, + readTraceFromStepFunctionEvent, } from "./context"; let currentSegment: any; @@ -60,6 +62,29 @@ describe("convertToAPMTraceID", () => { }); }); +describe("convertExecutionIDToAPMTraceID", () => { + it("converts a valid execution id to a trace id", () => { + const executionID = "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492"; + const result = convertExecutionIDToAPMTraceID(executionID); + expect(result).toEqual("1603157358436861074"); + }); + it("returns undefined when execution id has too few segments", () => { + const executionID = "e4a2-4cb2-963f-8f1fa4aec492"; + const result = convertExecutionIDToAPMTraceID(executionID); + expect(result).toBeUndefined(); + }); + it("returns undefined when execution id is too short", () => { + const executionID = "fb7b1e15-e4a2-4cb2-963f-8f"; + const result = convertExecutionIDToAPMTraceID(executionID); + expect(result).toBeUndefined(); + }); + it("returns undefined when execution id has non-hexidecimal character", () => { + const executionID = "fb7b1e15-e4a2-4cb2-963f-8f1fa4ZZZZZZ"; + const result = convertExecutionIDToAPMTraceID(executionID); + expect(result).toBeUndefined(); + }); +}); + describe("convertToAPMParentID", () => { it("converts an xray parent ID to an APM parent ID", () => { const xrayParentID = "0b11cc4230d3e09e"; @@ -219,6 +244,56 @@ describe("readTraceFromEvent", () => { expect(result).toBeUndefined(); }); }); + +describe("readTraceFromStepFunctionEvent", () => { + it("reads a trace from an execution id", () => { + const result = readTraceFromStepFunctionEvent({ + datadogContext: { + Execution: { + Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + }, + }, + }); + expect(result).toEqual({ + parentID: "0", + sampleMode: SampleMode.USER_KEEP, + traceID: "1603157358436861074", + }); + }); + it("returns undefined when event isn't an object", () => { + const result = readTraceFromStepFunctionEvent("event"); + expect(result).toBeUndefined(); + }); + it("returns undefined when event is missing datadogContext property", () => { + const result = readTraceFromStepFunctionEvent({}); + expect(result).toBeUndefined(); + }); + it("returns undefined when datadogContext is missing Execution property", () => { + const result = readTraceFromStepFunctionEvent({ + datadogContext: {}, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when Execution is missing Name field", () => { + const result = readTraceFromStepFunctionEvent({ + datadogContext: { + Execution: {}, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when Name isn't a valid execution id", () => { + const result = readTraceFromStepFunctionEvent({ + datadogContext: { + Execution: { + Name: "12345", + }, + }, + }); + expect(result).toBeUndefined(); + }); +}); + describe("extractTraceContext", () => { it("returns trace read from header as highest priority", () => { currentSegment = { @@ -232,6 +307,11 @@ describe("extractTraceContext", () => { "x-datadog-sampling-priority": "2", "x-datadog-trace-id": "4110911582297405551", }, + datadogContext: { + Execution: { + Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + }, + }, }); expect(result).toEqual({ parentID: "797643193680388251", @@ -239,6 +319,25 @@ describe("extractTraceContext", () => { traceID: "4110911582297405551", }); }); + it("returns trace read from execution context", () => { + currentSegment = { + id: "0b11cc4230d3e09e", + trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875", + }; + const result = extractTraceContext({ + datadogContext: { + Execution: { + Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + }, + }, + }); + + expect(result).toEqual({ + parentID: "0", + sampleMode: SampleMode.USER_KEEP, + traceID: "1603157358436861074", + }); + }); it("returns trace read from env if no headers present", () => { currentSegment = { id: "0b11cc4230d3e09e", diff --git a/src/trace/context.ts b/src/trace/context.ts index cbc15ff1..ea2ee82f 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -29,7 +29,10 @@ export interface TraceContext { * @param event An incoming lambda event. This must have incoming trace headers in order to be read. */ export function extractTraceContext(event: any) { - const trace = readTraceFromEvent(event); + let trace = readTraceFromEvent(event); + if (trace === undefined) { + trace = readTraceFromStepFunctionEvent(event); + } if (trace !== undefined) { try { addTraceContextToXray(trace); @@ -106,6 +109,56 @@ export function readTraceContextFromXray() { return undefined; } +export function readTraceFromStepFunctionEvent(event: any): TraceContext | undefined { + if (typeof event !== "object") { + return; + } + const { datadogContext } = event; + if (typeof datadogContext !== "object") { + return; + } + const execution = datadogContext.Execution; + if (typeof execution !== "object") { + return; + } + const name = execution.Name; + if (typeof name !== "string") { + return; + } + const traceID = convertExecutionIDToAPMTraceID(name); + if (traceID === undefined) { + return; + } + return { + traceID, + parentID: "0", + sampleMode: SampleMode.USER_KEEP, + }; +} + +export function convertExecutionIDToAPMTraceID(executionId: string): string | undefined { + // fb7b1e15-e4a2-4cb2-863f-8f1fa4aec492 + const parts = executionId.split("-"); + if (parts.length < 5) { + return; + } + const lastParts = parts[3] + parts[4]; + if (lastParts.length !== 16) { + return; + } + + // We want to turn the last 63 bits into a decimal number in a string representation + // Unfortunately, all numbers in javascript are represented by float64 bit numbers, which + // means we can't parse 64 bit integers accurately. + const hex = new BigNumber(lastParts, 16); + if (hex.isNaN()) { + return; + } + // Toggle off the 64th bit + const last63Bits = hex.mod(new BigNumber("8000000000000000", 16)); + return last63Bits.toString(10); +} + export function convertTraceContext(traceHeader: XRayTraceHeader): TraceContext | undefined { const sampleMode = convertToSampleMode(traceHeader.sampled); const traceID = convertToAPMTraceID(traceHeader.traceID); From f1d3f0ab7bf3486e08a1ddb215ea0b05089b19bf Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Mon, 7 Oct 2019 10:23:15 -0400 Subject: [PATCH 2/8] Add metadata to step functions --- src/trace/context.spec.ts | 4 +- src/trace/context.ts | 107 ++++++++++++++++++++++++++--- src/trace/listener.ts | 12 +++- src/trace/trace-context-service.ts | 7 +- 4 files changed, 116 insertions(+), 14 deletions(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index f9dfb67c..23b2b776 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -255,7 +255,7 @@ describe("readTraceFromStepFunctionEvent", () => { }, }); expect(result).toEqual({ - parentID: "0", + parentID: "8897738568179535026", sampleMode: SampleMode.USER_KEEP, traceID: "1603157358436861074", }); @@ -333,7 +333,7 @@ describe("extractTraceContext", () => { }); expect(result).toEqual({ - parentID: "0", + parentID: "8897738568179535026", sampleMode: SampleMode.USER_KEEP, traceID: "1603157358436861074", }); diff --git a/src/trace/context.ts b/src/trace/context.ts index ea2ee82f..c8f86c3e 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -18,12 +18,28 @@ export interface XRayTraceHeader { sampled: number; } -export interface TraceContext { +export interface BaseTraceContext { traceID: string; parentID: string; sampleMode: SampleMode; + isStepFunction: boolean; } +export interface RegularTraceContext extends BaseTraceContext { + isStepFunction: false; +} +export interface StepFunctionTraceContext extends BaseTraceContext { + isStepFunction: true; + executionStartTime: Date; + retryCount: number; + stepName: string; + stateMachineArn: string; + stateMachineName: string; + executionID: string; +} + +export type TraceContext = RegularTraceContext | StepFunctionTraceContext; + /** * 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. @@ -91,6 +107,7 @@ export function readTraceFromEvent(event: any): TraceContext | undefined { parentID, sampleMode, traceID, + isStepFunction: false, }; } @@ -109,7 +126,7 @@ export function readTraceContextFromXray() { return undefined; } -export function readTraceFromStepFunctionEvent(event: any): TraceContext | undefined { +export function readTraceFromStepFunctionEvent(event: any): StepFunctionTraceContext | undefined { if (typeof event !== "object") { return; } @@ -121,28 +138,101 @@ export function readTraceFromStepFunctionEvent(event: any): TraceContext | undef if (typeof execution !== "object") { return; } - const name = execution.Name; - if (typeof name !== "string") { + const executionID = execution.Name; + if (typeof executionID !== "string") { return; } - const traceID = convertExecutionIDToAPMTraceID(name); + const traceID = convertExecutionIDToAPMTraceID(executionID); if (traceID === undefined) { return; } + const startTime = execution.StartTime; + if (typeof startTime !== "string") { + return; + } + const executionStartTime = new Date(startTime); + + const state = datadogContext.State; + if (typeof state !== "object") { + return; + } + const retryCount = state.RetryCount; + if (typeof retryCount !== "number") { + return; + } + const stepName = state.Name; + if (typeof stepName !== "string") { + return; + } + const stateMachine = datadogContext.StateMachine; + if (typeof stateMachine !== "object") { + return; + } + const stateMachineArn = stateMachine.Id; + if (typeof stateMachineArn !== "string") { + return; + } + const stateMachineName = stateMachine.Name; + if (typeof stateMachineName !== "string") { + return; + } + return { traceID, - parentID: "0", + parentID: traceID, sampleMode: SampleMode.USER_KEEP, + isStepFunction: true, + executionStartTime, + retryCount, + stepName, + stateMachineArn, + executionID, + stateMachineName, + }; +} + +export function logStepFunctionRootSpan(traceContext: StepFunctionTraceContext) { + const { stateMachineArn, stateMachineName, executionID } = traceContext; + const traceID = new BigNumber(traceContext.traceID, 10).toString(16); + const startDate = traceContext.executionStartTime.valueOf(); + const endDate = Date.now(); + + const duration = endDate - startDate; + const trace = { + traces: [ + [ + { + trace_id: traceID, + span_id: traceID, + parentID: "0", + name: `aws.step_function_execution`, + resource: stateMachineArn, + error: 0, + metrics: { + _sample_rate: 1, + _sampling_priority_v1: 2, + }, + meta: { + "aws.step_function.execution_id": traceContext.executionID, + }, + start: startDate * 1000000, + duration: duration * 1000000, + service: stateMachineName, + }, + ], + ], }; + + process.stdout.write(JSON.stringify(trace) + "\n"); } -export function convertExecutionIDToAPMTraceID(executionId: string): string | undefined { +export function convertExecutionIDToAPMTraceID(executionId: string, useLast16: boolean = true): string | undefined { // fb7b1e15-e4a2-4cb2-863f-8f1fa4aec492 const parts = executionId.split("-"); if (parts.length < 5) { return; } - const lastParts = parts[3] + parts[4]; + const lastParts = useLast16 ? parts[3] + parts[4] : parts[0] + parts[2] + parts[2]; if (lastParts.length !== 16) { return; } @@ -170,6 +260,7 @@ export function convertTraceContext(traceHeader: XRayTraceHeader): TraceContext parentID, sampleMode, traceID, + isStepFunction: false, }; } diff --git a/src/trace/listener.ts b/src/trace/listener.ts index c4ad1276..a1b45b27 100644 --- a/src/trace/listener.ts +++ b/src/trace/listener.ts @@ -1,7 +1,7 @@ import { Context } from "aws-lambda"; import Tracer, { SpanContext, SpanOptions, TraceOptions } from "dd-trace"; -import { extractTraceContext } from "./context"; +import { extractTraceContext, logStepFunctionRootSpan } from "./context"; import { patchHttp, unpatchHttp } from "./patch-http"; import { TraceContextService } from "./trace-context-service"; @@ -34,6 +34,11 @@ export class TraceListener { } public async onCompleteInvocation() { + const rootTraceContext = this.contextService.rootTraceContext; + if (rootTraceContext !== undefined && rootTraceContext.isStepFunction) { + logStepFunctionRootSpan(rootTraceContext); + } + if (this.config.autoPatchHTTP) { unpatchHttp(); } @@ -51,6 +56,11 @@ export class TraceListener { request_id: this.context.awsRequestId, resource_names: this.context.functionName, }; + const rootTraceContext = this.contextService.rootTraceContext; + if (rootTraceContext !== undefined && rootTraceContext.isStepFunction) { + options.tags["aws.step_function.retry_count"] = rootTraceContext.retryCount; + options.tags["aws.step_function.execution_id"] = rootTraceContext.executionID; + } } if (spanContext !== null) { diff --git a/src/trace/trace-context-service.ts b/src/trace/trace-context-service.ts index 8caa2991..6e98ea17 100644 --- a/src/trace/trace-context-service.ts +++ b/src/trace/trace-context-service.ts @@ -1,6 +1,6 @@ import { getSegment } from "aws-xray-sdk-core"; -import { logError } from "../utils"; +import { logError, logDebug } from "../utils"; import { parentIDHeader, samplingPriorityHeader, traceIDHeader } from "./constants"; import { convertToAPMParentID, TraceContext } from "./context"; @@ -24,15 +24,16 @@ export class TraceContextService { return; } const traceContext = { ...this.rootTraceContext }; - try { + /*try { const segment = getSegment(); const value = convertToAPMParentID(segment.id); if (value !== undefined) { + logDebug(`set trace context from xray with parent ${value} from segemt`); traceContext.parentID = value; } } catch (error) { logError("couldn't retrieve segment from xray", { innerError: error }); - } + }*/ return traceContext; } From 28261c7d35a6e061603278641648fc51c2fc823e Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Tue, 22 Oct 2019 15:30:03 -0400 Subject: [PATCH 3/8] Refactor to add execution id metadata to xray/datadog traces --- package.json | 3 +- src/trace/context.spec.ts | 204 ++++++++++++++++++++++++----------- src/trace/context.ts | 123 +++++---------------- src/trace/listener.ts | 18 ++-- src/trace/patch-http.spec.ts | 1 + 5 files changed, 177 insertions(+), 172 deletions(-) diff --git a/package.json b/package.json index a90e18d1..f9576c10 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,8 @@ }, "collectCoverage": true, "coverageReporters": [ - "lcovonly" + "lcovonly", + "text-summary" ], "testRegex": "(src\\/).*(\\.spec\\.ts)$", "testPathIgnorePatterns": [ diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index 23b2b776..e69c1382 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -1,5 +1,5 @@ import { LogLevel, setLogLevel } from "../utils"; -import { SampleMode } from "./constants"; +import { SampleMode, xraySubsegmentKey, xraySubsegmentNamespace } from "./constants"; import { convertToAPMParentID, convertToAPMTraceID, @@ -8,16 +8,19 @@ import { extractTraceContext, readTraceContextFromXray, readTraceFromEvent, - convertExecutionIDToAPMTraceID, - readTraceFromStepFunctionEvent, + readStepFunctionContextFromEvent, } from "./context"; let currentSegment: any; jest.mock("aws-xray-sdk-core", () => { return { - captureFunc: () => { - throw Error("Unimplemented"); + captureFunc: (subsegmentName: string, callback: (segment: any) => void) => { + if (currentSegment) { + callback(currentSegment); + } else { + throw Error("Unimplemented"); + } }, getSegment: () => { if (currentSegment === undefined) { @@ -62,29 +65,6 @@ describe("convertToAPMTraceID", () => { }); }); -describe("convertExecutionIDToAPMTraceID", () => { - it("converts a valid execution id to a trace id", () => { - const executionID = "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492"; - const result = convertExecutionIDToAPMTraceID(executionID); - expect(result).toEqual("1603157358436861074"); - }); - it("returns undefined when execution id has too few segments", () => { - const executionID = "e4a2-4cb2-963f-8f1fa4aec492"; - const result = convertExecutionIDToAPMTraceID(executionID); - expect(result).toBeUndefined(); - }); - it("returns undefined when execution id is too short", () => { - const executionID = "fb7b1e15-e4a2-4cb2-963f-8f"; - const result = convertExecutionIDToAPMTraceID(executionID); - expect(result).toBeUndefined(); - }); - it("returns undefined when execution id has non-hexidecimal character", () => { - const executionID = "fb7b1e15-e4a2-4cb2-963f-8f1fa4ZZZZZZ"; - const result = convertExecutionIDToAPMTraceID(executionID); - expect(result).toBeUndefined(); - }); -}); - describe("convertToAPMParentID", () => { it("converts an xray parent ID to an APM parent ID", () => { const xrayParentID = "0b11cc4230d3e09e"; @@ -245,48 +225,128 @@ describe("readTraceFromEvent", () => { }); }); -describe("readTraceFromStepFunctionEvent", () => { - it("reads a trace from an execution id", () => { - const result = readTraceFromStepFunctionEvent({ - datadogContext: { - Execution: { - Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", - }, +describe("readStepFunctionContextFromEvent", () => { + const stepFunctionEvent = { + datadogContext: { + Execution: { + Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + StartTime: "2019-09-30T20:28:24.236Z", }, - }); + State: { + Name: "step-one", + RetryCount: 2, + }, + StateMachine: { + Id: "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", + Name: "my-state-machine", + }, + }, + } as const; + it("reads a trace from an execution id", () => { + const result = readStepFunctionContextFromEvent(stepFunctionEvent); expect(result).toEqual({ - parentID: "8897738568179535026", - sampleMode: SampleMode.USER_KEEP, - traceID: "1603157358436861074", + "aws.step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + "aws.step_function.retry_count": 2, + "aws.step_function.state_machine_arn": + "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", + "aws.step_function.state_machine_name": "my-state-machine", }); }); it("returns undefined when event isn't an object", () => { - const result = readTraceFromStepFunctionEvent("event"); + const result = readStepFunctionContextFromEvent("event"); expect(result).toBeUndefined(); }); it("returns undefined when event is missing datadogContext property", () => { - const result = readTraceFromStepFunctionEvent({}); + const result = readStepFunctionContextFromEvent({}); expect(result).toBeUndefined(); }); it("returns undefined when datadogContext is missing Execution property", () => { - const result = readTraceFromStepFunctionEvent({ + const result = readStepFunctionContextFromEvent({ datadogContext: {}, }); expect(result).toBeUndefined(); }); it("returns undefined when Execution is missing Name field", () => { - const result = readTraceFromStepFunctionEvent({ + const result = readStepFunctionContextFromEvent({ datadogContext: { + ...stepFunctionEvent.datadogContext, Execution: {}, }, }); expect(result).toBeUndefined(); }); - it("returns undefined when Name isn't a valid execution id", () => { - const result = readTraceFromStepFunctionEvent({ + it("returns undefined when Name isn't a string", () => { + const result = readStepFunctionContextFromEvent({ datadogContext: { + ...stepFunctionEvent.datadogContext, Execution: { - Name: "12345", + Name: 12345, + }, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when State isn't defined", () => { + const result = readStepFunctionContextFromEvent({ + datadogContext: { + ...stepFunctionEvent.datadogContext, + State: undefined, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when try retry count isn't a number", () => { + const result = readStepFunctionContextFromEvent({ + datadogContext: { + ...stepFunctionEvent.datadogContext, + State: { + ...stepFunctionEvent.datadogContext.State, + RetryCount: "1", + }, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when try step name isn't a string", () => { + const result = readStepFunctionContextFromEvent({ + datadogContext: { + ...stepFunctionEvent.datadogContext, + State: { + ...stepFunctionEvent.datadogContext.State, + Name: 1, + }, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when StateMachine is undefined", () => { + const result = readStepFunctionContextFromEvent({ + datadogContext: { + ...stepFunctionEvent.datadogContext, + StateMachine: undefined, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when StateMachineId isn't a string", () => { + const result = readStepFunctionContextFromEvent({ + datadogContext: { + ...stepFunctionEvent.datadogContext, + StateMachine: { + ...stepFunctionEvent.datadogContext.StateMachine, + Id: 1, + }, + }, + }); + expect(result).toBeUndefined(); + }); + it("returns undefined when StateMachineName isn't a string", () => { + const result = readStepFunctionContextFromEvent({ + datadogContext: { + ...stepFunctionEvent.datadogContext, + StateMachine: { + ...stepFunctionEvent.datadogContext.StateMachine, + Name: 1, }, }, }); @@ -307,11 +367,6 @@ describe("extractTraceContext", () => { "x-datadog-sampling-priority": "2", "x-datadog-trace-id": "4110911582297405551", }, - datadogContext: { - Execution: { - Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", - }, - }, }); expect(result).toEqual({ parentID: "797643193680388251", @@ -319,23 +374,17 @@ describe("extractTraceContext", () => { traceID: "4110911582297405551", }); }); - it("returns trace read from execution context", () => { + it("returns trace read from env if no headers present", () => { currentSegment = { id: "0b11cc4230d3e09e", trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875", }; - const result = extractTraceContext({ - datadogContext: { - Execution: { - Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", - }, - }, - }); + const result = extractTraceContext({}); expect(result).toEqual({ - parentID: "8897738568179535026", + parentID: "797643193680388254", sampleMode: SampleMode.USER_KEEP, - traceID: "1603157358436861074", + traceID: "4110911582297405557", }); }); it("returns trace read from env if no headers present", () => { @@ -351,4 +400,37 @@ describe("extractTraceContext", () => { traceID: "4110911582297405557", }); }); + + it("adds step function metadata to xray", () => { + const stepFunctionEvent = { + datadogContext: { + Execution: { + Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + StartTime: "2019-09-30T20:28:24.236Z", + }, + State: { + Name: "step-one", + RetryCount: 2, + }, + StateMachine: { + Id: "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", + Name: "my-state-machine", + }, + }, + } as const; + const addMetadata = jest.fn(); + currentSegment = { addMetadata }; + extractTraceContext(stepFunctionEvent); + expect(addMetadata).toHaveBeenCalledWith( + xraySubsegmentKey, + { + "aws.step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + "aws.step_function.retry_count": 2, + "aws.step_function.state_machine_arn": + "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", + "aws.step_function.state_machine_name": "my-state-machine", + }, + xraySubsegmentNamespace, + ); + }); }); diff --git a/src/trace/context.ts b/src/trace/context.ts index c8f86c3e..a3a3dd42 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -18,27 +18,18 @@ export interface XRayTraceHeader { sampled: number; } -export interface BaseTraceContext { +export interface TraceContext { traceID: string; parentID: string; sampleMode: SampleMode; - isStepFunction: boolean; } -export interface RegularTraceContext extends BaseTraceContext { - isStepFunction: false; +export interface StepFunctionContext { + "aws.step_function.retry_count": number; + "aws.step_function.execution_id": string; + "aws.step_function.state_machine_name": string; + "aws.step_function.state_machine_arn": string; } -export interface StepFunctionTraceContext extends BaseTraceContext { - isStepFunction: true; - executionStartTime: Date; - retryCount: number; - stepName: string; - stateMachineArn: string; - stateMachineName: string; - executionID: string; -} - -export type TraceContext = RegularTraceContext | StepFunctionTraceContext; /** * Reads the trace context from either an incoming lambda event, or the current xray segment. @@ -46,8 +37,13 @@ export type TraceContext = RegularTraceContext | StepFunctionTraceContext; */ export function extractTraceContext(event: any) { let trace = readTraceFromEvent(event); - if (trace === undefined) { - trace = readTraceFromStepFunctionEvent(event); + let stepFuncContext = readStepFunctionContextFromEvent(event); + if (stepFuncContext) { + try { + addStepFunctionContextToXray(stepFuncContext); + } catch (error) { + logError("couldn't add step function metadata to xray", { innerError: error }); + } } if (trace !== undefined) { try { @@ -73,6 +69,12 @@ export function addTraceContextToXray(traceContext: TraceContext) { }); } +export function addStepFunctionContextToXray(context: StepFunctionContext) { + captureFunc(xraySubsegmentName, (segment) => { + segment.addMetadata(xraySubsegmentKey, context, xraySubsegmentNamespace); + }); +} + export function readTraceFromEvent(event: any): TraceContext | undefined { if (typeof event !== "object") { return; @@ -107,7 +109,6 @@ export function readTraceFromEvent(event: any): TraceContext | undefined { parentID, sampleMode, traceID, - isStepFunction: false, }; } @@ -126,7 +127,7 @@ export function readTraceContextFromXray() { return undefined; } -export function readTraceFromStepFunctionEvent(event: any): StepFunctionTraceContext | undefined { +export function readStepFunctionContextFromEvent(event: any): StepFunctionContext | undefined { if (typeof event !== "object") { return; } @@ -142,16 +143,6 @@ export function readTraceFromStepFunctionEvent(event: any): StepFunctionTraceCon if (typeof executionID !== "string") { return; } - const traceID = convertExecutionIDToAPMTraceID(executionID); - if (traceID === undefined) { - return; - } - const startTime = execution.StartTime; - if (typeof startTime !== "string") { - return; - } - const executionStartTime = new Date(startTime); - const state = datadogContext.State; if (typeof state !== "object") { return; @@ -176,79 +167,14 @@ export function readTraceFromStepFunctionEvent(event: any): StepFunctionTraceCon if (typeof stateMachineName !== "string") { return; } - return { - traceID, - parentID: traceID, - sampleMode: SampleMode.USER_KEEP, - isStepFunction: true, - executionStartTime, - retryCount, - stepName, - stateMachineArn, - executionID, - stateMachineName, + "aws.step_function.retry_count": retryCount, + "aws.step_function.execution_id": executionID, + "aws.step_function.state_machine_name": stateMachineName, + "aws.step_function.state_machine_arn": stateMachineArn, }; } -export function logStepFunctionRootSpan(traceContext: StepFunctionTraceContext) { - const { stateMachineArn, stateMachineName, executionID } = traceContext; - const traceID = new BigNumber(traceContext.traceID, 10).toString(16); - const startDate = traceContext.executionStartTime.valueOf(); - const endDate = Date.now(); - - const duration = endDate - startDate; - const trace = { - traces: [ - [ - { - trace_id: traceID, - span_id: traceID, - parentID: "0", - name: `aws.step_function_execution`, - resource: stateMachineArn, - error: 0, - metrics: { - _sample_rate: 1, - _sampling_priority_v1: 2, - }, - meta: { - "aws.step_function.execution_id": traceContext.executionID, - }, - start: startDate * 1000000, - duration: duration * 1000000, - service: stateMachineName, - }, - ], - ], - }; - - process.stdout.write(JSON.stringify(trace) + "\n"); -} - -export function convertExecutionIDToAPMTraceID(executionId: string, useLast16: boolean = true): string | undefined { - // fb7b1e15-e4a2-4cb2-863f-8f1fa4aec492 - const parts = executionId.split("-"); - if (parts.length < 5) { - return; - } - const lastParts = useLast16 ? parts[3] + parts[4] : parts[0] + parts[2] + parts[2]; - if (lastParts.length !== 16) { - return; - } - - // We want to turn the last 63 bits into a decimal number in a string representation - // Unfortunately, all numbers in javascript are represented by float64 bit numbers, which - // means we can't parse 64 bit integers accurately. - const hex = new BigNumber(lastParts, 16); - if (hex.isNaN()) { - return; - } - // Toggle off the 64th bit - const last63Bits = hex.mod(new BigNumber("8000000000000000", 16)); - return last63Bits.toString(10); -} - export function convertTraceContext(traceHeader: XRayTraceHeader): TraceContext | undefined { const sampleMode = convertToSampleMode(traceHeader.sampled); const traceID = convertToAPMTraceID(traceHeader.traceID); @@ -260,7 +186,6 @@ export function convertTraceContext(traceHeader: XRayTraceHeader): TraceContext parentID, sampleMode, traceID, - isStepFunction: false, }; } diff --git a/src/trace/listener.ts b/src/trace/listener.ts index a1b45b27..37a96e9d 100644 --- a/src/trace/listener.ts +++ b/src/trace/listener.ts @@ -1,7 +1,7 @@ import { Context } from "aws-lambda"; import Tracer, { SpanContext, SpanOptions, TraceOptions } from "dd-trace"; -import { extractTraceContext, logStepFunctionRootSpan } from "./context"; +import { extractTraceContext, StepFunctionContext } from "./context"; import { patchHttp, unpatchHttp } from "./patch-http"; import { TraceContextService } from "./trace-context-service"; @@ -16,6 +16,7 @@ export interface TraceConfig { export class TraceListener { private contextService = new TraceContextService(); private context?: Context; + private stepFunctionContext?: StepFunctionContext; private coldstart = true; public get currentTraceHeaders() { @@ -29,16 +30,10 @@ export class TraceListener { patchHttp(this.contextService); } this.context = context; - this.contextService.rootTraceContext = extractTraceContext(event); } public async onCompleteInvocation() { - const rootTraceContext = this.contextService.rootTraceContext; - if (rootTraceContext !== undefined && rootTraceContext.isStepFunction) { - logStepFunctionRootSpan(rootTraceContext); - } - if (this.config.autoPatchHTTP) { unpatchHttp(); } @@ -56,10 +51,11 @@ export class TraceListener { request_id: this.context.awsRequestId, resource_names: this.context.functionName, }; - const rootTraceContext = this.contextService.rootTraceContext; - if (rootTraceContext !== undefined && rootTraceContext.isStepFunction) { - options.tags["aws.step_function.retry_count"] = rootTraceContext.retryCount; - options.tags["aws.step_function.execution_id"] = rootTraceContext.executionID; + if (this.stepFunctionContext) { + options.tags = { + ...options.tags, + ...this.stepFunctionContext, + }; } } diff --git a/src/trace/patch-http.spec.ts b/src/trace/patch-http.spec.ts index 73c90d7c..9389bdbe 100644 --- a/src/trace/patch-http.spec.ts +++ b/src/trace/patch-http.spec.ts @@ -21,6 +21,7 @@ describe("patchHttp", () => { beforeEach(() => { contextService = new TraceContextService(); contextService.rootTraceContext = { + isStepFunction: false, parentID: "78910", sampleMode: SampleMode.USER_KEEP, traceID: "123456", From a342eea9e5b185c71ab0095e7eb969b997b4f7b4 Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Thu, 24 Oct 2019 12:04:16 -0400 Subject: [PATCH 4/8] Add baggage metadata to X-Ray --- src/trace/constants.ts | 1 + src/trace/context.spec.ts | 48 +++++++++++++++++++----------------- src/trace/context.ts | 18 ++++++++------ src/trace/listener.ts | 3 ++- src/trace/patch-http.spec.ts | 1 - 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/trace/constants.ts b/src/trace/constants.ts index aa6cff81..64be5d36 100644 --- a/src/trace/constants.ts +++ b/src/trace/constants.ts @@ -10,4 +10,5 @@ export const parentIDHeader = "x-datadog-parent-id"; export const samplingPriorityHeader = "x-datadog-sampling-priority"; export const xraySubsegmentName = "datadog-metadata"; export const xraySubsegmentKey = "trace"; +export const xrayBaggageSubsegmentKey = "baggage"; export const xraySubsegmentNamespace = "datadog"; diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index e69c1382..8469e4be 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -227,7 +227,7 @@ describe("readTraceFromEvent", () => { describe("readStepFunctionContextFromEvent", () => { const stepFunctionEvent = { - datadogContext: { + dd: { Execution: { Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", StartTime: "2019-09-30T20:28:24.236Z", @@ -250,6 +250,7 @@ describe("readStepFunctionContextFromEvent", () => { "aws.step_function.state_machine_arn": "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", "aws.step_function.state_machine_name": "my-state-machine", + "aws.step_function.step_name": "step-one", }); }); it("returns undefined when event isn't an object", () => { @@ -262,14 +263,14 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when datadogContext is missing Execution property", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: {}, + dd: {}, }); expect(result).toBeUndefined(); }); it("returns undefined when Execution is missing Name field", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, Execution: {}, }, }); @@ -277,8 +278,8 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when Name isn't a string", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, Execution: { Name: 12345, }, @@ -288,8 +289,8 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when State isn't defined", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, State: undefined, }, }); @@ -297,10 +298,10 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when try retry count isn't a number", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, State: { - ...stepFunctionEvent.datadogContext.State, + ...stepFunctionEvent.dd.State, RetryCount: "1", }, }, @@ -309,10 +310,10 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when try step name isn't a string", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, State: { - ...stepFunctionEvent.datadogContext.State, + ...stepFunctionEvent.dd.State, Name: 1, }, }, @@ -321,8 +322,8 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when StateMachine is undefined", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, StateMachine: undefined, }, }); @@ -330,10 +331,10 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when StateMachineId isn't a string", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, StateMachine: { - ...stepFunctionEvent.datadogContext.StateMachine, + ...stepFunctionEvent.dd.StateMachine, Id: 1, }, }, @@ -342,10 +343,10 @@ describe("readStepFunctionContextFromEvent", () => { }); it("returns undefined when StateMachineName isn't a string", () => { const result = readStepFunctionContextFromEvent({ - datadogContext: { - ...stepFunctionEvent.datadogContext, + dd: { + ...stepFunctionEvent.dd, StateMachine: { - ...stepFunctionEvent.datadogContext.StateMachine, + ...stepFunctionEvent.dd.StateMachine, Name: 1, }, }, @@ -403,7 +404,7 @@ describe("extractTraceContext", () => { it("adds step function metadata to xray", () => { const stepFunctionEvent = { - datadogContext: { + dd: { Execution: { Name: "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", StartTime: "2019-09-30T20:28:24.236Z", @@ -429,6 +430,7 @@ describe("extractTraceContext", () => { "aws.step_function.state_machine_arn": "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", "aws.step_function.state_machine_name": "my-state-machine", + "aws.step_function.step_name": "step-one", }, xraySubsegmentNamespace, ); diff --git a/src/trace/context.ts b/src/trace/context.ts index a3a3dd42..a9e40460 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -1,7 +1,7 @@ import { captureFunc, getSegment } from "aws-xray-sdk-core"; import { BigNumber } from "bignumber.js"; -import { logError } from "../utils"; +import { logError, logDebug } from "../utils"; import { parentIDHeader, SampleMode, @@ -10,6 +10,7 @@ import { xraySubsegmentKey, xraySubsegmentName, xraySubsegmentNamespace, + xrayBaggageSubsegmentKey, } from "./constants"; export interface XRayTraceHeader { @@ -29,6 +30,7 @@ export interface StepFunctionContext { "aws.step_function.execution_id": string; "aws.step_function.state_machine_name": string; "aws.step_function.state_machine_arn": string; + "aws.step_function.step_name": string; } /** @@ -71,7 +73,7 @@ export function addTraceContextToXray(traceContext: TraceContext) { export function addStepFunctionContextToXray(context: StepFunctionContext) { captureFunc(xraySubsegmentName, (segment) => { - segment.addMetadata(xraySubsegmentKey, context, xraySubsegmentNamespace); + segment.addMetadata(xrayBaggageSubsegmentKey, context, xraySubsegmentNamespace); }); } @@ -115,6 +117,7 @@ export function readTraceFromEvent(event: any): TraceContext | undefined { export function readTraceContextFromXray() { try { const segment = getSegment(); + logDebug(`Setting X-Ray parent trace to segment with ${segment.id} and trace ${segment.trace_id}`); const traceHeader = { parentID: segment.id, sampled: segment.notTraced ? 0 : 1, @@ -131,11 +134,11 @@ export function readStepFunctionContextFromEvent(event: any): StepFunctionContex if (typeof event !== "object") { return; } - const { datadogContext } = event; - if (typeof datadogContext !== "object") { + const { dd } = event; + if (typeof dd !== "object") { return; } - const execution = datadogContext.Execution; + const execution = dd.Execution; if (typeof execution !== "object") { return; } @@ -143,7 +146,7 @@ export function readStepFunctionContextFromEvent(event: any): StepFunctionContex if (typeof executionID !== "string") { return; } - const state = datadogContext.State; + const state = dd.State; if (typeof state !== "object") { return; } @@ -155,7 +158,7 @@ export function readStepFunctionContextFromEvent(event: any): StepFunctionContex if (typeof stepName !== "string") { return; } - const stateMachine = datadogContext.StateMachine; + const stateMachine = dd.StateMachine; if (typeof stateMachine !== "object") { return; } @@ -172,6 +175,7 @@ export function readStepFunctionContextFromEvent(event: any): StepFunctionContex "aws.step_function.execution_id": executionID, "aws.step_function.state_machine_name": stateMachineName, "aws.step_function.state_machine_arn": stateMachineArn, + "aws.step_function.step_name": stepName, }; } diff --git a/src/trace/listener.ts b/src/trace/listener.ts index 37a96e9d..e08baa56 100644 --- a/src/trace/listener.ts +++ b/src/trace/listener.ts @@ -1,7 +1,7 @@ import { Context } from "aws-lambda"; import Tracer, { SpanContext, SpanOptions, TraceOptions } from "dd-trace"; -import { extractTraceContext, StepFunctionContext } from "./context"; +import { extractTraceContext, StepFunctionContext, readStepFunctionContextFromEvent } from "./context"; import { patchHttp, unpatchHttp } from "./patch-http"; import { TraceContextService } from "./trace-context-service"; @@ -31,6 +31,7 @@ export class TraceListener { } this.context = context; this.contextService.rootTraceContext = extractTraceContext(event); + this.stepFunctionContext = readStepFunctionContextFromEvent(event); } public async onCompleteInvocation() { diff --git a/src/trace/patch-http.spec.ts b/src/trace/patch-http.spec.ts index 9389bdbe..73c90d7c 100644 --- a/src/trace/patch-http.spec.ts +++ b/src/trace/patch-http.spec.ts @@ -21,7 +21,6 @@ describe("patchHttp", () => { beforeEach(() => { contextService = new TraceContextService(); contextService.rootTraceContext = { - isStepFunction: false, parentID: "78910", sampleMode: SampleMode.USER_KEEP, traceID: "123456", From b033ff4dfc268c519f1af00c6ac092cb865420cd Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Thu, 24 Oct 2019 12:10:42 -0400 Subject: [PATCH 5/8] Fix linter errors --- src/trace/context.ts | 12 ++++++------ src/trace/listener.ts | 2 +- src/trace/trace-context-service.ts | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/trace/context.ts b/src/trace/context.ts index a9e40460..b7d9ff74 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -1,16 +1,16 @@ import { captureFunc, getSegment } from "aws-xray-sdk-core"; import { BigNumber } from "bignumber.js"; -import { logError, logDebug } from "../utils"; +import { logDebug, logError } from "../utils"; import { parentIDHeader, SampleMode, samplingPriorityHeader, traceIDHeader, + xrayBaggageSubsegmentKey, xraySubsegmentKey, xraySubsegmentName, xraySubsegmentNamespace, - xrayBaggageSubsegmentKey, } from "./constants"; export interface XRayTraceHeader { @@ -38,8 +38,8 @@ export interface StepFunctionContext { * @param event An incoming lambda event. This must have incoming trace headers in order to be read. */ export function extractTraceContext(event: any) { - let trace = readTraceFromEvent(event); - let stepFuncContext = readStepFunctionContextFromEvent(event); + const trace = readTraceFromEvent(event); + const stepFuncContext = readStepFunctionContextFromEvent(event); if (stepFuncContext) { try { addStepFunctionContextToXray(stepFuncContext); @@ -171,10 +171,10 @@ export function readStepFunctionContextFromEvent(event: any): StepFunctionContex return; } return { - "aws.step_function.retry_count": retryCount, "aws.step_function.execution_id": executionID, - "aws.step_function.state_machine_name": stateMachineName, + "aws.step_function.retry_count": retryCount, "aws.step_function.state_machine_arn": stateMachineArn, + "aws.step_function.state_machine_name": stateMachineName, "aws.step_function.step_name": stepName, }; } diff --git a/src/trace/listener.ts b/src/trace/listener.ts index e08baa56..bf052162 100644 --- a/src/trace/listener.ts +++ b/src/trace/listener.ts @@ -1,7 +1,7 @@ import { Context } from "aws-lambda"; import Tracer, { SpanContext, SpanOptions, TraceOptions } from "dd-trace"; -import { extractTraceContext, StepFunctionContext, readStepFunctionContextFromEvent } from "./context"; +import { extractTraceContext, readStepFunctionContextFromEvent, StepFunctionContext } from "./context"; import { patchHttp, unpatchHttp } from "./patch-http"; import { TraceContextService } from "./trace-context-service"; diff --git a/src/trace/trace-context-service.ts b/src/trace/trace-context-service.ts index 6e98ea17..a0fe4904 100644 --- a/src/trace/trace-context-service.ts +++ b/src/trace/trace-context-service.ts @@ -1,6 +1,6 @@ import { getSegment } from "aws-xray-sdk-core"; -import { logError, logDebug } from "../utils"; +import { logDebug, logError } from "../utils"; import { parentIDHeader, samplingPriorityHeader, traceIDHeader } from "./constants"; import { convertToAPMParentID, TraceContext } from "./context"; @@ -24,16 +24,16 @@ export class TraceContextService { return; } const traceContext = { ...this.rootTraceContext }; - /*try { + try { const segment = getSegment(); const value = convertToAPMParentID(segment.id); if (value !== undefined) { - logDebug(`set trace context from xray with parent ${value} from segemt`); + logDebug(`set trace context from xray with parent ${value} from segment`); traceContext.parentID = value; } } catch (error) { logError("couldn't retrieve segment from xray", { innerError: error }); - }*/ + } return traceContext; } From 2c8f3f8a67f4d1485a8e63bf5bb9972821a65319 Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Thu, 24 Oct 2019 12:13:54 -0400 Subject: [PATCH 6/8] Fix broken test --- src/trace/context.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index 8469e4be..1fb15f0f 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -1,5 +1,5 @@ import { LogLevel, setLogLevel } from "../utils"; -import { SampleMode, xraySubsegmentKey, xraySubsegmentNamespace } from "./constants"; +import { SampleMode, xrayBaggageSubsegmentKey, xraySubsegmentNamespace } from "./constants"; import { convertToAPMParentID, convertToAPMTraceID, @@ -423,7 +423,7 @@ describe("extractTraceContext", () => { currentSegment = { addMetadata }; extractTraceContext(stepFunctionEvent); expect(addMetadata).toHaveBeenCalledWith( - xraySubsegmentKey, + xrayBaggageSubsegmentKey, { "aws.step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", "aws.step_function.retry_count": 2, From 56ef9da4c8f2886aefcc1f0c86cfb7fe1edb9dcc Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Thu, 24 Oct 2019 15:44:06 -0400 Subject: [PATCH 7/8] Update constant --- src/trace/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trace/constants.ts b/src/trace/constants.ts index 64be5d36..4278d339 100644 --- a/src/trace/constants.ts +++ b/src/trace/constants.ts @@ -10,5 +10,5 @@ export const parentIDHeader = "x-datadog-parent-id"; export const samplingPriorityHeader = "x-datadog-sampling-priority"; export const xraySubsegmentName = "datadog-metadata"; export const xraySubsegmentKey = "trace"; -export const xrayBaggageSubsegmentKey = "baggage"; +export const xrayBaggageSubsegmentKey = "root_span_metadata"; export const xraySubsegmentNamespace = "datadog"; From c62b5bd0700cf61e7fe3db62a6e7856f501e576c Mon Sep 17 00:00:00 2001 From: DarcyRaynerDD Date: Fri, 25 Oct 2019 14:26:13 -0400 Subject: [PATCH 8/8] Change step function namespace --- src/trace/context.spec.ts | 20 ++++++++++---------- src/trace/context.ts | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/trace/context.spec.ts b/src/trace/context.spec.ts index 1fb15f0f..6d26fc5c 100644 --- a/src/trace/context.spec.ts +++ b/src/trace/context.spec.ts @@ -245,12 +245,12 @@ describe("readStepFunctionContextFromEvent", () => { it("reads a trace from an execution id", () => { const result = readStepFunctionContextFromEvent(stepFunctionEvent); expect(result).toEqual({ - "aws.step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", - "aws.step_function.retry_count": 2, - "aws.step_function.state_machine_arn": + "step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + "step_function.retry_count": 2, + "step_function.state_machine_arn": "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", - "aws.step_function.state_machine_name": "my-state-machine", - "aws.step_function.step_name": "step-one", + "step_function.state_machine_name": "my-state-machine", + "step_function.step_name": "step-one", }); }); it("returns undefined when event isn't an object", () => { @@ -425,12 +425,12 @@ describe("extractTraceContext", () => { expect(addMetadata).toHaveBeenCalledWith( xrayBaggageSubsegmentKey, { - "aws.step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", - "aws.step_function.retry_count": 2, - "aws.step_function.state_machine_arn": + "step_function.execution_id": "fb7b1e15-e4a2-4cb2-963f-8f1fa4aec492", + "step_function.retry_count": 2, + "step_function.state_machine_arn": "arn:aws:states:us-east-1:601427279990:stateMachine:HelloStepOneStepFunctionsStateMachine-z4T0mJveJ7pJ", - "aws.step_function.state_machine_name": "my-state-machine", - "aws.step_function.step_name": "step-one", + "step_function.state_machine_name": "my-state-machine", + "step_function.step_name": "step-one", }, xraySubsegmentNamespace, ); diff --git a/src/trace/context.ts b/src/trace/context.ts index b7d9ff74..6ad14eb0 100644 --- a/src/trace/context.ts +++ b/src/trace/context.ts @@ -26,11 +26,11 @@ export interface TraceContext { } export interface StepFunctionContext { - "aws.step_function.retry_count": number; - "aws.step_function.execution_id": string; - "aws.step_function.state_machine_name": string; - "aws.step_function.state_machine_arn": string; - "aws.step_function.step_name": string; + "step_function.retry_count": number; + "step_function.execution_id": string; + "step_function.state_machine_name": string; + "step_function.state_machine_arn": string; + "step_function.step_name": string; } /** @@ -171,11 +171,11 @@ export function readStepFunctionContextFromEvent(event: any): StepFunctionContex return; } return { - "aws.step_function.execution_id": executionID, - "aws.step_function.retry_count": retryCount, - "aws.step_function.state_machine_arn": stateMachineArn, - "aws.step_function.state_machine_name": stateMachineName, - "aws.step_function.step_name": stepName, + "step_function.execution_id": executionID, + "step_function.retry_count": retryCount, + "step_function.state_machine_arn": stateMachineArn, + "step_function.state_machine_name": stateMachineName, + "step_function.step_name": stepName, }; }