in xray/segment.go [77:160]
func BeginSegmentWithSampling(ctx context.Context, name string, r *http.Request, traceHeader *header.Header) (context.Context, *Segment) {
// If SDK is disabled then return with an empty segment
if SdkDisabled() {
seg := &Segment{}
return context.WithValue(ctx, ContextKey, seg), seg
}
if dName := os.Getenv("AWS_XRAY_TRACING_NAME"); dName != "" {
name = dName
}
seg := basicSegment(name, nil)
cfg := GetRecorder(ctx)
seg.assignConfiguration(cfg)
seg.Lock()
defer seg.Unlock()
seg.addPlugin(plugins.InstancePluginMetadata)
seg.addSDKAndServiceInformation()
if seg.ParentSegment.GetConfiguration().ServiceVersion != "" {
seg.GetService().Version = seg.ParentSegment.GetConfiguration().ServiceVersion
}
if r == nil || traceHeader == nil {
// No header or request information provided so we can only evaluate sampling based on the serviceName
sd := seg.ParentSegment.GetConfiguration().SamplingStrategy.ShouldTrace(&sampling.Request{ServiceName: name})
seg.Sampled = sd.Sample
logger.Debugf("SamplingStrategy decided: %t", seg.Sampled)
seg.AddRuleName(sd)
} else {
// Sampling strategy for http calls
seg.Sampled = traceHeader.SamplingDecision == header.Sampled
switch traceHeader.SamplingDecision {
case header.Sampled:
logger.Debug("Incoming header decided: Sampled=true")
case header.NotSampled:
logger.Debug("Incoming header decided: Sampled=false")
}
if traceHeader.SamplingDecision != header.Sampled && traceHeader.SamplingDecision != header.NotSampled {
samplingRequest := &sampling.Request{
Host: r.Host,
URL: r.URL.Path,
Method: r.Method,
ServiceName: seg.Name,
ServiceType: plugins.InstancePluginMetadata.Origin,
}
sd := seg.ParentSegment.GetConfiguration().SamplingStrategy.ShouldTrace(samplingRequest)
seg.Sampled = sd.Sample
logger.Debugf("SamplingStrategy decided: %t", seg.Sampled)
seg.AddRuleName(sd)
}
}
// check whether segment is dummy or not based on sampling decision
if !seg.ParentSegment.Sampled {
seg.Dummy = true
}
// Dummy segments don't get sent and don't need a goroutine to cancel them.
if !seg.Dummy {
// Create a new context for to cancel segment.
// Start new goroutine to listen for segment close/cancel events.
// Cancel simply calls `segment.Close()`.
//
// This way, even if the client consumes the `ctx.Done()` event, the
// X-Ray SDK has a way of canceling (closing) the segment in the
// `segment.Close()` method using this new cancellation context.
ctx1, cancelCtx := context.WithCancel(ctx)
seg.cancelCtx = cancelCtx
go func() {
<-ctx1.Done()
seg.handleContextDone()
}()
}
// generates segment and trace id based on sampling decision and AWS_XRAY_NOOP_ID env variable
idGeneration(seg)
return context.WithValue(ctx, ContextKey, seg), seg
}