Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 2ee9c92

Browse files
author
philicious
authored
Fix traceid validator (#879)
* Fix comments in jaeger propagation validator * Add support for 64Bit and 128Bit traceIds Fix inject validators Fix extract formatter for leading zero bugs
1 parent 8864dcf commit 2ee9c92

File tree

3 files changed

+142
-10
lines changed

3 files changed

+142
-10
lines changed

packages/opencensus-propagation-jaeger/src/jaeger-format.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ import {
2222
} from '@opencensus/core';
2323
import * as crypto from 'crypto';
2424
import * as uuid from 'uuid';
25-
import { isValidSpanId, isValidTraceId } from './validators';
25+
import {
26+
formatTraceId,
27+
formatSpanId,
28+
isValidSpanId,
29+
isValidTraceId,
30+
} from './validators';
2631

2732
// TRACER_STATE_HEADER_NAME is the header key used for a span's serialized
2833
// context.
@@ -57,8 +62,8 @@ export class JaegerFormat implements Propagation {
5762
const tracerStateHeaderParts = tracerStateHeader.split(':');
5863
if (tracerStateHeaderParts.length !== 4) return null;
5964

60-
const traceId = tracerStateHeaderParts[0];
61-
const spanId = tracerStateHeaderParts[1];
65+
const traceId = formatTraceId(tracerStateHeaderParts[0]);
66+
const spanId = formatSpanId(tracerStateHeaderParts[1]);
6267
const jflags = Number(
6368
'0x' +
6469
(isNaN(Number(tracerStateHeaderParts[3]))

packages/opencensus-propagation-jaeger/src/validators.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,25 @@ const compose = (...fns: ValidationFn[]): ValidationFn => {
5454
};
5555

5656
/**
57-
* Determines if the given traceId is valid based on section 2.2.2.1 of the
58-
* Trace Context spec.
57+
* Compose a set of validation functions into a single validation call.
58+
*/
59+
const orCompose = (...fns: ValidationFn[]): ValidationFn => {
60+
return (value: string) => {
61+
return fns.reduce((isValid, fn) => isValid || fn(value), false);
62+
};
63+
};
64+
65+
/**
66+
* Determines if the given traceId is valid based on https://www.jaegertracing.io/docs/1.21/client-libraries/#value
5967
*/
6068
export const isValidTraceId = compose(
6169
isHex,
6270
isNotAllZeros,
63-
isLength(32)
71+
orCompose(isLength(32), isLength(16))
6472
);
6573

6674
/**
67-
* Determines if the given spanId is valid based on section 2.2.2.2 of the Trace
68-
* Context spec.
75+
* Determines if the given spanId is valid based on https://www.jaegertracing.io/docs/1.21/client-libraries/#value
6976
*/
7077
export const isValidSpanId = compose(
7178
isHex,
@@ -74,10 +81,26 @@ export const isValidSpanId = compose(
7481
);
7582

7683
/**
77-
* Determines if the given option is valid based on section 2.2.3 of the Trace
78-
* Context spec.
84+
* Determines if the given option is valid based on https://www.jaegertracing.io/docs/1.21/client-libraries/#value
7985
*/
8086
export const isValidOption = compose(
8187
isHex,
8288
isLength(2)
8389
);
90+
91+
/**
92+
* Formats a traceId to 64Bit or 128Bit Hex and add leading zeroes
93+
*/
94+
export const formatTraceId = (id: string) => {
95+
if (id.length > 16) {
96+
return ('0000000000000000000000000000000' + id).substr(-32);
97+
}
98+
return ('000000000000000' + id).substr(-16);
99+
};
100+
101+
/**
102+
* Formats a spanId to 64Bit and add leading zeroes
103+
*/
104+
export const formatSpanId = (id: string) => {
105+
return ('000000000000000' + id).substr(-16);
106+
};

packages/opencensus-propagation-jaeger/test/test-jaeger-format.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,66 @@ describe('JaegerPropagation', () => {
6262
);
6363
assert.deepStrictEqual(jaegerFormat.extract(getter), spanContext);
6464
});
65+
66+
it('should format traceId for 64Bit Hex id without leading zeros', () => {
67+
const spanContext = jaegerFormat.generate();
68+
spanContext.traceId = '70c2f20bd65603bd';
69+
const getter = helperGetter(
70+
`${spanContext.traceId}:${spanContext.spanId}::${spanContext.options}`
71+
);
72+
assert.deepStrictEqual(jaegerFormat.extract(getter), spanContext);
73+
});
74+
75+
it('should format traceId for 64Bit Hex id with leading zeros when needed', () => {
76+
const spanContext = jaegerFormat.generate();
77+
spanContext.traceId = 'c2f20bd65603bd';
78+
const compareSpanContext = { ...spanContext };
79+
compareSpanContext.traceId = '00c2f20bd65603bd';
80+
const getter = helperGetter(
81+
`${spanContext.traceId}:${spanContext.spanId}::${spanContext.options}`
82+
);
83+
assert.deepStrictEqual(jaegerFormat.extract(getter), compareSpanContext);
84+
});
85+
86+
it('should format traceId for 128Bit Hex id without leading zeros', () => {
87+
const spanContext = jaegerFormat.generate();
88+
spanContext.traceId = '929985345ae64c35acddd590f13ffc82';
89+
const getter = helperGetter(
90+
`${spanContext.traceId}:${spanContext.spanId}::${spanContext.options}`
91+
);
92+
assert.deepStrictEqual(jaegerFormat.extract(getter), spanContext);
93+
});
94+
95+
it('should format traceId for 128Bit Hex id with leading zeros when needed', () => {
96+
const spanContext = jaegerFormat.generate();
97+
spanContext.traceId = '9985345ae64c35acddd590f13ffc82';
98+
const compareSpanContext = { ...spanContext };
99+
compareSpanContext.traceId = '009985345ae64c35acddd590f13ffc82';
100+
const getter = helperGetter(
101+
`${spanContext.traceId}:${spanContext.spanId}::${spanContext.options}`
102+
);
103+
assert.deepStrictEqual(jaegerFormat.extract(getter), compareSpanContext);
104+
});
105+
});
106+
107+
it('should format spanId without leading zeros', () => {
108+
const spanContext = jaegerFormat.generate();
109+
spanContext.spanId = '70c2f20bd65603bd';
110+
const getter = helperGetter(
111+
`${spanContext.traceId}:${spanContext.spanId}::${spanContext.options}`
112+
);
113+
assert.deepStrictEqual(jaegerFormat.extract(getter), spanContext);
114+
});
115+
116+
it('should format spanId with leading zeros when needed', () => {
117+
const spanContext = jaegerFormat.generate();
118+
spanContext.spanId = 'c2f20bd65603bd';
119+
const compareSpanContext = { ...spanContext };
120+
compareSpanContext.spanId = '00c2f20bd65603bd';
121+
const getter = helperGetter(
122+
`${spanContext.traceId}:${spanContext.spanId}::${spanContext.options}`
123+
);
124+
assert.deepStrictEqual(jaegerFormat.extract(getter), compareSpanContext);
65125
});
66126

67127
describe('inject', () => {
@@ -104,6 +164,50 @@ describe('JaegerPropagation', () => {
104164
jaegerFormat.inject(setter, emptySpanContext);
105165
assert.deepStrictEqual(jaegerFormat.extract(getter), null);
106166
});
167+
168+
it('should inject spancontext with 64Bit traceID', () => {
169+
const spanContext = {
170+
traceId: '70c2f20bd65603bd',
171+
spanId: '5ba4ceca5d0edd4c',
172+
options: SAMPLED_VALUE,
173+
};
174+
const headers: { [key: string]: string | string[] | undefined } = {};
175+
const setter: HeaderSetter = {
176+
setHeader(name: string, value: string) {
177+
headers[name] = value;
178+
},
179+
};
180+
const getter: HeaderGetter = {
181+
getHeader(name: string) {
182+
return headers[name];
183+
},
184+
};
185+
186+
jaegerFormat.inject(setter, spanContext);
187+
assert.deepStrictEqual(jaegerFormat.extract(getter), spanContext);
188+
});
189+
190+
it('should inject spancontext with 128Bit traceID', () => {
191+
const spanContext = {
192+
traceId: '929985345ae64c35acddd590f13ffc82',
193+
spanId: '5ba4ceca5d0edd4c',
194+
options: SAMPLED_VALUE,
195+
};
196+
const headers: { [key: string]: string | string[] | undefined } = {};
197+
const setter: HeaderSetter = {
198+
setHeader(name: string, value: string) {
199+
headers[name] = value;
200+
},
201+
};
202+
const getter: HeaderGetter = {
203+
getHeader(name: string) {
204+
return headers[name];
205+
},
206+
};
207+
208+
jaegerFormat.inject(setter, spanContext);
209+
assert.deepStrictEqual(jaegerFormat.extract(getter), spanContext);
210+
});
107211
});
108212

109213
// Same test as propagation-stackdriver.

0 commit comments

Comments
 (0)