-
Notifications
You must be signed in to change notification settings - Fork 20
/
session_id.go
64 lines (52 loc) · 1.21 KB
/
session_id.go
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
package pyroscope
import (
crand "crypto/rand"
"encoding/binary"
"encoding/hex"
"hash/fnv"
"math/rand"
"os"
"sync"
)
const sessionIDLabelName = "__session_id__"
type sessionID uint64
func (s sessionID) String() string {
var b [8]byte
binary.LittleEndian.PutUint64(b[:], uint64(s))
return hex.EncodeToString(b[:])
}
func newSessionID() sessionID { return globalSessionIDGenerator.newSessionID() }
var globalSessionIDGenerator = newSessionIDGenerator()
type sessionIDGenerator struct {
sync.Mutex
src *rand.Rand
}
func (gen *sessionIDGenerator) newSessionID() sessionID {
var b [8]byte
gen.Lock()
_, _ = gen.src.Read(b[:])
gen.Unlock()
return sessionID(binary.LittleEndian.Uint64(b[:]))
}
func newSessionIDGenerator() *sessionIDGenerator {
s, ok := sessionIDHostSeed()
if !ok {
s = sessionIDRandSeed()
}
return &sessionIDGenerator{src: rand.New(rand.NewSource(s))}
}
func sessionIDRandSeed() int64 {
var rndSeed int64
_ = binary.Read(crand.Reader, binary.LittleEndian, &rndSeed)
return rndSeed
}
var hostname = os.Hostname
func sessionIDHostSeed() (int64, bool) {
v, err := hostname()
if err != nil {
return 0, false
}
h := fnv.New64a()
_, _ = h.Write([]byte(v))
return int64(h.Sum64()), true
}