context.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package lib
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "encoding/hex"
  6. "errors"
  7. "fmt"
  8. "github.com/gin-gonic/gin"
  9. "golang.org/x/net/context"
  10. "math/rand"
  11. "net"
  12. "os"
  13. "time"
  14. )
  15. var LocalIP = net.ParseIP("127.0.0.1")
  16. type Trace struct {
  17. TraceId string
  18. SpanId string
  19. Caller string
  20. SrcMethod string
  21. HintCode int64
  22. HintContent string
  23. }
  24. type TraceContext struct {
  25. Trace
  26. CSpanId string
  27. }
  28. func NewTrace() *TraceContext {
  29. trace := &TraceContext{}
  30. trace.TraceId = GetTraceId()
  31. trace.SpanId = NewSpanId()
  32. return trace
  33. }
  34. func NewSpanId() string {
  35. timestamp := uint32(time.Now().Unix())
  36. ipToLong := binary.BigEndian.Uint32(LocalIP.To4())
  37. b := bytes.Buffer{}
  38. b.WriteString(fmt.Sprintf("%08x", ipToLong^timestamp))
  39. b.WriteString(fmt.Sprintf("%08x", rand.Int31()))
  40. return b.String()
  41. }
  42. func GetTraceId() (traceId string) {
  43. return calcTraceId(LocalIP.String())
  44. }
  45. func calcTraceId(ip string) (traceId string) {
  46. now := time.Now()
  47. timestamp := uint32(now.Unix())
  48. timeNano := now.UnixNano()
  49. pid := os.Getpid()
  50. b := bytes.Buffer{}
  51. netIP := net.ParseIP(ip)
  52. if netIP == nil {
  53. b.WriteString("00000000")
  54. } else {
  55. b.WriteString(hex.EncodeToString(netIP.To4()))
  56. }
  57. b.WriteString(fmt.Sprintf("%08x", timestamp&0xffffffff))
  58. b.WriteString(fmt.Sprintf("%04x", timeNano&0xffff))
  59. b.WriteString(fmt.Sprintf("%04x", pid&0xffff))
  60. b.WriteString(fmt.Sprintf("%06x", rand.Int31n(1<<24)))
  61. b.WriteString("b0") // 末两位标记来源,b0为go
  62. return b.String()
  63. }
  64. func GetLocalIPs() (ips []net.IP) {
  65. interfaceAddr, err := net.InterfaceAddrs()
  66. if err != nil {
  67. return nil
  68. }
  69. for _, address := range interfaceAddr {
  70. ipNet, isValidIpNet := address.(*net.IPNet)
  71. if isValidIpNet && !ipNet.IP.IsLoopback() {
  72. if ipNet.IP.To4() != nil {
  73. ips = append(ips, ipNet.IP)
  74. }
  75. }
  76. }
  77. return ips
  78. }
  79. func SetGinTraceContext(c *gin.Context, trace *TraceContext) error {
  80. if trace == nil || c == nil {
  81. return errors.New("context is nil")
  82. }
  83. c.Set("trace", trace)
  84. return nil
  85. }
  86. func SetTraceContext(ctx context.Context, trace *TraceContext) context.Context {
  87. if trace == nil {
  88. return ctx
  89. }
  90. return context.WithValue(ctx, "trace", trace)
  91. }
  92. func GetTraceContext(ctx context.Context) *TraceContext {
  93. if ginCtx, ok := ctx.(*gin.Context); ok {
  94. traceIntraceContext, exists := ginCtx.Get("trace")
  95. if !exists {
  96. return NewTrace()
  97. }
  98. traceContext, ok := traceIntraceContext.(*TraceContext)
  99. if ok {
  100. return traceContext
  101. }
  102. return NewTrace()
  103. }
  104. if contextInterface, ok := ctx.(context.Context); ok {
  105. traceContext, ok := contextInterface.Value("trace").(*TraceContext)
  106. if ok {
  107. return traceContext
  108. }
  109. return NewTrace()
  110. }
  111. return NewTrace()
  112. }