1818import com .amazonaws .xray .AWSXRayRecorder ;
1919import com .amazonaws .xray .entities .Entity ;
2020import com .amazonaws .xray .entities .FacadeSegment ;
21+ import com .amazonaws .xray .entities .NoOpSegment ;
2122import com .amazonaws .xray .entities .Segment ;
2223import com .amazonaws .xray .entities .Subsegment ;
2324import com .amazonaws .xray .entities .SubsegmentImpl ;
2425import com .amazonaws .xray .entities .TraceHeader ;
25- import com .amazonaws .xray .entities .TraceHeader .SampleDecision ;
2626import com .amazonaws .xray .entities .TraceID ;
2727import com .amazonaws .xray .exceptions .SubsegmentNotFoundException ;
2828import com .amazonaws .xray .listeners .SegmentListener ;
@@ -35,40 +35,44 @@ public class LambdaSegmentContext implements SegmentContext {
3535 private static final Log logger = LogFactory .getLog (LambdaSegmentContext .class );
3636
3737 private static final String LAMBDA_TRACE_HEADER_KEY = "_X_AMZN_TRACE_ID" ;
38-
38+
3939 // See: https://github.com/aws/aws-xray-sdk-java/issues/251
4040 private static final String LAMBDA_TRACE_HEADER_PROP = "com.amazonaws.xray.traceHeader" ;
4141
4242 private static TraceHeader getTraceHeaderFromEnvironment () {
4343 String lambdaTraceHeaderKey = System .getenv (LAMBDA_TRACE_HEADER_KEY );
44- return TraceHeader .fromString (lambdaTraceHeaderKey != null && lambdaTraceHeaderKey .length () > 0
45- ? lambdaTraceHeaderKey
44+ return TraceHeader .fromString (lambdaTraceHeaderKey != null && lambdaTraceHeaderKey .length () > 0
45+ ? lambdaTraceHeaderKey
4646 : System .getProperty (LAMBDA_TRACE_HEADER_PROP ));
4747 }
4848
4949 private static boolean isInitializing (TraceHeader traceHeader ) {
5050 return traceHeader .getRootTraceId () == null || traceHeader .getSampled () == null || traceHeader .getParentId () == null ;
5151 }
5252
53- private static FacadeSegment newFacadeSegment (AWSXRayRecorder recorder , String name ) {
54- TraceHeader traceHeader = getTraceHeaderFromEnvironment ();
55- if (isInitializing (traceHeader )) {
56- logger .warn (LAMBDA_TRACE_HEADER_KEY + " is missing a trace ID, parent ID, or sampling decision. Subsegment "
57- + name + " discarded." );
58- return new FacadeSegment (recorder , TraceID .create (recorder ), "" , SampleDecision .NOT_SAMPLED );
59- }
60- return new FacadeSegment (recorder , traceHeader .getRootTraceId (), traceHeader .getParentId (), traceHeader .getSampled ());
61- }
62-
6353 @ Override
6454 public Subsegment beginSubsegment (AWSXRayRecorder recorder , String name ) {
6555 if (logger .isDebugEnabled ()) {
6656 logger .debug ("Beginning subsegment named: " + name );
6757 }
6858
59+ TraceHeader traceHeader = LambdaSegmentContext .getTraceHeaderFromEnvironment ();
6960 Entity entity = getTraceEntity ();
70- if (entity == null ) { // First subsgment of a subsegment branch.
71- Segment parentSegment = newFacadeSegment (recorder , name );
61+ if (entity == null ) { // First subsegment of a subsegment branch
62+ Segment parentSegment ;
63+ if (isInitializing (traceHeader )) {
64+ if (logger .isDebugEnabled ()) {
65+ logger .debug ("Creating No-Op parent segment" );
66+ }
67+ parentSegment = Segment .noOp (TraceID .create (recorder ), recorder );
68+ } else {
69+ parentSegment = new FacadeSegment (
70+ recorder ,
71+ traceHeader .getRootTraceId (),
72+ traceHeader .getParentId (),
73+ traceHeader .getSampled ()
74+ );
75+ }
7276
7377 boolean isRecording = parentSegment .isRecording ();
7478
@@ -145,6 +149,8 @@ public void endSubsegment(AWSXRayRecorder recorder) {
145149 current .getCreator ().getEmitter ().sendSubsegment ((Subsegment ) current );
146150 }
147151 clearTraceEntity ();
152+ } else if (parentEntity instanceof NoOpSegment ) {
153+ clearTraceEntity ();
148154 } else {
149155 setTraceEntity (current .getParent ());
150156 }
0 commit comments