@uoa/lambda-tracing 1.2.0 → 1.5.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 +130 -109
- package/dist/UoaB3Propagator.d.ts +1 -0
- package/dist/UoaB3Propagator.js +26 -8
- package/dist/logging.js +6 -5
- package/dist/tracing.d.ts +2 -1
- package/dist/tracing.js +16 -6
- package/dist/uoaHttps.js +12 -8
- package/logging.ts +8 -6
- package/package.json +1 -1
- package/readme.md +12 -6
- package/tracing.ts +14 -5
- package/uoaHttps.ts +12 -8
package/UoaB3Propagator.ts
CHANGED
|
@@ -3,18 +3,19 @@
|
|
|
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
|
+
const crypto = require('crypto');
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
export const X_B3_TRACE_ID = 'x-b3-traceid';
|
|
@@ -24,133 +25,153 @@ export const X_B3_PARENT_SPAN_ID = 'x-b3-parentspanid';
|
|
|
24
25
|
export const X_B3_FLAGS = 'x-b3-flags';
|
|
25
26
|
export const X_B3_INFO = 'x-b3-info';
|
|
26
27
|
export const B3_DEBUG_FLAG_KEY = createContextKey(
|
|
27
|
-
|
|
28
|
+
'B3 Debug Flag'
|
|
28
29
|
);
|
|
29
30
|
export const B3_INFO_KEY = createContextKey(
|
|
30
|
-
|
|
31
|
-
)
|
|
31
|
+
'B3 Info Header'
|
|
32
|
+
);
|
|
33
|
+
export const B3_TRACE_ID_LENGTH_KEY = createContextKey(
|
|
34
|
+
'B3 TraceId Header Length'
|
|
35
|
+
);
|
|
32
36
|
|
|
33
37
|
const VALID_SAMPLED_VALUES = new Set([true, 'true', 'True', '1', 1]);
|
|
34
38
|
const VALID_UNSAMPLED_VALUES = new Set([false, 'false', 'False', '0', 0]);
|
|
35
39
|
|
|
36
40
|
function parseHeader(header: unknown) {
|
|
37
|
-
|
|
41
|
+
return Array.isArray(header) ? header[0] : header;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
function getHeaderValue(carrier: unknown, getter: TextMapGetter, key: string) {
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
const header = getter.get(carrier, key);
|
|
46
|
+
return parseHeader(header);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getTraceIdLength(carrier: unknown, getter: TextMapGetter): number {
|
|
50
|
+
const traceId = getHeaderValue(carrier, getter, X_B3_TRACE_ID);
|
|
51
|
+
if (typeof traceId === 'string') {
|
|
52
|
+
if (traceId.length <= 16 || traceId.length > 32) {
|
|
53
|
+
return 16;
|
|
54
|
+
} else {
|
|
55
|
+
return 32;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return 16;
|
|
43
59
|
}
|
|
44
60
|
|
|
45
61
|
function getTraceId(carrier: unknown, getter: TextMapGetter): string {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
62
|
+
const traceId = getHeaderValue(carrier, getter, X_B3_TRACE_ID);
|
|
63
|
+
if (typeof traceId === 'string') {
|
|
64
|
+
return traceId.padStart(32, '0');
|
|
65
|
+
}
|
|
66
|
+
return '';
|
|
51
67
|
}
|
|
52
68
|
|
|
53
69
|
function getSpanId(carrier: unknown, getter: TextMapGetter): string {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
const spanId = getHeaderValue(carrier, getter, X_B3_SPAN_ID);
|
|
71
|
+
if (typeof spanId === 'string') {
|
|
72
|
+
return spanId;
|
|
73
|
+
}
|
|
74
|
+
return '';
|
|
59
75
|
}
|
|
60
76
|
|
|
61
77
|
function getDebug(carrier: unknown, getter: TextMapGetter): string | undefined {
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
const debug = getHeaderValue(carrier, getter, X_B3_FLAGS);
|
|
79
|
+
return debug === '1' ? '1' : undefined;
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
function getTraceFlags(
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
carrier: unknown,
|
|
84
|
+
getter: TextMapGetter
|
|
69
85
|
): TraceFlags | undefined {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
const traceFlags = getHeaderValue(carrier, getter, X_B3_SAMPLED);
|
|
87
|
+
const debug = getDebug(carrier, getter);
|
|
88
|
+
if (debug === '1' || VALID_SAMPLED_VALUES.has(traceFlags)) {
|
|
89
|
+
return TraceFlags.SAMPLED;
|
|
90
|
+
}
|
|
91
|
+
if (traceFlags === undefined || VALID_UNSAMPLED_VALUES.has(traceFlags)) {
|
|
92
|
+
return TraceFlags.NONE;
|
|
93
|
+
}
|
|
94
|
+
// This indicates to isValidSampledValue that this is not valid
|
|
95
|
+
return;
|
|
80
96
|
}
|
|
81
97
|
|
|
82
98
|
function getInfo(carrier: unknown, getter: TextMapGetter): string | undefined {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
const info = getHeaderValue(carrier, getter, X_B3_INFO);
|
|
100
|
+
if (typeof info === 'string') {
|
|
101
|
+
return info;
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
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
|
-
|
|
107
|
+
inject(context: Context, carrier: any, setter: TextMapSetter<any>): void {
|
|
108
|
+
const spanContext = trace.getSpanContext(context);
|
|
109
|
+
if (
|
|
110
|
+
!spanContext ||
|
|
111
|
+
!isSpanContextValid(spanContext) ||
|
|
112
|
+
isTracingSuppressed(context)
|
|
113
|
+
)
|
|
114
|
+
return;
|
|
115
|
+
|
|
116
|
+
const debug = context.getValue(B3_DEBUG_FLAG_KEY);
|
|
117
|
+
const traceIdLength: number = <number>context.getValue(B3_TRACE_ID_LENGTH_KEY);
|
|
118
|
+
setter.set(carrier, X_B3_TRACE_ID, spanContext.traceId.slice(spanContext.traceId.length - traceIdLength));
|
|
119
|
+
setter.set(carrier, X_B3_SPAN_ID, crypto.randomBytes(8).toString('hex'));
|
|
120
|
+
setter.set(carrier, X_B3_PARENT_SPAN_ID, spanContext.spanId);
|
|
121
|
+
const info = context.getValue(B3_INFO_KEY);
|
|
122
|
+
if (getTraceInfoHeader()) {
|
|
123
|
+
setter.set(carrier, X_B3_INFO, getTraceInfoHeader());
|
|
124
|
+
} else if (info && typeof info === 'string') {
|
|
125
|
+
setter.set(carrier, X_B3_INFO, info.toString());
|
|
126
|
+
}
|
|
127
|
+
// According to the B3 spec, if the debug flag is set,
|
|
128
|
+
// the sampled flag shouldn't be propagated as well.
|
|
129
|
+
if (debug === '1') {
|
|
130
|
+
setter.set(carrier, X_B3_FLAGS, debug);
|
|
131
|
+
} else if (spanContext.traceFlags !== undefined) {
|
|
132
|
+
// We set the header only if there is an existing sampling decision.
|
|
133
|
+
// Otherwise we will omit it => Absent.
|
|
134
|
+
setter.set(
|
|
135
|
+
carrier,
|
|
136
|
+
X_B3_SAMPLED,
|
|
137
|
+
(TraceFlags.SAMPLED & spanContext.traceFlags) === TraceFlags.SAMPLED
|
|
138
|
+
? '1'
|
|
139
|
+
: '0'
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
extract(context: Context, carrier: any, getter: TextMapGetter<any>): Context {
|
|
145
|
+
const traceIdLength = getTraceIdLength(carrier, getter);
|
|
146
|
+
context = context.setValue(B3_TRACE_ID_LENGTH_KEY, traceIdLength);
|
|
147
|
+
|
|
148
|
+
const traceId = getTraceId(carrier, getter);
|
|
149
|
+
const spanId = getSpanId(carrier, getter);
|
|
150
|
+
const traceFlags = getTraceFlags(carrier, getter) as TraceFlags;
|
|
151
|
+
const debug = getDebug(carrier, getter);
|
|
152
|
+
const info = getInfo(carrier, getter);
|
|
153
|
+
|
|
154
|
+
context = context.setValue(B3_DEBUG_FLAG_KEY, debug);
|
|
155
|
+
if (info) {
|
|
156
|
+
context = context.setValue(B3_INFO_KEY, info);
|
|
157
|
+
}
|
|
158
|
+
return trace.setSpanContext(context, {
|
|
159
|
+
traceId,
|
|
160
|
+
spanId,
|
|
161
|
+
isRemote: true,
|
|
162
|
+
traceFlags,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
fields(): string[] {
|
|
167
|
+
return [
|
|
168
|
+
X_B3_TRACE_ID,
|
|
169
|
+
X_B3_SPAN_ID,
|
|
170
|
+
X_B3_FLAGS,
|
|
171
|
+
X_B3_SAMPLED,
|
|
172
|
+
X_B3_PARENT_SPAN_ID,
|
|
173
|
+
X_B3_INFO
|
|
174
|
+
];
|
|
175
|
+
}
|
|
155
176
|
|
|
156
177
|
}
|
|
@@ -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
|
*
|
|
@@ -9,6 +9,7 @@ exports.UoaB3Propagator = exports.B3_INFO_KEY = exports.B3_DEBUG_FLAG_KEY = expo
|
|
|
9
9
|
const api_1 = require("@opentelemetry/api");
|
|
10
10
|
const core_1 = require("@opentelemetry/core");
|
|
11
11
|
const tracing_1 = require("./tracing");
|
|
12
|
+
const crypto = require('crypto');
|
|
12
13
|
exports.X_B3_TRACE_ID = 'x-b3-traceid';
|
|
13
14
|
exports.X_B3_SPAN_ID = 'x-b3-spanid';
|
|
14
15
|
exports.X_B3_SAMPLED = 'x-b3-sampled';
|
|
@@ -17,6 +18,7 @@ exports.X_B3_FLAGS = 'x-b3-flags';
|
|
|
17
18
|
exports.X_B3_INFO = 'x-b3-info';
|
|
18
19
|
exports.B3_DEBUG_FLAG_KEY = (0, api_1.createContextKey)('B3 Debug Flag');
|
|
19
20
|
exports.B3_INFO_KEY = (0, api_1.createContextKey)('B3 Info Header');
|
|
21
|
+
exports.B3_TRACE_ID_LENGTH_KEY = (0, api_1.createContextKey)('B3 TraceId Header Length');
|
|
20
22
|
const VALID_SAMPLED_VALUES = new Set([true, 'true', 'True', '1', 1]);
|
|
21
23
|
const VALID_UNSAMPLED_VALUES = new Set([false, 'false', 'False', '0', 0]);
|
|
22
24
|
function parseHeader(header) {
|
|
@@ -26,6 +28,18 @@ function getHeaderValue(carrier, getter, key) {
|
|
|
26
28
|
const header = getter.get(carrier, key);
|
|
27
29
|
return parseHeader(header);
|
|
28
30
|
}
|
|
31
|
+
function getTraceIdLength(carrier, getter) {
|
|
32
|
+
const traceId = getHeaderValue(carrier, getter, exports.X_B3_TRACE_ID);
|
|
33
|
+
if (typeof traceId === 'string') {
|
|
34
|
+
if (traceId.length <= 16 || traceId.length > 32) {
|
|
35
|
+
return 16;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
return 32;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return 16;
|
|
42
|
+
}
|
|
29
43
|
function getTraceId(carrier, getter) {
|
|
30
44
|
const traceId = getHeaderValue(carrier, getter, exports.X_B3_TRACE_ID);
|
|
31
45
|
if (typeof traceId === 'string') {
|
|
@@ -38,7 +52,7 @@ function getSpanId(carrier, getter) {
|
|
|
38
52
|
if (typeof spanId === 'string') {
|
|
39
53
|
return spanId;
|
|
40
54
|
}
|
|
41
|
-
return '
|
|
55
|
+
return '';
|
|
42
56
|
}
|
|
43
57
|
function getDebug(carrier, getter) {
|
|
44
58
|
const debug = getHeaderValue(carrier, getter, exports.X_B3_FLAGS);
|
|
@@ -71,14 +85,16 @@ class UoaB3Propagator {
|
|
|
71
85
|
(0, core_1.isTracingSuppressed)(context))
|
|
72
86
|
return;
|
|
73
87
|
const debug = context.getValue(exports.B3_DEBUG_FLAG_KEY);
|
|
74
|
-
|
|
75
|
-
setter.set(carrier, exports.
|
|
88
|
+
const traceIdLength = context.getValue(exports.B3_TRACE_ID_LENGTH_KEY);
|
|
89
|
+
setter.set(carrier, exports.X_B3_TRACE_ID, spanContext.traceId.slice(spanContext.traceId.length - traceIdLength));
|
|
90
|
+
setter.set(carrier, exports.X_B3_SPAN_ID, crypto.randomBytes(8).toString('hex'));
|
|
91
|
+
setter.set(carrier, exports.X_B3_PARENT_SPAN_ID, spanContext.spanId);
|
|
76
92
|
const info = context.getValue(exports.B3_INFO_KEY);
|
|
77
|
-
if (
|
|
78
|
-
setter.set(carrier, exports.X_B3_INFO,
|
|
93
|
+
if ((0, tracing_1.getTraceInfoHeader)()) {
|
|
94
|
+
setter.set(carrier, exports.X_B3_INFO, (0, tracing_1.getTraceInfoHeader)());
|
|
79
95
|
}
|
|
80
|
-
else if (
|
|
81
|
-
setter.set(carrier, exports.X_B3_INFO,
|
|
96
|
+
else if (info && typeof info === 'string') {
|
|
97
|
+
setter.set(carrier, exports.X_B3_INFO, info.toString());
|
|
82
98
|
}
|
|
83
99
|
// According to the B3 spec, if the debug flag is set,
|
|
84
100
|
// the sampled flag shouldn't be propagated as well.
|
|
@@ -94,6 +110,8 @@ class UoaB3Propagator {
|
|
|
94
110
|
}
|
|
95
111
|
}
|
|
96
112
|
extract(context, carrier, getter) {
|
|
113
|
+
const traceIdLength = getTraceIdLength(carrier, getter);
|
|
114
|
+
context = context.setValue(exports.B3_TRACE_ID_LENGTH_KEY, traceIdLength);
|
|
97
115
|
const traceId = getTraceId(carrier, getter);
|
|
98
116
|
const spanId = getSpanId(carrier, getter);
|
|
99
117
|
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/dist/uoaHttps.js
CHANGED
|
@@ -44,14 +44,15 @@ function request(...args) {
|
|
|
44
44
|
return https.request(args[0], args[1]);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
function doGetRequest(hostname, path, headers) {
|
|
47
|
+
function doGetRequest(hostname, path, headers, port = 443) {
|
|
48
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
49
|
return new Promise(function (resolve, reject) {
|
|
50
50
|
const options = {
|
|
51
51
|
"method": "GET",
|
|
52
52
|
"hostname": hostname,
|
|
53
53
|
"path": path,
|
|
54
|
-
"headers": headers
|
|
54
|
+
"headers": headers,
|
|
55
|
+
"port": port
|
|
55
56
|
};
|
|
56
57
|
api_1.propagation.inject(api_1.context.active(), options.headers);
|
|
57
58
|
const req = https.request(options, function (response) {
|
|
@@ -72,14 +73,15 @@ function doGetRequest(hostname, path, headers) {
|
|
|
72
73
|
});
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
|
-
function doPostRequest(hostname, path, headers, data) {
|
|
76
|
+
function doPostRequest(hostname, path, headers, data, port = 443) {
|
|
76
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
77
78
|
return new Promise(function (resolve, reject) {
|
|
78
79
|
const options = {
|
|
79
80
|
"method": "POST",
|
|
80
81
|
"hostname": hostname,
|
|
81
82
|
"path": path,
|
|
82
|
-
"headers": headers
|
|
83
|
+
"headers": headers,
|
|
84
|
+
"port": port
|
|
83
85
|
};
|
|
84
86
|
api_1.propagation.inject(api_1.context.active(), options.headers);
|
|
85
87
|
const req = https.request(options, function (response) {
|
|
@@ -121,14 +123,15 @@ function doPostRequest(hostname, path, headers, data) {
|
|
|
121
123
|
});
|
|
122
124
|
});
|
|
123
125
|
}
|
|
124
|
-
function doPutRequest(hostname, path, headers, data) {
|
|
126
|
+
function doPutRequest(hostname, path, headers, data, port = 443) {
|
|
125
127
|
return __awaiter(this, void 0, void 0, function* () {
|
|
126
128
|
return new Promise(function (resolve, reject) {
|
|
127
129
|
const options = {
|
|
128
130
|
"method": "PUT",
|
|
129
131
|
"hostname": hostname,
|
|
130
132
|
"path": path,
|
|
131
|
-
"headers": headers
|
|
133
|
+
"headers": headers,
|
|
134
|
+
"port": port
|
|
132
135
|
};
|
|
133
136
|
api_1.propagation.inject(api_1.context.active(), options.headers);
|
|
134
137
|
const req = https.request(options, function (response) {
|
|
@@ -170,14 +173,15 @@ function doPutRequest(hostname, path, headers, data) {
|
|
|
170
173
|
});
|
|
171
174
|
});
|
|
172
175
|
}
|
|
173
|
-
function doDeleteRequest(hostname, path, headers) {
|
|
176
|
+
function doDeleteRequest(hostname, path, headers, port = 443) {
|
|
174
177
|
return __awaiter(this, void 0, void 0, function* () {
|
|
175
178
|
return new Promise(function (resolve, reject) {
|
|
176
179
|
const options = {
|
|
177
180
|
"method": "DELETE",
|
|
178
181
|
"hostname": hostname,
|
|
179
182
|
"path": path,
|
|
180
|
-
"headers": headers
|
|
183
|
+
"headers": headers,
|
|
184
|
+
"port": port
|
|
181
185
|
};
|
|
182
186
|
api_1.propagation.inject(api_1.context.active(), options.headers);
|
|
183
187
|
const req = https.request(options, function (response) {
|
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
|
}
|
package/uoaHttps.ts
CHANGED
|
@@ -16,13 +16,14 @@ function request(...args: any[]): http.ClientRequest {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
async function doGetRequest(hostname: string, path: string, headers: any) {
|
|
19
|
+
async function doGetRequest(hostname: string, path: string, headers: any, port: number | string = 443) {
|
|
20
20
|
return new Promise(function (resolve, reject) {
|
|
21
21
|
const options = {
|
|
22
22
|
"method": "GET",
|
|
23
23
|
"hostname": hostname,
|
|
24
24
|
"path": path,
|
|
25
|
-
"headers": headers
|
|
25
|
+
"headers": headers,
|
|
26
|
+
"port": port
|
|
26
27
|
}
|
|
27
28
|
propagation.inject(context.active(), options.headers);
|
|
28
29
|
|
|
@@ -48,13 +49,14 @@ async function doGetRequest(hostname: string, path: string, headers: any) {
|
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
async function doPostRequest(hostname: string, path: string, headers: any, data: any) {
|
|
52
|
+
async function doPostRequest(hostname: string, path: string, headers: any, data: any, port: number | string = 443) {
|
|
52
53
|
return new Promise(function (resolve, reject) {
|
|
53
54
|
const options = {
|
|
54
55
|
"method": "POST",
|
|
55
56
|
"hostname": hostname,
|
|
56
57
|
"path": path,
|
|
57
|
-
"headers": headers
|
|
58
|
+
"headers": headers,
|
|
59
|
+
"port": port
|
|
58
60
|
}
|
|
59
61
|
propagation.inject(context.active(), options.headers);
|
|
60
62
|
|
|
@@ -98,13 +100,14 @@ async function doPostRequest(hostname: string, path: string, headers: any, data:
|
|
|
98
100
|
});
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
async function doPutRequest(hostname: string, path: string, headers: any, data: any) {
|
|
103
|
+
async function doPutRequest(hostname: string, path: string, headers: any, data: any, port: number | string = 443) {
|
|
102
104
|
return new Promise(function (resolve, reject) {
|
|
103
105
|
const options = {
|
|
104
106
|
"method": "PUT",
|
|
105
107
|
"hostname": hostname,
|
|
106
108
|
"path": path,
|
|
107
|
-
"headers": headers
|
|
109
|
+
"headers": headers,
|
|
110
|
+
"port": port
|
|
108
111
|
}
|
|
109
112
|
propagation.inject(context.active(), options.headers);
|
|
110
113
|
|
|
@@ -148,13 +151,14 @@ async function doPutRequest(hostname: string, path: string, headers: any, data:
|
|
|
148
151
|
});
|
|
149
152
|
}
|
|
150
153
|
|
|
151
|
-
async function doDeleteRequest(hostname: string, path: string, headers: any) {
|
|
154
|
+
async function doDeleteRequest(hostname: string, path: string, headers: any, port: number | string = 443) {
|
|
152
155
|
return new Promise(function (resolve, reject) {
|
|
153
156
|
const options = {
|
|
154
157
|
"method": "DELETE",
|
|
155
158
|
"hostname": hostname,
|
|
156
159
|
"path": path,
|
|
157
|
-
"headers": headers
|
|
160
|
+
"headers": headers,
|
|
161
|
+
"port": port
|
|
158
162
|
}
|
|
159
163
|
propagation.inject(context.active(), options.headers);
|
|
160
164
|
|