| 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" | |
| ) | |