github.com/replit/upm@v0.0.0-20240423230255-9ce4fc3ea24c/internal/trace/spancontext.go (about) 1 /* 2 This SpanContext implements 3 [ddtrace.SpanContextW3C](https://github.com/DataDog/dd-trace-go/blob/49273dfcc871f3329614c40cd98116b6d44cdb12/ddtrace/ddtrace.go#L25) 4 , implementation is mostly based on 5 https://github.com/DataDog/dd-trace-go/blob/49273dfcc871f3329614c40cd98116b6d44cdb12/ddtrace/tracer/spancontext.go#L85 6 7 We have our own version because that one was made private. 8 */ 9 10 package trace 11 12 import ( 13 "encoding/binary" 14 "encoding/hex" 15 "errors" 16 "fmt" 17 "strconv" 18 "strings" 19 20 "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" 21 ) 22 23 type SpanContext struct { 24 traceID traceID 25 spanID uint64 26 } 27 28 type traceID [16]byte // traceID in big endian, i.e. <upper><lower> 29 30 var ErrSpanContextCorrupted = errors.New("span context corrupted") 31 32 func (c *SpanContext) TraceID128() string { 33 return c.traceID.HexEncoded() 34 } 35 36 func (c *SpanContext) TraceID128Bytes() [16]byte { 37 return c.traceID 38 } 39 40 func (c *SpanContext) TraceID() uint64 { 41 return c.traceID.Lower() 42 } 43 44 func (c *SpanContext) SpanID() uint64 { 45 return c.spanID 46 } 47 48 func (c *SpanContext) ForeachBaggageItem(handler func(k, v string) bool) { 49 } 50 51 func GetHexSpanID(c ddtrace.SpanContextW3C) string { 52 return fmt.Sprintf("%016x", c.SpanID()) 53 } 54 55 func GetHexTraceID(c ddtrace.SpanContextW3C) string { 56 return fmt.Sprintf("%032x", c.TraceID128Bytes()) 57 } 58 59 func (c *SpanContext) ParseTraceID(v string) error { 60 if len(v) > 32 { 61 v = v[len(v)-32:] 62 } 63 v = strings.TrimLeft(v, "0") 64 var err error 65 if len(v) <= 16 { // 64-bit trace id 66 var tid uint64 67 tid, err = strconv.ParseUint(v, 16, 64) 68 c.traceID.SetLower(tid) 69 } else { // 128-bit trace id 70 idUpper := v[:len(v)-16] 71 //nolint:errcheck 72 c.traceID.SetUpperFromHex(idUpper) 73 var l uint64 74 l, err = strconv.ParseUint(v[len(idUpper):], 16, 64) 75 c.traceID.SetLower(l) 76 } 77 if err != nil { 78 return ErrSpanContextCorrupted 79 } 80 return nil 81 } 82 83 func (c *SpanContext) ParseSpanID(v string) error { 84 var err error 85 c.spanID, err = strconv.ParseUint(v, 16, 64) 86 if err != nil { 87 return err 88 } 89 return nil 90 } 91 92 func (t *traceID) HexEncoded() string { 93 return hex.EncodeToString(t[:]) 94 } 95 96 func (t *traceID) Lower() uint64 { 97 return binary.BigEndian.Uint64(t[8:]) 98 } 99 100 func (t *traceID) Upper() uint64 { 101 return binary.BigEndian.Uint64(t[:8]) 102 } 103 104 func (t *traceID) SetLower(i uint64) { 105 binary.BigEndian.PutUint64(t[8:], i) 106 } 107 108 func (t *traceID) SetUpper(i uint64) { 109 binary.BigEndian.PutUint64(t[:8], i) 110 } 111 112 func (t *traceID) SetUpperFromHex(s string) error { 113 u, err := strconv.ParseUint(s, 16, 64) 114 if err != nil { 115 return fmt.Errorf("malformed %q: %s", s, err) 116 } 117 t.SetUpper(u) 118 return nil 119 }