Skip to content

Commit 194bbd3

Browse files
authored
feat(tracer): add isTraceSampled method (#1435)
1 parent 27ca202 commit 194bbd3

File tree

5 files changed

+139
-3
lines changed

5 files changed

+139
-3
lines changed

Diff for: packages/commons/src/config/EnvironmentVariablesService.ts

+37-3
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,23 @@ class EnvironmentVariablesService extends ConfigService {
5353
* @returns {string}
5454
*/
5555
public getXrayTraceId(): string | undefined {
56-
const xRayTraceId = this.get(this.xRayTraceIdVariable);
56+
const xRayTraceData = this.getXrayTraceData();
5757

58-
if (xRayTraceId === '') return undefined;
58+
return xRayTraceData?.Root;
59+
}
5960

60-
return xRayTraceId.split(';')[0].replace('Root=', '');
61+
/**
62+
* It returns true if the Sampled flag is set in the _X_AMZN_TRACE_ID environment variable.
63+
*
64+
* The AWS X-Ray Trace data available in the environment variable has this format:
65+
* `Root=1-5759e988-bd862e3fe1be46a994272793;Parent=557abcec3ee5a047;Sampled=1`,
66+
*
67+
* @returns {boolean}
68+
*/
69+
public getXrayTraceSampled(): boolean {
70+
const xRayTraceData = this.getXrayTraceData();
71+
72+
return xRayTraceData?.Sampled === '1';
6173
}
6274

6375
/**
@@ -72,6 +84,28 @@ class EnvironmentVariablesService extends ConfigService {
7284
return truthyValues.includes(value.toLowerCase());
7385
}
7486

87+
/**
88+
* It parses the key/value data present in the _X_AMZN_TRACE_ID environment variable
89+
* and returns it as an object when available.
90+
*/
91+
private getXrayTraceData(): Record<string, string> | undefined {
92+
const xRayTraceEnv = this.get(this.xRayTraceIdVariable);
93+
94+
if (xRayTraceEnv === '') return undefined;
95+
96+
if (!xRayTraceEnv.includes('=')) return { Root: xRayTraceEnv };
97+
98+
const xRayTraceData: Record<string, string> = {};
99+
100+
xRayTraceEnv.split(';').forEach((field) => {
101+
102+
const [ key, value ] = field.split('=');
103+
104+
xRayTraceData[key] = value;
105+
});
106+
107+
return xRayTraceData;
108+
}
75109
}
76110

77111
export {

Diff for: packages/commons/tests/unit/config/EnvironmentVariablesService.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,48 @@ describe('Class: EnvironmentVariablesService', () => {
110110

111111
});
112112

113+
describe('Method: getXrayTraceSampled', () => {
114+
115+
test('It returns true if the Sampled flag is set in the _X_AMZN_TRACE_ID environment variable', () => {
116+
117+
// Prepare
118+
process.env._X_AMZN_TRACE_ID = 'Root=1-5759e988-bd862e3fe1be46a994272793;Parent=557abcec3ee5a047;Sampled=1';
119+
const service = new EnvironmentVariablesService();
120+
121+
// Act
122+
const value = service.getXrayTraceSampled();
123+
124+
// Assess
125+
expect(value).toEqual(true);
126+
});
127+
128+
test('It returns false if the Sampled flag is not set in the _X_AMZN_TRACE_ID environment variable', () => {
129+
130+
// Prepare
131+
process.env._X_AMZN_TRACE_ID = 'Root=1-5759e988-bd862e3fe1be46a994272793;Parent=557abcec3ee5a047';
132+
const service = new EnvironmentVariablesService();
133+
134+
// Act
135+
const value = service.getXrayTraceSampled();
136+
137+
// Assess
138+
expect(value).toEqual(false);
139+
});
140+
141+
it('It returns false when no _X_AMZN_TRACE_ID environment variable is present', () => {
142+
143+
// Prepare
144+
delete process.env._X_AMZN_TRACE_ID;
145+
const service = new EnvironmentVariablesService();
146+
147+
// Act
148+
const value = service.getXrayTraceSampled();
149+
150+
// Assess
151+
expect(value).toEqual(false);
152+
});
153+
});
154+
113155
describe('Method: isValueTrue', () => {
114156

115157
const valuesToTest: Array<Array<string | boolean>> = [

Diff for: packages/tracer/src/Tracer.ts

+17
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ class Tracer extends Utility implements TracerInterface {
508508
* @returns string - The root X-Ray trace id.
509509
*/
510510
public getRootXrayTraceId(): string | undefined {
511+
if (!this.isTracingEnabled()) return undefined;
512+
511513
return this.envVarsService.getXrayTraceId();
512514
}
513515

@@ -547,6 +549,21 @@ class Tracer extends Utility implements TracerInterface {
547549
return segment;
548550
}
549551

552+
/**
553+
* Get the current value of the AWS X-Ray Sampled flag.
554+
*
555+
* Utility method that returns the current AWS X-Ray Sampled flag.
556+
*
557+
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-traces
558+
*
559+
* @returns boolean - `true` if the trace is sampled, `false` if tracing is disabled or the trace is not sampled.
560+
*/
561+
public isTraceSampled(): boolean {
562+
if (!this.isTracingEnabled()) return false;
563+
564+
return this.envVarsService.getXrayTraceSampled();
565+
}
566+
550567
/**
551568
* Get the current value of the `tracingEnabled` property.
552569
*

Diff for: packages/tracer/src/TracerInterface.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface TracerInterface {
1313
captureMethod(options?: CaptureMethodOptions): MethodDecorator
1414
getSegment(): Segment | Subsegment | undefined
1515
getRootXrayTraceId(): string | undefined
16+
isTraceSampled(): boolean
1617
isTracingEnabled(): boolean
1718
putAnnotation: (key: string, value: string | number | boolean) => void
1819
putMetadata: (key: string, value: unknown, namespace?: string | undefined) => void

Diff for: packages/tracer/tests/unit/Tracer.test.ts

+42
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,48 @@ describe('Class: Tracer', () => {
277277

278278
});
279279

280+
test('when called and Tracer is disabled, it returns undefined', () => {
281+
282+
// Prepare
283+
const tracer: Tracer = new Tracer({ enabled: false });
284+
285+
// Act
286+
const xRayTraceId = tracer.getRootXrayTraceId();
287+
288+
// Assess
289+
expect(xRayTraceId).toBe(undefined);
290+
});
291+
292+
});
293+
294+
describe('Method: isTraceSampled', () => {
295+
296+
test('when called, it returns true if the Sampled flag is set', () => {
297+
298+
// Prepare
299+
const tracer: Tracer = new Tracer();
300+
301+
// Act
302+
const xRayTraceSampled = tracer.isTraceSampled();
303+
304+
// Assess
305+
expect(xRayTraceSampled).toBe(false);
306+
307+
});
308+
309+
test('when called and Trace is disabled, it returns false', () => {
310+
311+
// Prepare
312+
const tracer: Tracer = new Tracer({ enabled: false });
313+
314+
// Act
315+
const xRayTraceSampled = tracer.isTraceSampled();
316+
317+
// Assess
318+
expect(xRayTraceSampled).toBe(false);
319+
320+
});
321+
280322
});
281323

282324
describe('Method: getSegment', () => {

0 commit comments

Comments
 (0)