// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package export import ( crand "crypto/rand" "encoding/binary" "fmt" "math/rand" "sync" "sync/atomic" ) type TraceID [16]byte type SpanID [8]byte func (t TraceID) String() string { return fmt.Sprintf("%02x", t[:]) } func (s SpanID) String() string { return fmt.Sprintf("%02x", s[:]) } func (s SpanID) IsValid() bool { return s != SpanID{} } var ( generationMu sync.Mutex nextSpanID uint64 spanIDInc uint64 traceIDAdd [2]uint64 traceIDRand *rand.Rand ) func initGenerator() { var rngSeed int64 for _, p := range []interface{}{ &rngSeed, &traceIDAdd, &nextSpanID, &spanIDInc, } { binary.Read(crand.Reader, binary.LittleEndian, p) } traceIDRand = rand.New(rand.NewSource(rngSeed)) spanIDInc |= 1 } func newTraceID() TraceID { generationMu.Lock() defer generationMu.Unlock() if traceIDRand == nil { initGenerator() } var tid [16]byte binary.LittleEndian.PutUint64(tid[0:8], traceIDRand.Uint64()+traceIDAdd[0]) binary.LittleEndian.PutUint64(tid[8:16], traceIDRand.Uint64()+traceIDAdd[1]) return tid } func newSpanID() SpanID { var id uint64 for id == 0 { id = atomic.AddUint64(&nextSpanID, spanIDInc) } var sid [8]byte binary.LittleEndian.PutUint64(sid[:], id) return sid }