func BeginSegmentWithSampling()

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
}