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