@@ -36,7 +36,13 @@ module.exports.init = function init() {
36
36
37
37
var namespace = contextUtils . getNamespace ( ) ;
38
38
namespace . enter ( namespace . createContext ( ) ) ;
39
- contextUtils . setSegment ( facadeSegment ( ) ) ;
39
+
40
+ if ( LambdaUtils . validTraceData ( process . env . _X_AMZN_TRACE_ID ) ) {
41
+ contextUtils . setSegment ( facadeSegment ( ) ) ;
42
+ }
43
+ else {
44
+ contextUtils . setSegment ( noOpSegment ( ) ) ;
45
+ }
40
46
} ;
41
47
42
48
var facadeSegment = function facadeSegment ( ) {
@@ -109,3 +115,74 @@ var facadeSegment = function facadeSegment() {
109
115
110
116
return segment ;
111
117
} ;
118
+
119
+ var noOpSegment = function noOpSegment ( ) {
120
+ var segment = new Segment ( 'no-op' ) ;
121
+ var whitelistFcn = [ ] ;
122
+ var silentFcn = [ 'addNewSubsegment' , 'addSubsegment' , 'removeSubsegment' , 'toString' , 'addSubsegmentWithoutSampling' , 'addNewSubsegmentWithoutSampling' , 'incrementCounter' , 'decrementCounter' , 'isClosed' , 'close' , 'format' , 'flush' ] ;
123
+ var xAmznTraceId = process . env . _X_AMZN_TRACE_ID ;
124
+
125
+ for ( var key in segment ) {
126
+ if ( typeof segment [ key ] === 'function' && whitelistFcn . indexOf ( key ) === - 1 ) {
127
+ if ( silentFcn . indexOf ( key ) === - 1 ) {
128
+ segment [ key ] = ( function ( ) {
129
+ var func = key ;
130
+ return function noOp ( ) {
131
+ logger . getLogger ( ) . warn ( 'Function "' + func + '" cannot be called on an AWS Lambda segment. Please use a subsegment to record data.' ) ;
132
+ return ;
133
+ } ;
134
+ } ) ( ) ;
135
+ } else {
136
+ segment [ key ] = function noOp ( ) {
137
+ return ;
138
+ } ;
139
+ }
140
+ }
141
+ }
142
+
143
+ segment . trace_id = TraceID . Invalid ( ) . toString ( ) ;
144
+ segment . isClosed = function ( ) {
145
+ return true ;
146
+ } ;
147
+ segment . in_progress = false ;
148
+ segment . counter = 1 ;
149
+ segment . notTraced = true ;
150
+ segment . noOp = true ;
151
+
152
+ segment . reset = function reset ( ) {
153
+ this . trace_id = TraceID . Invalid ( ) . toString ( ) ;
154
+ this . id = '00000000' ;
155
+ delete this . subsegments ;
156
+ this . notTraced = true ;
157
+ } ;
158
+
159
+ segment . resolveLambdaTraceData = function resolveLambdaTraceData ( ) {
160
+ var xAmznLambda = process . env . _X_AMZN_TRACE_ID ;
161
+
162
+ if ( xAmznLambda ) {
163
+
164
+ // This check resets the trace data whenever a new trace header is read to not leak data between invocations
165
+ if ( xAmznLambda != xAmznTraceIdPrev ) {
166
+ this . reset ( ) ;
167
+
168
+ if ( LambdaUtils . populateTraceData ( segment , xAmznLambda ) ) {
169
+ xAmznTraceIdPrev = xAmznLambda ;
170
+ }
171
+ }
172
+ } else {
173
+ this . reset ( ) ;
174
+ contextUtils . contextMissingStrategy . contextMissing ( 'Missing AWS Lambda trace data for X-Ray. ' +
175
+ 'Ensure Active Tracing is enabled and no subsegments are created outside the function handler.' ) ;
176
+ }
177
+ } ;
178
+
179
+ // Test for valid trace data during SDK startup. It's likely we're still in the cold-start portion of the
180
+ // code at this point and a valid trace header has not been set
181
+ if ( LambdaUtils . validTraceData ( xAmznTraceId ) ) {
182
+ if ( LambdaUtils . populateTraceData ( segment , xAmznTraceId ) ) {
183
+ xAmznTraceIdPrev = xAmznTraceId ;
184
+ }
185
+ }
186
+
187
+ return segment ;
188
+ } ;
0 commit comments