in xray/segment.go [77:152]
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
}
// create a new context to close it on segment close;
// this makes sure the closing of the segment won't affect the client's code, that uses the returned 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
}