in xray/segment.go [264:333]
func BeginSubsegment(ctx context.Context, name string) (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 len(name) > 200 {
name = name[:200]
}
var parent *Segment
// first time to create facade segment
if getTraceHeaderFromContext(ctx) != nil && GetSegment(ctx) == nil {
_, parent = newFacadeSegment(ctx)
} else {
parent = GetSegment(ctx)
if parent == nil {
cfg := GetRecorder(ctx)
failedMessage := fmt.Sprintf("failed to begin subsegment named '%v': segment cannot be found.", name)
if cfg != nil && cfg.ContextMissingStrategy != nil {
cfg.ContextMissingStrategy.ContextMissing(failedMessage)
} else {
globalCfg.ContextMissingStrategy().ContextMissing(failedMessage)
}
return ctx, nil
}
}
seg := &Segment{parent: parent}
logger.Debugf("Beginning subsegment named %s", name)
seg.Lock()
defer seg.Unlock()
seg.ParentSegment = parent.ParentSegment
// generates subsegment id based on sampling decision and AWS_XRAY_NOOP_ID env variable
noOpID := os.Getenv("AWS_XRAY_NOOP_ID")
if noOpID != "" && strings.ToLower(noOpID) == "false" {
seg.ID = NewSegmentID()
} else {
if !seg.ParentSegment.Sampled {
seg.ID = noOpSegmentID()
} else {
seg.ID = NewSegmentID()
}
}
// check whether segment is dummy or not based on sampling decision
if !seg.ParentSegment.Sampled {
seg.Dummy = true
}
atomic.AddUint32(&seg.ParentSegment.totalSubSegments, 1)
parent.Lock()
parent.rawSubsegments = append(parent.rawSubsegments, seg)
parent.openSegments++
parent.Unlock()
seg.Name = name
seg.StartTime = float64(time.Now().UnixNano()) / float64(time.Second)
seg.InProgress = true
seg.Sampled = seg.ParentSegment.Sampled
seg.TraceID = seg.ParentSegment.TraceID
seg.ParentID = seg.ParentSegment.ID
return context.WithValue(ctx, ContextKey, seg), seg
}