@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.
@@ -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
- import {
7
- Context,
8
- isSpanContextValid,
9
- trace,
10
- TextMapGetter,
11
- TextMapPropagator,
12
- TextMapSetter,
13
- TraceFlags,
14
- createContextKey
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 {getRequestId} from "./tracing";
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
- 'B3 Debug Flag'
27
+ 'B3 Debug Flag'
28
28
  );
29
29
  export const B3_INFO_KEY = createContextKey(
30
- 'B3 Info Header'
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
- return Array.isArray(header) ? header[0] : header;
40
+ return Array.isArray(header) ? header[0] : header;
38
41
  }
39
42
 
40
43
  function getHeaderValue(carrier: unknown, getter: TextMapGetter, key: string) {
41
- const header = getter.get(carrier, key);
42
- return parseHeader(header);
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
- const traceId = getHeaderValue(carrier, getter, X_B3_TRACE_ID);
47
- if (typeof traceId === 'string') {
48
- return traceId.padStart(32, '0');
49
- }
50
- return '';
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
- const spanId = getHeaderValue(carrier, getter, X_B3_SPAN_ID);
55
- if (typeof spanId === 'string') {
56
- return spanId;
57
- }
58
- return 'aaaaaaaaaaaaaaaa'; //Valid dummy value as spanId will change when AwsLambdaInstrumentation is initialised
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
- const debug = getHeaderValue(carrier, getter, X_B3_FLAGS);
63
- return debug === '1' ? '1' : undefined;
77
+ const debug = getHeaderValue(carrier, getter, X_B3_FLAGS);
78
+ return debug === '1' ? '1' : undefined;
64
79
  }
65
80
 
66
81
  function getTraceFlags(
67
- carrier: unknown,
68
- getter: TextMapGetter
82
+ carrier: unknown,
83
+ getter: TextMapGetter
69
84
  ): TraceFlags | undefined {
70
- const traceFlags = getHeaderValue(carrier, getter, X_B3_SAMPLED);
71
- const debug = getDebug(carrier, getter);
72
- if (debug === '1' || VALID_SAMPLED_VALUES.has(traceFlags)) {
73
- return TraceFlags.SAMPLED;
74
- }
75
- if (traceFlags === undefined || VALID_UNSAMPLED_VALUES.has(traceFlags)) {
76
- return TraceFlags.NONE;
77
- }
78
- // This indicates to isValidSampledValue that this is not valid
79
- return;
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
- const info = getHeaderValue(carrier, getter, X_B3_INFO);
84
- if (typeof info === 'string') {
85
- return info;
86
- }
87
- return undefined;
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
- inject(context: Context, carrier: any, setter: TextMapSetter<any>): void {
92
- const spanContext = trace.getSpanContext(context);
93
- if (
94
- !spanContext ||
95
- !isSpanContextValid(spanContext) ||
96
- isTracingSuppressed(context)
97
- )
98
- return;
99
-
100
- const debug = context.getValue(B3_DEBUG_FLAG_KEY);
101
- setter.set(carrier, X_B3_TRACE_ID, spanContext.traceId);
102
- setter.set(carrier, X_B3_SPAN_ID, spanContext.spanId);
103
- const info = context.getValue(B3_INFO_KEY);
104
- if (info && typeof info === 'string') {
105
- setter.set(carrier, X_B3_INFO, info.toString());
106
- } else if (getRequestId()) {
107
- setter.set(carrier, X_B3_INFO, `lambdaRequestId:${getRequestId()}`);
108
- }
109
- // According to the B3 spec, if the debug flag is set,
110
- // the sampled flag shouldn't be propagated as well.
111
- if (debug === '1') {
112
- setter.set(carrier, X_B3_FLAGS, debug);
113
- } else if (spanContext.traceFlags !== undefined) {
114
- // We set the header only if there is an existing sampling decision.
115
- // Otherwise we will omit it => Absent.
116
- setter.set(
117
- carrier,
118
- X_B3_SAMPLED,
119
- (TraceFlags.SAMPLED & spanContext.traceFlags) === TraceFlags.SAMPLED
120
- ? '1'
121
- : '0'
122
- );
123
- }
124
- }
125
-
126
- extract(context: Context, carrier: any, getter: TextMapGetter<any>): Context {
127
- const traceId = getTraceId(carrier, getter);
128
- const spanId = getSpanId(carrier, getter);
129
- const traceFlags = getTraceFlags(carrier, getter) as TraceFlags;
130
- const debug = getDebug(carrier, getter);
131
- const info = getInfo(carrier, getter);
132
-
133
- context = context.setValue(B3_DEBUG_FLAG_KEY, debug);
134
- if (info) {
135
- context = context.setValue(B3_INFO_KEY, info);
136
- }
137
- return trace.setSpanContext(context, {
138
- traceId,
139
- spanId,
140
- isRemote: true,
141
- traceFlags,
142
- });
143
- }
144
-
145
- fields(): string[] {
146
- return [
147
- X_B3_TRACE_ID,
148
- X_B3_SPAN_ID,
149
- X_B3_FLAGS,
150
- X_B3_SAMPLED,
151
- X_B3_PARENT_SPAN_ID,
152
- X_B3_INFO
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;
@@ -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 'aaaaaaaaaaaaaaaa'; //Valid dummy value as spanId will change when AwsLambdaInstrumentation is initialised
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
- setter.set(carrier, exports.X_B3_TRACE_ID, spanContext.traceId);
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 (info && typeof info === 'string') {
78
- setter.set(carrier, exports.X_B3_INFO, info.toString());
91
+ if ((0, tracing_1.getTraceInfoHeader)()) {
92
+ setter.set(carrier, exports.X_B3_INFO, (0, tracing_1.getTraceInfoHeader)());
79
93
  }
80
- else if ((0, tracing_1.getRequestId)()) {
81
- setter.set(carrier, exports.X_B3_INFO, `lambdaRequestId:${(0, tracing_1.getRequestId)()}`);
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 (infoHeader) {
39
- info = infoHeader.toString();
38
+ if ((0, tracing_1.getTraceInfoHeader)()) {
39
+ info = (0, tracing_1.getTraceInfoHeader)();
40
40
  }
41
- else if ((0, tracing_1.getRequestId)()) {
42
- info = `lambdaRequestId:${(0, tracing_1.getRequestId)()}`;
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
@@ -1,2 +1,3 @@
1
1
  export declare function initializeTracing(): void;
2
- export declare function getRequestId(): string;
2
+ export declare function getTraceInfoHeader(): string;
3
+ export declare function setTraceInfoHeader(info: string): void;
package/dist/tracing.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRequestId = exports.initializeTracing = void 0;
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 requestId;
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
- requestId = context.awsRequestId;
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 getRequestId() {
34
- return requestId;
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.getRequestId = getRequestId;
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 {getRequestId} from "./tracing";
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 (infoHeader) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uoa/lambda-tracing",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Library for logging & distributed tracing in UoA Lambda projects",
5
5
  "repository": {
6
6
  "type": "git",
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|lambdaRequestId:dc2f1b60-96af-4869-9b75-036f9ddcdb33|
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 32
109
- characters, it will be left padded with 0's to get to a length of 32.\
110
- If this header is not passed, it will be randomly generated.
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
- If this header is not passed, it will be set as `lambdaRequestId:requestId` where `requestId` is the id of the current lambda invocation.
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 requestId: string;
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
- requestId = context.awsRequestId;
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 getRequestId() {
33
- return requestId;
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
  }