File: idgenerator.go

package info (click to toggle)
golang-github-openzipkin-zipkin-go 0.1.5%2Bgit20190103.2fd7f4a-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 532 kB
  • sloc: makefile: 22
file content (116 lines) | stat: -rw-r--r-- 3,012 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
Package idgenerator contains several Span and Trace ID generators which can be
used by the Zipkin tracer. Additional third party generators can be plugged in
if they adhere to the IDGenerator interface.
*/
package idgenerator

import (
	"math/rand"
	"sync"
	"time"

	"github.com/openzipkin/zipkin-go/model"
)

var (
	seededIDGen = rand.New(rand.NewSource(time.Now().UnixNano()))
	// NewSource returns a new pseudo-random Source seeded with the given value.
	// Unlike the default Source used by top-level functions, this source is not
	// safe for concurrent use by multiple goroutines. Hence the need for a mutex.
	seededIDLock sync.Mutex
)

// IDGenerator interface can be used to provide the Zipkin Tracer with custom
// implementations to generate Span and Trace IDs.
type IDGenerator interface {
	SpanID(traceID model.TraceID) model.ID // Generates a new Span ID
	TraceID() model.TraceID                // Generates a new Trace ID
}

// NewRandom64 returns an ID Generator which can generate 64 bit trace and span
// id's
func NewRandom64() IDGenerator {
	return &randomID64{}
}

// NewRandom128 returns an ID Generator which can generate 128 bit trace and 64
// bit span id's
func NewRandom128() IDGenerator {
	return &randomID128{}
}

// NewRandomTimestamped generates 128 bit time sortable traceid's and 64 bit
// spanid's.
func NewRandomTimestamped() IDGenerator {
	return &randomTimestamped{}
}

// randomID64 can generate 64 bit traceid's and 64 bit spanid's.
type randomID64 struct{}

func (r *randomID64) TraceID() (id model.TraceID) {
	seededIDLock.Lock()
	id = model.TraceID{
		Low: uint64(seededIDGen.Int63()),
	}
	seededIDLock.Unlock()
	return
}

func (r *randomID64) SpanID(traceID model.TraceID) (id model.ID) {
	if !traceID.Empty() {
		return model.ID(traceID.Low)
	}
	seededIDLock.Lock()
	id = model.ID(seededIDGen.Int63())
	seededIDLock.Unlock()
	return
}

// randomID128 can generate 128 bit traceid's and 64 bit spanid's.
type randomID128 struct{}

func (r *randomID128) TraceID() (id model.TraceID) {
	seededIDLock.Lock()
	id = model.TraceID{
		High: uint64(seededIDGen.Int63()),
		Low:  uint64(seededIDGen.Int63()),
	}
	seededIDLock.Unlock()
	return
}

func (r *randomID128) SpanID(traceID model.TraceID) (id model.ID) {
	if !traceID.Empty() {
		return model.ID(traceID.Low)
	}
	seededIDLock.Lock()
	id = model.ID(seededIDGen.Int63())
	seededIDLock.Unlock()
	return
}

// randomTimestamped can generate 128 bit time sortable traceid's compatible
// with AWS X-Ray and 64 bit spanid's.
type randomTimestamped struct{}

func (t *randomTimestamped) TraceID() (id model.TraceID) {
	seededIDLock.Lock()
	id = model.TraceID{
		High: uint64(time.Now().Unix()<<32) + uint64(seededIDGen.Int31()),
		Low:  uint64(seededIDGen.Int63()),
	}
	seededIDLock.Unlock()
	return
}

func (t *randomTimestamped) SpanID(traceID model.TraceID) (id model.ID) {
	if !traceID.Empty() {
		return model.ID(traceID.Low)
	}
	seededIDLock.Lock()
	id = model.ID(seededIDGen.Int63())
	seededIDLock.Unlock()
	return
}