func (seg *Segment) RemoveSubsegment(remove *Segment) bool {
	seg.Lock()
	for i, v := range seg.rawSubsegments {
		if v == remove {
			seg.rawSubsegments[i] = seg.rawSubsegments[len(seg.rawSubsegments)-1]
			seg.rawSubsegments[len(seg.rawSubsegments)-1] = nil
			seg.rawSubsegments = seg.rawSubsegments[:len(seg.rawSubsegments)-1]
			seg.openSegments--
			if seg.ParentSegment != seg {
				seg.Unlock()
				atomic.AddUint32(&seg.ParentSegment.totalSubSegments, ^uint32(0))
			} else {
				seg.Unlock()
			}
			return true
		}
	}
	seg.Unlock()
	return false
}
RemoveSubsegment removes a subsegment child from a segment or subsegment.
package xray
import (
	"context"
	"crypto/rand"
	"fmt"
	"net/http"
	"os"
	"runtime"
	"strings"
	"sync/atomic"
	"time"
	"github.com/aws/aws-xray-sdk-go/header"
	"github.com/aws/aws-xray-sdk-go/internal/logger"
	"github.com/aws/aws-xray-sdk-go/internal/plugins"
	"github.com/aws/aws-xray-sdk-go/strategy/sampling"
)
func NewTraceID() string {
	var r [12]byte
	_, err := rand.Read(r[:])
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("1-%08x-%02x", time.Now().Unix(), r)
}
func NewSegmentID() string {
	var r [8]byte
	_, err := rand.Read(r[:])
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%02x", r)
}
func noOpTraceID() string {
	return "1-00000000-000000000000000000000000"
}
func noOpSegmentID() string {
	return "0000000000000000"
}
func BeginFacadeSegment(ctx context.Context, name string, h *header.Header) (context.Context, *Segment) {
	seg := basicSegment(name, h)
	if h == nil {
		idGeneration(seg)
	}
	cfg := GetRecorder(ctx)
	seg.assignConfiguration(cfg)
	return context.WithValue(ctx, ContextKey, seg), seg
}
func BeginSegment(ctx context.Context, name string) (context.Context, *Segment) {
	return BeginSegmentWithSampling(ctx, name, nil, nil)
}
func BeginSegmentWithSampling(ctx context.Context, name string, r *http.Request, traceHeader *header.Header) (context.Context, *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 {
		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 {
		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)
		}
	}
	if ctx.Done() != nil {
		go func() {
			<-ctx.Done()
			seg.handleContextDone()
		}()
	}
	if !seg.ParentSegment.Sampled {
		seg.Dummy = true
	}
	idGeneration(seg)
	return context.WithValue(ctx, ContextKey, seg), seg
}
func idGeneration(seg *Segment) {
	noOpID := os.Getenv("AWS_XRAY_NOOP_ID")
	if noOpID != "" && strings.ToLower(noOpID) == "false" {
		seg.TraceID = NewTraceID()
		seg.ID = NewSegmentID()
	} else {
		if !seg.Sampled {
			seg.TraceID = noOpTraceID()
			seg.ID = noOpSegmentID()
		} else {
			seg.TraceID = NewTraceID()
			seg.ID = NewSegmentID()
		}
	}
}
func basicSegment(name string, h *header.Header) *Segment {
	if len(name) > 200 {
		name = name[:200]
	}
	seg := &Segment{parent: nil}
	logger.Debugf("Beginning segment named %s", name)
	seg.ParentSegment = seg
	seg.Lock()
	defer seg.Unlock()
	seg.Name = name
	seg.StartTime = float64(time.Now().UnixNano()) / float64(time.Second)
	seg.InProgress = true
	seg.Dummy = false
	if h == nil {
		seg.Sampled = true
	} else {
		seg.Facade = true
		seg.ID = h.ParentID
		seg.TraceID = h.TraceID
		seg.Sampled = h.SamplingDecision == header.Sampled
	}
	return seg
}
func (seg *Segment) assignConfiguration(cfg *Config) {
	seg.Lock()
	if cfg == nil {
		seg.GetConfiguration().ContextMissingStrategy = globalCfg.contextMissingStrategy
		seg.GetConfiguration().ExceptionFormattingStrategy = globalCfg.exceptionFormattingStrategy
		seg.GetConfiguration().SamplingStrategy = globalCfg.samplingStrategy
		seg.GetConfiguration().StreamingStrategy = globalCfg.streamingStrategy
		seg.GetConfiguration().Emitter = globalCfg.emitter
		seg.GetConfiguration().ServiceVersion = globalCfg.serviceVersion
	} else {
		if cfg.ContextMissingStrategy != nil {
			seg.GetConfiguration().ContextMissingStrategy = cfg.ContextMissingStrategy
		} else {
			seg.GetConfiguration().ContextMissingStrategy = globalCfg.contextMissingStrategy
		}
		if cfg.ExceptionFormattingStrategy != nil {
			seg.GetConfiguration().ExceptionFormattingStrategy = cfg.ExceptionFormattingStrategy
		} else {
			seg.GetConfiguration().ExceptionFormattingStrategy = globalCfg.exceptionFormattingStrategy
		}
		if cfg.SamplingStrategy != nil {
			seg.GetConfiguration().SamplingStrategy = cfg.SamplingStrategy
		} else {
			seg.GetConfiguration().SamplingStrategy = globalCfg.samplingStrategy
		}
		if cfg.StreamingStrategy != nil {
			seg.GetConfiguration().StreamingStrategy = cfg.StreamingStrategy
		} else {
			seg.GetConfiguration().StreamingStrategy = globalCfg.streamingStrategy
		}
		if cfg.Emitter != nil {
			seg.GetConfiguration().Emitter = cfg.Emitter
		} else {
			seg.GetConfiguration().Emitter = globalCfg.emitter
		}
		if cfg.ServiceVersion != "" {
			seg.GetConfiguration().ServiceVersion = cfg.ServiceVersion
		} else {
			seg.GetConfiguration().ServiceVersion = globalCfg.serviceVersion
		}
	}
	seg.Unlock()
}
func BeginSubsegment(ctx context.Context, name string) (context.Context, *Segment) {
	if SdkDisabled() {
		seg := &Segment{}
		return context.WithValue(ctx, ContextKey, seg), seg
	}
	if len(name) > 200 {
		name = name[:200]
	}
	var parent *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
	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()
		}
	}
	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
	return context.WithValue(ctx, ContextKey, seg), seg
}
func NewSegmentFromHeader(ctx context.Context, name string, r *http.Request, h *header.Header) (context.Context, *Segment) {
	con, seg := BeginSegmentWithSampling(ctx, name, r, h)
	if h.TraceID != "" {
		seg.TraceID = h.TraceID
	}
	if h.ParentID != "" {
		seg.ParentID = h.ParentID
	}
	seg.IncomingHeader = h
	seg.RequestWasTraced = true
	return con, seg
}
func SdkDisabled() bool {
	disableKey := os.Getenv("AWS_XRAY_SDK_DISABLED")
	return strings.ToLower(disableKey) == "true"
}
func (seg *Segment) Close(err error) {
	if SdkDisabled() {
		return
	}
	seg.Lock()
	if seg.parent != nil {
		logger.Debugf("Closing subsegment named %s", seg.Name)
	} else {
		logger.Debugf("Closing segment named %s", seg.Name)
	}
	seg.EndTime = float64(time.Now().UnixNano()) / float64(time.Second)
	seg.InProgress = false
	if err != nil {
		seg.addError(err)
	}
	if seg.Dummy {
		seg.Unlock()
		return
	}
	seg.Unlock()
	seg.send()
}
func (seg *Segment) CloseAndStream(err error) {
	if SdkDisabled() {
		return
	}
	seg.Lock()
	defer seg.Unlock()
	if seg.parent != nil {
		logger.Debugf("Ending subsegment named: %s", seg.Name)
		seg.EndTime = float64(time.Now().UnixNano()) / float64(time.Second)
		seg.InProgress = false
		seg.Emitted = true
		if seg.parent.RemoveSubsegment(seg) {
			logger.Debugf("Removing subsegment named: %s", seg.Name)
		}
	}
	if err != nil {
		seg.addError(err)
	}
	if seg.Dummy {
		return
	}
	seg.beforeEmitSubsegment(seg.parent)
	seg.emit()
}