@@ -36,7 +36,13 @@ module.exports.init = function init() {
3636
3737 var namespace = contextUtils . getNamespace ( ) ;
3838 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+ }
4046} ;
4147
4248var facadeSegment = function facadeSegment ( ) {
@@ -109,3 +115,74 @@ var facadeSegment = function facadeSegment() {
109115
110116 return segment ;
111117} ;
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