@uoa/lambda-tracing 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/UoaB3Propagator.ts +128 -109
- package/dist/UoaB3Propagator.d.ts +1 -0
- package/dist/UoaB3Propagator.js +23 -7
- package/dist/logging.js +6 -5
- package/dist/tracing.d.ts +2 -1
- package/dist/tracing.js +16 -6
- package/logging.ts +8 -6
- package/package.json +1 -1
- package/readme.md +12 -6
- package/tracing.ts +14 -5
package/UoaB3Propagator.ts
CHANGED
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* See {@link https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-propagator-b3/src/B3MultiPropagator.ts}
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
import {
|
|
7
|
+
Context,
|
|
8
|
+
isSpanContextValid,
|
|
9
|
+
trace,
|
|
10
|
+
TextMapGetter,
|
|
11
|
+
TextMapPropagator,
|
|
12
|
+
TextMapSetter,
|
|
13
|
+
TraceFlags,
|
|
14
|
+
createContextKey
|
|
15
15
|
} from '@opentelemetry/api';
|
|
16
16
|
import { isTracingSuppressed } from '@opentelemetry/core';
|
|
17
|
-
import {
|
|
17
|
+
import {getTraceInfoHeader} from "./tracing";
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
export const X_B3_TRACE_ID = 'x-b3-traceid';
|
|
@@ -24,133 +24,152 @@ export const X_B3_PARENT_SPAN_ID = 'x-b3-parentspanid';
|
|
|
24
24
|
export const X_B3_FLAGS = 'x-b3-flags';
|
|
25
25
|
export const X_B3_INFO = 'x-b3-info';
|
|
26
26
|
export const B3_DEBUG_FLAG_KEY = createContextKey(
|
|
27
|
-
|
|
27
|
+
'B3 Debug Flag'
|
|
28
28
|
);
|
|
29
29
|
export const B3_INFO_KEY = createContextKey(
|
|
30
|
-
|
|
31
|
-
)
|
|
30
|
+
'B3 Info Header'
|
|
31
|
+
);
|
|
32
|
+
export const B3_TRACE_ID_LENGTH_KEY = createContextKey(
|
|
33
|
+
'B3 TraceId Header Length'
|
|
34
|
+
);
|
|
32
35
|
|
|
33
36
|
const VALID_SAMPLED_VALUES = new Set([true, 'true', 'True', '1', 1]);
|
|
34
37
|
const VALID_UNSAMPLED_VALUES = new Set([false, 'false', 'False', '0', 0]);
|
|
35
38
|
|
|
36
39
|
function parseHeader(header: unknown) {
|
|
37
|
-
|
|
40
|
+
return Array.isArray(header) ? header[0] : header;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
function getHeaderValue(carrier: unknown, getter: TextMapGetter, key: string) {
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
const header = getter.get(carrier, key);
|
|
45
|
+
return parseHeader(header);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getTraceIdLength(carrier: unknown, getter: TextMapGetter): number {
|
|
49
|
+
const traceId = getHeaderValue(carrier, getter, X_B3_TRACE_ID);
|
|
50
|
+
if (typeof traceId === 'string') {
|
|
51
|
+
if (traceId.length <= 16 || traceId.length > 32) {
|
|
52
|
+
return 16;
|
|
53
|
+
} else {
|
|
54
|
+
return 32;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return 16;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
60
|
function getTraceId(carrier: unknown, getter: TextMapGetter): string {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
const traceId = getHeaderValue(carrier, getter, X_B3_TRACE_ID);
|
|
62
|
+
if (typeof traceId === 'string') {
|
|
63
|
+
return traceId.padStart(32, '0');
|
|
64
|
+
}
|
|
65
|
+
return '';
|
|
51
66
|
}
|
|
52
67
|
|
|
53
68
|
function getSpanId(carrier: unknown, getter: TextMapGetter): string {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
const spanId = getHeaderValue(carrier, getter, X_B3_SPAN_ID);
|
|
70
|
+
if (typeof spanId === 'string') {
|
|
71
|
+
return spanId;
|
|
72
|
+
}
|
|
73
|
+
return '';
|
|
59
74
|
}
|
|
60
75
|
|
|
61
76
|
function getDebug(carrier: unknown, getter: TextMapGetter): string | undefined {
|
|
62
|
-
|
|
63
|
-
|
|
77
|
+
const debug = getHeaderValue(carrier, getter, X_B3_FLAGS);
|
|
78
|
+
return debug === '1' ? '1' : undefined;
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
function getTraceFlags(
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
carrier: unknown,
|
|
83
|
+
getter: TextMapGetter
|
|
69
84
|
): TraceFlags | undefined {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
const traceFlags = getHeaderValue(carrier, getter, X_B3_SAMPLED);
|
|
86
|
+
const debug = getDebug(carrier, getter);
|
|
87
|
+
if (debug === '1' || VALID_SAMPLED_VALUES.has(traceFlags)) {
|
|
88
|
+
return TraceFlags.SAMPLED;
|
|
89
|
+
}
|
|
90
|
+
if (traceFlags === undefined || VALID_UNSAMPLED_VALUES.has(traceFlags)) {
|
|
91
|
+
return TraceFlags.NONE;
|
|
92
|
+
}
|
|
93
|
+
// This indicates to isValidSampledValue that this is not valid
|
|
94
|
+
return;
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
function getInfo(carrier: unknown, getter: TextMapGetter): string | undefined {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
98
|
+
const info = getHeaderValue(carrier, getter, X_B3_INFO);
|
|
99
|
+
if (typeof info === 'string') {
|
|
100
|
+
return info;
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
88
103
|
}
|
|
89
104
|
|
|
90
105
|
export class UoaB3Propagator implements TextMapPropagator {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
106
|
+
inject(context: Context, carrier: any, setter: TextMapSetter<any>): void {
|
|
107
|
+
const spanContext = trace.getSpanContext(context);
|
|
108
|
+
if (
|
|
109
|
+
!spanContext ||
|
|
110
|
+
!isSpanContextValid(spanContext) ||
|
|
111
|
+
isTracingSuppressed(context)
|
|
112
|
+
)
|
|
113
|
+
return;
|
|
114
|
+
|
|
115
|
+
const debug = context.getValue(B3_DEBUG_FLAG_KEY);
|
|
116
|
+
const traceIdLength: number = <number>context.getValue(B3_TRACE_ID_LENGTH_KEY);
|
|
117
|
+
setter.set(carrier, X_B3_TRACE_ID, spanContext.traceId.slice(spanContext.traceId.length - traceIdLength));
|
|
118
|
+
setter.set(carrier, X_B3_SPAN_ID, spanContext.spanId);
|
|
119
|
+
const info = context.getValue(B3_INFO_KEY);
|
|
120
|
+
if (getTraceInfoHeader()) {
|
|
121
|
+
setter.set(carrier, X_B3_INFO, getTraceInfoHeader());
|
|
122
|
+
} else if (info && typeof info === 'string') {
|
|
123
|
+
setter.set(carrier, X_B3_INFO, info.toString());
|
|
124
|
+
}
|
|
125
|
+
// According to the B3 spec, if the debug flag is set,
|
|
126
|
+
// the sampled flag shouldn't be propagated as well.
|
|
127
|
+
if (debug === '1') {
|
|
128
|
+
setter.set(carrier, X_B3_FLAGS, debug);
|
|
129
|
+
} else if (spanContext.traceFlags !== undefined) {
|
|
130
|
+
// We set the header only if there is an existing sampling decision.
|
|
131
|
+
// Otherwise we will omit it => Absent.
|
|
132
|
+
setter.set(
|
|
133
|
+
carrier,
|
|
134
|
+
X_B3_SAMPLED,
|
|
135
|
+
(TraceFlags.SAMPLED & spanContext.traceFlags) === TraceFlags.SAMPLED
|
|
136
|
+
? '1'
|
|
137
|
+
: '0'
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
extract(context: Context, carrier: any, getter: TextMapGetter<any>): Context {
|
|
143
|
+
const traceIdLength = getTraceIdLength(carrier, getter);
|
|
144
|
+
context = context.setValue(B3_TRACE_ID_LENGTH_KEY, traceIdLength);
|
|
145
|
+
|
|
146
|
+
const traceId = getTraceId(carrier, getter);
|
|
147
|
+
const spanId = getSpanId(carrier, getter);
|
|
148
|
+
const traceFlags = getTraceFlags(carrier, getter) as TraceFlags;
|
|
149
|
+
const debug = getDebug(carrier, getter);
|
|
150
|
+
const info = getInfo(carrier, getter);
|
|
151
|
+
|
|
152
|
+
context = context.setValue(B3_DEBUG_FLAG_KEY, debug);
|
|
153
|
+
if (info) {
|
|
154
|
+
context = context.setValue(B3_INFO_KEY, info);
|
|
155
|
+
}
|
|
156
|
+
return trace.setSpanContext(context, {
|
|
157
|
+
traceId,
|
|
158
|
+
spanId,
|
|
159
|
+
isRemote: true,
|
|
160
|
+
traceFlags,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
fields(): string[] {
|
|
165
|
+
return [
|
|
166
|
+
X_B3_TRACE_ID,
|
|
167
|
+
X_B3_SPAN_ID,
|
|
168
|
+
X_B3_FLAGS,
|
|
169
|
+
X_B3_SAMPLED,
|
|
170
|
+
X_B3_PARENT_SPAN_ID,
|
|
171
|
+
X_B3_INFO
|
|
172
|
+
];
|
|
173
|
+
}
|
|
155
174
|
|
|
156
175
|
}
|
|
@@ -12,6 +12,7 @@ export declare const X_B3_FLAGS = "x-b3-flags";
|
|
|
12
12
|
export declare const X_B3_INFO = "x-b3-info";
|
|
13
13
|
export declare const B3_DEBUG_FLAG_KEY: symbol;
|
|
14
14
|
export declare const B3_INFO_KEY: symbol;
|
|
15
|
+
export declare const B3_TRACE_ID_LENGTH_KEY: symbol;
|
|
15
16
|
export declare class UoaB3Propagator implements TextMapPropagator {
|
|
16
17
|
inject(context: Context, carrier: any, setter: TextMapSetter<any>): void;
|
|
17
18
|
extract(context: Context, carrier: any, getter: TextMapGetter<any>): Context;
|
package/dist/UoaB3Propagator.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UoaB3Propagator = exports.B3_INFO_KEY = exports.B3_DEBUG_FLAG_KEY = exports.X_B3_INFO = exports.X_B3_FLAGS = exports.X_B3_PARENT_SPAN_ID = exports.X_B3_SAMPLED = exports.X_B3_SPAN_ID = exports.X_B3_TRACE_ID = void 0;
|
|
3
|
+
exports.UoaB3Propagator = exports.B3_TRACE_ID_LENGTH_KEY = exports.B3_INFO_KEY = exports.B3_DEBUG_FLAG_KEY = exports.X_B3_INFO = exports.X_B3_FLAGS = exports.X_B3_PARENT_SPAN_ID = exports.X_B3_SAMPLED = exports.X_B3_SPAN_ID = exports.X_B3_TRACE_ID = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Class extended from OpenTelemetry B3MultiPropagator so that we can propagate & log the X-B3-Info header
|
|
6
6
|
*
|
|
@@ -17,6 +17,7 @@ exports.X_B3_FLAGS = 'x-b3-flags';
|
|
|
17
17
|
exports.X_B3_INFO = 'x-b3-info';
|
|
18
18
|
exports.B3_DEBUG_FLAG_KEY = (0, api_1.createContextKey)('B3 Debug Flag');
|
|
19
19
|
exports.B3_INFO_KEY = (0, api_1.createContextKey)('B3 Info Header');
|
|
20
|
+
exports.B3_TRACE_ID_LENGTH_KEY = (0, api_1.createContextKey)('B3 TraceId Header Length');
|
|
20
21
|
const VALID_SAMPLED_VALUES = new Set([true, 'true', 'True', '1', 1]);
|
|
21
22
|
const VALID_UNSAMPLED_VALUES = new Set([false, 'false', 'False', '0', 0]);
|
|
22
23
|
function parseHeader(header) {
|
|
@@ -26,6 +27,18 @@ function getHeaderValue(carrier, getter, key) {
|
|
|
26
27
|
const header = getter.get(carrier, key);
|
|
27
28
|
return parseHeader(header);
|
|
28
29
|
}
|
|
30
|
+
function getTraceIdLength(carrier, getter) {
|
|
31
|
+
const traceId = getHeaderValue(carrier, getter, exports.X_B3_TRACE_ID);
|
|
32
|
+
if (typeof traceId === 'string') {
|
|
33
|
+
if (traceId.length <= 16 || traceId.length > 32) {
|
|
34
|
+
return 16;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return 32;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return 16;
|
|
41
|
+
}
|
|
29
42
|
function getTraceId(carrier, getter) {
|
|
30
43
|
const traceId = getHeaderValue(carrier, getter, exports.X_B3_TRACE_ID);
|
|
31
44
|
if (typeof traceId === 'string') {
|
|
@@ -38,7 +51,7 @@ function getSpanId(carrier, getter) {
|
|
|
38
51
|
if (typeof spanId === 'string') {
|
|
39
52
|
return spanId;
|
|
40
53
|
}
|
|
41
|
-
return '
|
|
54
|
+
return '';
|
|
42
55
|
}
|
|
43
56
|
function getDebug(carrier, getter) {
|
|
44
57
|
const debug = getHeaderValue(carrier, getter, exports.X_B3_FLAGS);
|
|
@@ -71,14 +84,15 @@ class UoaB3Propagator {
|
|
|
71
84
|
(0, core_1.isTracingSuppressed)(context))
|
|
72
85
|
return;
|
|
73
86
|
const debug = context.getValue(exports.B3_DEBUG_FLAG_KEY);
|
|
74
|
-
|
|
87
|
+
const traceIdLength = context.getValue(exports.B3_TRACE_ID_LENGTH_KEY);
|
|
88
|
+
setter.set(carrier, exports.X_B3_TRACE_ID, spanContext.traceId.slice(spanContext.traceId.length - traceIdLength));
|
|
75
89
|
setter.set(carrier, exports.X_B3_SPAN_ID, spanContext.spanId);
|
|
76
90
|
const info = context.getValue(exports.B3_INFO_KEY);
|
|
77
|
-
if (
|
|
78
|
-
setter.set(carrier, exports.X_B3_INFO,
|
|
91
|
+
if ((0, tracing_1.getTraceInfoHeader)()) {
|
|
92
|
+
setter.set(carrier, exports.X_B3_INFO, (0, tracing_1.getTraceInfoHeader)());
|
|
79
93
|
}
|
|
80
|
-
else if (
|
|
81
|
-
setter.set(carrier, exports.X_B3_INFO,
|
|
94
|
+
else if (info && typeof info === 'string') {
|
|
95
|
+
setter.set(carrier, exports.X_B3_INFO, info.toString());
|
|
82
96
|
}
|
|
83
97
|
// According to the B3 spec, if the debug flag is set,
|
|
84
98
|
// the sampled flag shouldn't be propagated as well.
|
|
@@ -94,6 +108,8 @@ class UoaB3Propagator {
|
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
110
|
extract(context, carrier, getter) {
|
|
111
|
+
const traceIdLength = getTraceIdLength(carrier, getter);
|
|
112
|
+
context = context.setValue(exports.B3_TRACE_ID_LENGTH_KEY, traceIdLength);
|
|
97
113
|
const traceId = getTraceId(carrier, getter);
|
|
98
114
|
const spanId = getSpanId(carrier, getter);
|
|
99
115
|
const traceFlags = getTraceFlags(carrier, getter);
|
package/dist/logging.js
CHANGED
|
@@ -35,18 +35,19 @@ function getLogReplacementValues(callingModule, logInfo) {
|
|
|
35
35
|
}
|
|
36
36
|
let info = '-';
|
|
37
37
|
const infoHeader = context.active().getValue(UoaB3Propagator_1.B3_INFO_KEY);
|
|
38
|
-
if (
|
|
39
|
-
info =
|
|
38
|
+
if ((0, tracing_1.getTraceInfoHeader)()) {
|
|
39
|
+
info = (0, tracing_1.getTraceInfoHeader)();
|
|
40
40
|
}
|
|
41
|
-
else if (
|
|
42
|
-
info =
|
|
41
|
+
else if (infoHeader) {
|
|
42
|
+
info = infoHeader.toString();
|
|
43
43
|
}
|
|
44
|
+
const traceIdLength = context.active().getValue(UoaB3Propagator_1.B3_TRACE_ID_LENGTH_KEY);
|
|
44
45
|
let logReplacements = new Map();
|
|
45
46
|
logReplacements.set('%date', moment().toISOString());
|
|
46
47
|
logReplacements.set('%thread', '-');
|
|
47
48
|
logReplacements.set('%level', logInfo.level.toUpperCase());
|
|
48
49
|
logReplacements.set('%class', moduleParts.join('.'));
|
|
49
|
-
logReplacements.set('%traceId', traceId);
|
|
50
|
+
logReplacements.set('%traceId', traceId.slice(traceId.length - traceIdLength));
|
|
50
51
|
logReplacements.set('%spanId', spanId);
|
|
51
52
|
logReplacements.set('%info', info);
|
|
52
53
|
logReplacements.set('%message', logInfo.message.replace(/\n/g, ''));
|
package/dist/tracing.d.ts
CHANGED
package/dist/tracing.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.setTraceInfoHeader = exports.getTraceInfoHeader = exports.initializeTracing = void 0;
|
|
4
4
|
const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
|
|
5
5
|
const instrumentation_aws_lambda_1 = require("@opentelemetry/instrumentation-aws-lambda");
|
|
6
6
|
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
7
7
|
const UoaB3Propagator_1 = require("./UoaB3Propagator");
|
|
8
|
+
const api_1 = require("@opentelemetry/api");
|
|
8
9
|
const provider = new sdk_trace_node_1.NodeTracerProvider();
|
|
9
|
-
let
|
|
10
|
+
let infoHeader;
|
|
10
11
|
function initializeTracing() {
|
|
11
12
|
provider.register({
|
|
12
13
|
propagator: new UoaB3Propagator_1.UoaB3Propagator()
|
|
@@ -16,7 +17,7 @@ function initializeTracing() {
|
|
|
16
17
|
new instrumentation_aws_lambda_1.AwsLambdaInstrumentation({
|
|
17
18
|
requestHook: (span, { event, context }) => {
|
|
18
19
|
span.setAttribute('faas.name', context.functionName);
|
|
19
|
-
|
|
20
|
+
infoHeader = undefined; //reset header value in case lambda execution environment maintained since last invocation
|
|
20
21
|
},
|
|
21
22
|
responseHook: (span, { err, res }) => {
|
|
22
23
|
if (err instanceof Error)
|
|
@@ -30,7 +31,16 @@ function initializeTracing() {
|
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
33
|
exports.initializeTracing = initializeTracing;
|
|
33
|
-
function
|
|
34
|
-
|
|
34
|
+
function getTraceInfoHeader() {
|
|
35
|
+
if (infoHeader) {
|
|
36
|
+
return infoHeader;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return api_1.context.active().getValue(UoaB3Propagator_1.B3_INFO_KEY);
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
|
-
exports.
|
|
42
|
+
exports.getTraceInfoHeader = getTraceInfoHeader;
|
|
43
|
+
function setTraceInfoHeader(info) {
|
|
44
|
+
infoHeader = info;
|
|
45
|
+
}
|
|
46
|
+
exports.setTraceInfoHeader = setTraceInfoHeader;
|
package/logging.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {B3_INFO_KEY} from "./UoaB3Propagator";
|
|
2
|
-
import {
|
|
1
|
+
import {B3_INFO_KEY, B3_TRACE_ID_LENGTH_KEY} from "./UoaB3Propagator";
|
|
2
|
+
import {getTraceInfoHeader} from "./tracing";
|
|
3
3
|
|
|
4
4
|
const winston = require('winston');
|
|
5
5
|
const moment = require('moment');
|
|
@@ -41,18 +41,20 @@ function getLogReplacementValues(callingModule: NodeModule, logInfo: any): Map<s
|
|
|
41
41
|
|
|
42
42
|
let info = '-';
|
|
43
43
|
const infoHeader = context.active().getValue(B3_INFO_KEY);
|
|
44
|
-
if (
|
|
44
|
+
if (getTraceInfoHeader()) {
|
|
45
|
+
info = getTraceInfoHeader();
|
|
46
|
+
} else if (infoHeader) {
|
|
45
47
|
info = infoHeader.toString();
|
|
46
|
-
} else if (getRequestId()) {
|
|
47
|
-
info = `lambdaRequestId:${getRequestId()}`;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
const traceIdLength: number = <number>context.active().getValue(B3_TRACE_ID_LENGTH_KEY);
|
|
51
|
+
|
|
50
52
|
let logReplacements: Map<string, string> = new Map<string, string>();
|
|
51
53
|
logReplacements.set('%date', moment().toISOString());
|
|
52
54
|
logReplacements.set('%thread', '-');
|
|
53
55
|
logReplacements.set('%level', logInfo.level.toUpperCase());
|
|
54
56
|
logReplacements.set('%class', moduleParts.join('.'));
|
|
55
|
-
logReplacements.set('%traceId', traceId);
|
|
57
|
+
logReplacements.set('%traceId', traceId.slice(traceId.length - traceIdLength));
|
|
56
58
|
logReplacements.set('%spanId', spanId);
|
|
57
59
|
logReplacements.set('%info', info);
|
|
58
60
|
logReplacements.set('%message', logInfo.message.replace(/\n/g, ''));
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -97,20 +97,26 @@ Valid logging pattern placeholders are as follows:
|
|
|
97
97
|
|%class|The module which logged the message|src.handle-service|
|
|
98
98
|
|%traceId|Unique Id for the request|5c0c783c965a684842608f10422fdf2c|
|
|
99
99
|
|%spanId|Unique Id for the current lambda invocation|6a8b025511ac1191|
|
|
100
|
-
|%info|Extra information to help with filtering the logs|
|
|
100
|
+
|%info|Extra information to help with filtering the logs|usefulCode=12345|
|
|
101
101
|
|%message|The logged message|Hello Logger!|
|
|
102
102
|
|
|
103
103
|
### Distributed Tracing
|
|
104
104
|
There are two headers that can be passed in API calls to your lambda project using this library: ```X-B3-TraceId``` and ```X-B3-Info```.
|
|
105
105
|
If passed to a lambda project using this library, the values of %traceId and %info in the logging pattern will be the corresponding header values.
|
|
106
106
|
|
|
107
|
-
`X-B3-TraceId` should be a 32 character lowercase hex encoded string.\
|
|
108
|
-
If the passed traceId is less than
|
|
109
|
-
characters, it will be left padded with 0's to get to a length of 32.\
|
|
110
|
-
If
|
|
107
|
+
`X-B3-TraceId` should be either a 16 or 32 character lowercase hex encoded string.\
|
|
108
|
+
If the passed traceId is less than 16 characters, it will be left padded with 0's to get to a length of 16.\
|
|
109
|
+
Likewise, if it is longer than 16 but less than 32 characters, it will be left padded with 0's to get to a length of 32.\
|
|
110
|
+
If it is longer than 32 characters, a new traceId will be generated.\
|
|
111
|
+
If the `X-B3-TraceId` **_and_** `X-B3-SpanId` headers are not passed, they will be randomly generated.
|
|
111
112
|
|
|
112
113
|
`X-B3-Info` can be any string value to provide extra information in your logs.\
|
|
113
|
-
|
|
114
|
+
The value of this header can be accessed by using the `getTraceInfoHeader(): string` function.
|
|
115
|
+
Similarly, it can be set using the `setTraceInfoHeader(string)` function.\
|
|
116
|
+
These two functions can be imported using:
|
|
117
|
+
```
|
|
118
|
+
const {setTraceInfoHeader, getTraceInfoHeader} = require('./logging/tracing');
|
|
119
|
+
```
|
|
114
120
|
|
|
115
121
|
**Header Propagation**
|
|
116
122
|
|
package/tracing.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {NodeTracerProvider} from '@opentelemetry/sdk-trace-node';
|
|
2
2
|
import {AwsLambdaInstrumentation} from '@opentelemetry/instrumentation-aws-lambda';
|
|
3
3
|
import {registerInstrumentations} from '@opentelemetry/instrumentation';
|
|
4
|
-
import {UoaB3Propagator} from "./UoaB3Propagator";
|
|
4
|
+
import {B3_INFO_KEY, UoaB3Propagator} from "./UoaB3Propagator";
|
|
5
|
+
import {context} from "@opentelemetry/api";
|
|
5
6
|
|
|
6
7
|
const provider = new NodeTracerProvider();
|
|
7
|
-
let
|
|
8
|
+
let infoHeader: string | undefined;
|
|
8
9
|
|
|
9
10
|
export function initializeTracing() {
|
|
10
11
|
provider.register({
|
|
@@ -16,7 +17,7 @@ export function initializeTracing() {
|
|
|
16
17
|
new AwsLambdaInstrumentation({
|
|
17
18
|
requestHook: (span, { event, context }) => {
|
|
18
19
|
span.setAttribute('faas.name', context.functionName);
|
|
19
|
-
|
|
20
|
+
infoHeader = undefined; //reset header value in case lambda execution environment maintained since last invocation
|
|
20
21
|
},
|
|
21
22
|
responseHook: (span, { err, res }) => {
|
|
22
23
|
if (err instanceof Error) span.setAttribute('faas.error', err.message);
|
|
@@ -29,6 +30,14 @@ export function initializeTracing() {
|
|
|
29
30
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
export function
|
|
33
|
-
|
|
33
|
+
export function getTraceInfoHeader(): string {
|
|
34
|
+
if (infoHeader) {
|
|
35
|
+
return infoHeader;
|
|
36
|
+
} else {
|
|
37
|
+
return <string>context.active().getValue(B3_INFO_KEY);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function setTraceInfoHeader(info: string) {
|
|
42
|
+
infoHeader = info;
|
|
34
43
|
}
|