Skip to content

Commit 61b7890

Browse files
Merge pull request #46 from DataDog/darcy.rayner/use-xray-env-var
Darcy.rayner/use xray env var
2 parents 884334a + 0fd8f63 commit 61b7890

File tree

4 files changed

+85
-64
lines changed

4 files changed

+85
-64
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "datadog-lambda-js",
3-
"version": "0.12.0",
3+
"version": "0.13.0",
44
"description": "Lambda client library that supports hybrid tracing in node js",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/trace/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export const xraySubsegmentName = "datadog-metadata";
1616
export const xraySubsegmentKey = "trace";
1717
export const xrayBaggageSubsegmentKey = "root_span_metadata";
1818
export const xraySubsegmentNamespace = "datadog";
19+
export const xrayTraceEnvVar = "_X_AMZN_TRACE_ID";

src/trace/context.spec.ts

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@ jest.mock("aws-xray-sdk-core", () => {
2222
throw Error("Unimplemented");
2323
}
2424
},
25-
getSegment: () => {
26-
if (currentSegment === undefined) {
27-
throw Error("Empty");
28-
}
29-
return currentSegment;
30-
},
3125
};
3226
});
3327

@@ -127,38 +121,34 @@ describe("convertTraceContext", () => {
127121
});
128122

129123
describe("readTraceContextFromXray", () => {
130-
it("will parse a trace context from the xray", () => {
131-
currentSegment = {
132-
id: "0b11cc4230d3e09e",
133-
trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875",
134-
};
135-
136-
const traceContext = readTraceContextFromXray();
137-
expect(traceContext).toEqual({
138-
parentID: "797643193680388254",
139-
sampleMode: SampleMode.USER_KEEP,
140-
traceID: "4110911582297405557",
141-
source: Source.Xray,
142-
});
143-
});
144-
it("will ignore a trace context from the xray, when sampling is turned off", () => {
145-
currentSegment = {
146-
id: "0b11cc4230d3e09e",
147-
notTraced: true,
148-
trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875",
149-
};
150-
151-
const traceContext = readTraceContextFromXray();
152-
expect(traceContext).toEqual({
153-
parentID: "797643193680388254",
154-
sampleMode: SampleMode.USER_REJECT,
155-
traceID: "4110911582297405557",
156-
source: Source.Xray,
124+
afterEach(() => {
125+
process.env["_X_AMZN_TRACE_ID"] = undefined;
126+
});
127+
it("returns a trace context from a valid env var", () => {
128+
process.env["_X_AMZN_TRACE_ID"] = "Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1";
129+
const context = readTraceContextFromXray();
130+
expect(context).toEqual({
131+
parentID: "10713633173203262661",
132+
sampleMode: 2,
133+
source: "xray",
134+
traceID: "3995693151288333088",
157135
});
158136
});
159-
it("returns undefined when trace header isn't in environment", () => {
160-
const traceContext = readTraceContextFromXray();
161-
expect(traceContext).toBeUndefined();
137+
it("returns undefined when given an invalid env var", () => {
138+
const badCases = [
139+
"Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5",
140+
"Root=1-5e272390-8c398be037738dc042009320",
141+
"1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1",
142+
"Root=1-5e272390-8c398be037738dc042009320;94ae789b969f1cc5;Sampled=1",
143+
"Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;1",
144+
"Root=a;Parent=94ae789b969f1cc5;Sampled=1",
145+
"Root=1-5e272390-8c398be037738dc042009320;Parent=b;Sampled=1",
146+
undefined,
147+
];
148+
for (const badCase of badCases) {
149+
process.env["_X_AMZN_TRACE_ID"] = badCase;
150+
expect(readTraceContextFromXray()).toBeUndefined();
151+
}
162152
});
163153
});
164154

@@ -361,11 +351,11 @@ describe("readStepFunctionContextFromEvent", () => {
361351
});
362352

363353
describe("extractTraceContext", () => {
354+
afterEach(() => {
355+
process.env["_X_AMZN_TRACE_ID"] = undefined;
356+
});
364357
it("returns trace read from header as highest priority", () => {
365-
currentSegment = {
366-
parent_id: "0b11cc4230d3e09e",
367-
trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875",
368-
};
358+
process.env["_X_AMZN_TRACE_ID"] = "Root=1-5ce31dc2-2c779014b90ce44db5e03875;Parent=0b11cc4230d3e09e;Sampled=1";
369359

370360
const result = extractTraceContext({
371361
headers: {
@@ -382,10 +372,7 @@ describe("extractTraceContext", () => {
382372
});
383373
});
384374
it("returns trace read from env if no headers present", () => {
385-
currentSegment = {
386-
id: "0b11cc4230d3e09e",
387-
trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875",
388-
};
375+
process.env["_X_AMZN_TRACE_ID"] = "Root=1-5ce31dc2-2c779014b90ce44db5e03875;Parent=0b11cc4230d3e09e;Sampled=1";
389376

390377
const result = extractTraceContext({});
391378
expect(result).toEqual({
@@ -396,10 +383,7 @@ describe("extractTraceContext", () => {
396383
});
397384
});
398385
it("returns trace read from env if no headers present", () => {
399-
currentSegment = {
400-
id: "0b11cc4230d3e09e",
401-
trace_id: "1-5ce31dc2-2c779014b90ce44db5e03875",
402-
};
386+
process.env["_X_AMZN_TRACE_ID"] = "Root=1-5ce31dc2-2c779014b90ce44db5e03875;Parent=0b11cc4230d3e09e;Sampled=1";
403387

404388
const result = extractTraceContext({});
405389
expect(result).toEqual({

src/trace/context.ts

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { captureFunc, getSegment } from "aws-xray-sdk-core";
1+
import { captureFunc } from "aws-xray-sdk-core";
22
import { BigNumber } from "bignumber.js";
33

44
import { logDebug, logError } from "../utils";
@@ -12,6 +12,7 @@ import {
1212
xraySubsegmentKey,
1313
xraySubsegmentName,
1414
xraySubsegmentNamespace,
15+
xrayTraceEnvVar,
1516
} from "./constants";
1617

1718
export interface XRayTraceHeader {
@@ -117,20 +118,55 @@ export function readTraceFromEvent(event: any): TraceContext | undefined {
117118
};
118119
}
119120

120-
export function readTraceContextFromXray() {
121-
try {
122-
const segment = getSegment();
123-
logDebug(`Setting X-Ray parent trace to segment with ${segment.id} and trace ${segment.trace_id}`);
124-
const traceHeader = {
125-
parentID: segment.id,
126-
sampled: segment.notTraced ? 0 : 1,
127-
traceID: segment.trace_id,
128-
};
129-
return convertTraceContext(traceHeader);
130-
} catch (error) {
131-
logError("couldn't read xray trace header", { innerError: error });
132-
}
133-
return undefined;
121+
export function readTraceContextFromXray(): TraceContext | undefined {
122+
const header = process.env[xrayTraceEnvVar];
123+
if (header === undefined) {
124+
logError("couldn't read xray trace header from env");
125+
return;
126+
}
127+
const context = parseTraceContextHeader(header);
128+
if (context === undefined) {
129+
logError("couldn't read xray trace context from env, variable had invalid format");
130+
} else {
131+
logDebug("read trace context from environment", context);
132+
}
133+
return context;
134+
}
135+
136+
export function parseTraceContextHeader(header: string): TraceContext | undefined {
137+
// Root=1-5e272390-8c398be037738dc042009320;Parent=94ae789b969f1cc5;Sampled=1
138+
logDebug(`Reading trace context from env var ${header}`);
139+
const [root, parent, sampled] = header.split(";");
140+
if (parent === undefined || sampled === undefined) {
141+
return;
142+
}
143+
const [, rawTraceID] = root.split("=");
144+
if (rawTraceID === undefined) {
145+
return;
146+
}
147+
const traceID = convertToAPMTraceID(rawTraceID);
148+
if (traceID === undefined) {
149+
return;
150+
}
151+
const [, rawParentID] = parent.split("=");
152+
if (rawParentID === undefined) {
153+
return;
154+
}
155+
const parentID = convertToAPMParentID(rawParentID);
156+
if (parentID === undefined) {
157+
return;
158+
}
159+
const [, rawSampled] = sampled.split("=");
160+
if (rawSampled === undefined) {
161+
return;
162+
}
163+
const sampleMode = convertToSampleMode(parseInt(rawSampled, 10));
164+
return {
165+
parentID,
166+
sampleMode,
167+
source: Source.Xray,
168+
traceID,
169+
};
134170
}
135171

136172
export function readStepFunctionContextFromEvent(event: any): StepFunctionContext | undefined {

0 commit comments

Comments
 (0)