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  }