-
Notifications
You must be signed in to change notification settings - Fork 157
/
Copy pathcontext_utils.js
224 lines (188 loc) · 7.63 KB
/
context_utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/**
* @module context_utils
*/
var cls = require('cls-hooked/context');
var logger = require('./logger');
var Segment = require('./segments/segment');
var Subsegment = require('./segments/attributes/subsegment');
var cls_mode = true;
var NAMESPACE ='AWSXRay';
var SEGMENT = 'segment';
var contextOverride = false;
var contextUtils = {
CONTEXT_MISSING_STRATEGY: {
RUNTIME_ERROR: {
contextMissing: function contextMissingRuntimeError(message) {
throw new Error(message);
}
},
LOG_ERROR: {
contextMissing: function contextMissingLogError(message) {
var err = new Error(message);
logger.getLogger().error(err.stack);
}
},
IGNORE_ERROR: {
contextMissing: function contextMissingIgnoreError() {
}
}
},
contextMissingStrategy: {},
/**
* Resolves the segment or subsegment given manual mode and params on the call required.
* @param [Segment|Subsegment] segment - The segment manually provided via params.XraySegment, if provided.
* @returns {Segment|Subsegment}
* @alias module:context_utils.resolveManualSegmentParams
*/
resolveManualSegmentParams: function resolveManualSegmentParams(params) {
if (params && !contextUtils.isAutomaticMode()) {
var xraySegment = params.XRaySegment || params.XraySegment;
var segment = params.Segment;
var found = null;
if (xraySegment && (xraySegment instanceof Segment || xraySegment instanceof Subsegment)) {
found = xraySegment;
delete params.XRaySegment;
delete params.XraySegment;
} else if (segment && (segment instanceof Segment || segment instanceof Subsegment)) {
found = segment;
delete params.Segment;
}
return found;
}
},
/**
* Gets current CLS namespace for X-Ray SDK or creates one if absent.
* @returns {Namespace}
* @alias module:context_utils.getNamespace
*/
getNamespace: function getNamespace() {
return cls.getNamespace(NAMESPACE) || cls.createNamespace(NAMESPACE);
},
/**
* Resolves the segment or subsegment given manual or automatic mode.
* @param [Segment|Subsegment] segment - The segment manually provided, if provided.
* @returns {Segment|Subsegment}
* @alias module:context_utils.resolveSegment
*/
resolveSegment: function resolveSegment(segment) {
if (cls_mode) {
return this.getSegment();
} else if (segment && !cls_mode) {
return segment;
} else if (!segment && !cls_mode) {
contextUtils.contextMissingStrategy.contextMissing('No sub/segment specified. A sub/segment must be provided for manual mode.');
}
},
/**
* Returns the current segment or subsegment. For use with in automatic mode only.
* @returns {Segment|Subsegment}
* @alias module:context_utils.getSegment
*/
getSegment: function getSegment() {
if (cls_mode) {
var segment = contextUtils.getNamespace(NAMESPACE).get(SEGMENT);
if (!segment) {
contextUtils.contextMissingStrategy.contextMissing('Failed to get the current sub/segment from the context.');
} else if (segment instanceof Segment && process.env.LAMBDA_TASK_ROOT && segment.facade == true) {
segment.resolveLambdaTraceData();
}
return segment;
} else {
contextUtils.contextMissingStrategy.contextMissing('Cannot get sub/segment from context. Not supported in manual mode.');
}
},
/**
* Sets the current segment or subsegment. For use with in automatic mode only.
* @param [Segment|Subsegment] segment - The sub/segment to set.
* @returns {Segment|Subsegment}
* @alias module:context_utils.setSegment
*/
setSegment: function setSegment(segment) {
if (cls_mode) {
if (!contextUtils.getNamespace(NAMESPACE).set(SEGMENT, segment)) {
logger.getLogger().warn('Failed to set the current sub/segment on the context.');
}
} else {
contextUtils.contextMissingStrategy.contextMissing('Cannot set sub/segment on context. Not supported in manual mode.');
}
},
/**
* Returns true if in automatic mode, otherwise false.
* @returns {Segment|Subsegment}
* @alias module:context_utils.isAutomaticMode
*/
isAutomaticMode: function isAutomaticMode() {
return cls_mode;
},
/**
* Enables automatic mode. Automatic mode uses 'cls-hooked'.
* @see https://github.com/jeff-lewis/cls-hooked
* @alias module:context_utils.enableAutomaticMode
*/
enableAutomaticMode: function enableAutomaticMode() {
cls_mode = true;
contextUtils.getNamespace(NAMESPACE);
logger.getLogger().debug('Overriding AWS X-Ray SDK mode. Set to automatic mode.');
},
/**
* Disables automatic mode. Current segment or subsegment then must be passed manually
* via the parent optional on captureFunc, captureAsyncFunc etc.
* @alias module:context_utils.enableManualMode
*/
enableManualMode: function enableManualMode() {
cls_mode = false;
if (cls.getNamespace(NAMESPACE)) {
cls.destroyNamespace(NAMESPACE);
}
logger.getLogger().debug('Overriding AWS X-Ray SDK mode. Set to manual mode.');
},
/**
* Sets the context missing strategy if no context missing strategy is set using the environment variable with
* key AWS_XRAY_CONTEXT_MISSING. The context missing strategy's contextMissing function will be called whenever
* trace context is not found.
* @param {string|function} strategy - The strategy to set. Valid string values are 'LOG_ERROR' and 'RUNTIME_ERROR'.
* Alternatively, a custom function can be supplied, which takes a error message string.
*/
setContextMissingStrategy: function setContextMissingStrategy(strategy) {
if (!contextOverride) {
if (typeof strategy === 'string') {
var lookupStrategy = contextUtils.CONTEXT_MISSING_STRATEGY[strategy.toUpperCase()];
if (lookupStrategy) {
contextUtils.contextMissingStrategy.contextMissing = lookupStrategy.contextMissing;
if (process.env.AWS_XRAY_CONTEXT_MISSING) {
logger.getLogger().debug('AWS_XRAY_CONTEXT_MISSING is set. Configured context missing strategy to ' +
process.env.AWS_XRAY_CONTEXT_MISSING + '.');
} else {
logger.getLogger().debug('Configured context missing strategy to: ' + strategy);
}
} else {
throw new Error('Invalid context missing strategy: ' + strategy + '. Valid values are ' +
Object.keys(contextUtils.CONTEXT_MISSING_STRATEGY) + '.');
}
} else if (typeof strategy === 'function') {
contextUtils.contextMissingStrategy.contextMissing = strategy;
logger.getLogger().info('Configured custom context missing strategy to function: ' + strategy.name);
} else {
throw new Error('Context missing strategy must be either a string or a custom function.');
}
} else {
logger.getLogger().warn('Ignoring call to setContextMissingStrategy as AWS_XRAY_CONTEXT_MISSING is set. ' +
'The current context missing strategy will not be changed.');
}
}
};
if (process.env.AWS_XRAY_MANUAL_MODE) {
cls_mode = false;
logger.getLogger().debug('Starting the AWS X-Ray SDK in manual mode.');
} else {
cls.createNamespace(NAMESPACE);
logger.getLogger().debug('Starting the AWS X-Ray SDK in automatic mode (default).');
}
if (process.env.AWS_XRAY_CONTEXT_MISSING) {
contextUtils.setContextMissingStrategy(process.env.AWS_XRAY_CONTEXT_MISSING);
contextOverride = true;
} else {
contextUtils.contextMissingStrategy.contextMissing = contextUtils.CONTEXT_MISSING_STRATEGY.LOG_ERROR.contextMissing;
logger.getLogger().debug('Using default context missing strategy: LOG_ERROR');
}
module.exports = contextUtils;