| package trace |
|
|
| import ( |
| "fmt" |
| "net" |
| "os" |
| "sync" |
| "sync/atomic" |
| "time" |
|
|
| "github.com/GoAdminGroup/go-admin/context" |
| ) |
|
|
| var ( |
| machineIDOnce sync.Once |
| machineID string |
| counter uint32 |
| ) |
|
|
| func getMachineID() string { |
| machineIDOnce.Do(func() { |
| addrs, err := net.InterfaceAddrs() |
| if err == nil { |
| for _, addr := range addrs { |
| if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() { |
| if ipNet.IP.To4() != nil { |
| machineID = ipNet.IP.String() |
| break |
| } |
| } |
| } |
| } |
|
|
| if machineID == "" { |
| machineID = "127.0.0.1" |
| } |
| }) |
|
|
| return machineID |
| } |
|
|
| func GenerateTraceID() string { |
| machineID := getMachineID() |
| timestamp := time.Now().UnixNano() / int64(time.Millisecond) |
| processID := os.Getpid() |
| id := atomic.AddUint32(&counter, 1) |
| id = id % 1000 |
| traceID := fmt.Sprintf("%08x%05d%013d%04d", machineIDToHex(machineID), processID, timestamp, id) |
|
|
| return traceID |
| } |
|
|
| func machineIDToHex(machineID string) uint32 { |
| ip := net.ParseIP(machineID) |
| ipUint32 := uint32(ip[12])<<24 | uint32(ip[13])<<16 | uint32(ip[14])<<8 | uint32(ip[15]) |
| return ipUint32 |
| } |
|
|
| func GetTraceID(ctx *context.Context) string { |
| traceID, ok := ctx.GetUserValue(TraceIDKey).(string) |
| if !ok { |
| return "" |
| } |
| return traceID |
| } |
|
|
| const ( |
| TraceIDKey = "traceID" |
| ) |
|
|