func BeginSegmentWithSampling()

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
}