func (t *tracer) newSpan() *span {
	sp := t.spanPool.Get().(*span)
	sp.context = spanContext{}
	sp.duration = -1
	sp.tracer = nil
	sp.tags = nil
	sp.logs = nil
	sp.prefix = nil
	return sp
}
newSpan retrieves an instance of a clean Span object.
package core
import (
	"io"
	"math/rand"
	"os"
	"sync"
	"time"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
)
type Tracer interface {
	opentracing.Tracer
	StartSpanWithOptions(string, opentracing.StartSpanOptions) opentracing.Span
}
type tracer struct {
	options TracerOptions
	SpanReporter
	spanPool *sync.Pool
	rng      *rand.Rand
	sync.Mutex
	textMapPropagator     *textMapPropagator
	httpHeadersPropagator *textMapPropagator
}
type TracerOptions struct {
	MultiEvent bool
	Writer io.Writer
	ServiceName string
	DebugAssertSingleGoroutine bool
	DebugAssertUseAfterFinish bool
}
func New() Tracer {
	return NewWithOptions(TracerOptions{
		MultiEvent: true,
		Writer:     nil,
	})
}
func NewWithOptions(opts TracerOptions) Tracer {
	if opts.Writer == nil {
		opts.Writer = os.Stdout
	}
	if opts.ServiceName == "" {
		opts.ServiceName = os.Getenv("CTRACE_SERVICE_NAME")
	}
	return &tracer{
		options:               opts,
		SpanReporter:          NewSpanReporter(opts.Writer, NewSpanEncoder()),
		spanPool:              &sync.Pool{New: func() interface{} { return &span{} }},
		rng:                   rand.New(rand.NewSource(time.Now().UnixNano())),
		textMapPropagator:     newTextMapPropagator(),
		httpHeadersPropagator: newHTTPHeadersPropagator(),
	}
}
func (t *tracer) StartSpan(
	operationName string,
	opts ...opentracing.StartSpanOption,
) opentracing.Span {
	sso := opentracing.StartSpanOptions{}
	for _, o := range opts {
		o.Apply(&sso)
	}
	return t.StartSpanWithOptions(operationName, sso)
}
func (t *tracer) StartSpanWithOptions(
	operationName string,
	opts opentracing.StartSpanOptions,
) opentracing.Span {
	sp := t.newSpan()
	startTime := opts.StartTime
	if startTime.IsZero() {
		startTime = time.Now()
	}
	sp.tracer = t
	sp.start = startTime
	sp.operation = operationName
	sp.tags = opts.Tags
	if t.options.ServiceName != "" {
		sp.setTag("service", t.options.ServiceName)
	}
	sp.logs = make([]opentracing.LogRecord, 0, 10)
	sp.logs = append(sp.logs, opentracing.LogRecord{
		Timestamp: startTime,
		Fields:    []log.Field{log.String("event", "Start-Span")},
	})
	if t.options.DebugAssertSingleGoroutine {
		sp.setTag(debugGoroutineIDTag, curGoroutineID())
	}
	for _, ref := range opts.References {
		if ref.ReferencedContext == nil {
			continue
		}
		refCtx := ref.ReferencedContext.(spanContext)
		sp.context.traceID = refCtx.traceID
		sp.context.spanID = t.randomID()
		sp.parentID = refCtx.spanID
		if l := len(refCtx.baggage); l > 0 {
			sp.context.baggage = make(map[string]string, l)
			for k, v := range refCtx.baggage {
				sp.context.baggage[k] = v
			}
		}
		break
	}
	if sp.context.traceID == 0 {
		sp.context.traceID = t.randomID()
		sp.context.spanID = sp.context.traceID
	}
	if t.options.MultiEvent {
		t.Report(sp)
	}
	return sp
}
func (t *tracer) Inject(sc opentracing.SpanContext, format interface{}, carrier interface{}) error {
	switch format {
	case opentracing.TextMap:
		return t.textMapPropagator.Inject(sc, carrier)
	case opentracing.HTTPHeaders:
		return t.httpHeadersPropagator.Inject(sc, carrier)
	case opentracing.Binary:
		return opentracing.ErrUnsupportedFormat
	}
	return opentracing.ErrUnsupportedFormat
}
func (t *tracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
	switch format {
	case opentracing.TextMap:
		return t.textMapPropagator.Extract(carrier)
	case opentracing.HTTPHeaders:
		return t.httpHeadersPropagator.Extract(carrier)
	case opentracing.Binary:
		return nil, opentracing.ErrUnsupportedFormat
	}
	return nil, opentracing.ErrUnsupportedFormat
}