github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/goid/traceid.go (about) 1 package goid 2 3 import ( 4 "net" 5 "os" 6 "sync/atomic" 7 8 "github.com/isyscore/isc-gobase/time" 9 ) 10 11 var seq uint64 = 0 12 var digits = []uint8{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} 13 14 const max = 8000 15 16 func GenerateTraceID() string { 17 buffer := make([]byte, 16) 18 19 // 计算当前session的咋一序号 20 atomic.AddUint64(&seq, 1) 21 current := seq 22 var next uint64 23 if current >= max { 24 next = 1 25 } else { 26 next = current + 1 27 } 28 seq = next 29 bs := shortToBytes(uint16(current)) 30 putBuffer(&buffer, bs, 0) 31 32 // 计算时间 33 t0 := time.TimeInMillis() 34 bt0 := int64ToBytes(t0) 35 putBuffer(&buffer, bt0, 2) 36 37 // 计算IP地址 38 addrs, _ := net.InterfaceAddrs() 39 for _, addr := range addrs { 40 if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { 41 if ipnet.IP.To4() != nil { 42 ip := ipnet.IP.To4() 43 putBuffer(&buffer, ip, 10) 44 break 45 } 46 } 47 } 48 49 // 计算PID 50 pid := os.Getpid() 51 bp := shortToBytes(uint16(pid)) 52 putBuffer(&buffer, bp, 14) 53 54 hex := encodeHex(buffer, digits) 55 56 return string(hex) 57 } 58 59 func putBuffer(buf *[]byte, b []byte, from int) { 60 idx := from 61 for _, e := range b { 62 (*buf)[idx] = e 63 idx++ 64 } 65 } 66 67 func shortToBytes(s uint16) []byte { 68 b := make([]byte, 2) 69 b[0] = byte(s >> 8) 70 b[1] = byte(s) 71 return b 72 } 73 74 func int64ToBytes(i int64) []byte { 75 b := make([]byte, 8) 76 b[0] = byte(i >> 56) 77 b[1] = byte(i >> 48) 78 b[2] = byte(i >> 40) 79 b[3] = byte(i >> 32) 80 b[4] = byte(i >> 24) 81 b[5] = byte(i >> 16) 82 b[6] = byte(i >> 8) 83 b[7] = byte(i) 84 return b 85 } 86 87 func encodeHex(data []byte, dig []uint8) []uint8 { 88 l := len(data) 89 out := make([]uint8, l<<1) 90 var j = 0 91 for i := 0; i < l; i++ { 92 out[j] = dig[(0xf0&data[i])>>4] 93 j++ 94 out[j] = dig[0x0f&data[i]] 95 j++ 96 } 97 return out 98 }