github.com/matrixorigin/matrixone@v0.7.0/pkg/util/trace/config.go (about) 1 // Copyright The OpenTelemetry Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Portions of this file are additionally subject to the following 16 // copyright. 17 // 18 // Copyright (C) 2022 Matrix Origin. 19 // 20 // Modified the behavior and the interface of the step. 21 22 package trace 23 24 import ( 25 "bytes" 26 "context" 27 "encoding/hex" 28 "encoding/json" 29 "github.com/google/uuid" 30 "go.uber.org/zap" 31 "go.uber.org/zap/zapcore" 32 "io" 33 ) 34 35 type TraceID [16]byte 36 37 var NilTraceID TraceID 38 39 // IsZero checks whether the trace TraceID is 0 value. 40 func (t TraceID) IsZero() bool { 41 return bytes.Equal(t[:], NilTraceID[:]) 42 } 43 44 func (t TraceID) String() string { 45 if t.IsZero() { 46 return "0" 47 } 48 return uuid.UUID(t).String() 49 } 50 51 type SpanID [8]byte 52 53 var NilSpanID SpanID 54 55 // SetByUUID use prefix of uuid as value 56 func (s *SpanID) SetByUUID(id string) { 57 if u, err := uuid.Parse(id); err == nil { 58 copy(s[:], u[:]) 59 } else { 60 copy(s[:], []byte(id)[:]) 61 } 62 } 63 64 func (s *SpanID) IsZero() bool { 65 return bytes.Equal(s[:], NilSpanID[:]) 66 } 67 68 func (s SpanID) String() string { 69 if s.IsZero() { 70 return "0" 71 } 72 return hex.EncodeToString(s[:]) 73 } 74 75 var _ zapcore.ObjectMarshaler = (*SpanContext)(nil) 76 77 const SpanFieldKey = "span" 78 79 func SpanField(sc SpanContext) zap.Field { 80 return zap.Object(SpanFieldKey, &sc) 81 } 82 83 func IsSpanField(field zapcore.Field) bool { 84 return field.Key == SpanFieldKey 85 } 86 87 func ContextField(ctx context.Context) zap.Field { 88 return SpanField(SpanFromContext(ctx).SpanContext()) 89 } 90 91 // SpanContext contains identifying trace information about a Span. 92 type SpanContext struct { 93 TraceID TraceID `json:"trace_id"` 94 SpanID SpanID `json:"span_id"` 95 // Kind default SpanKindInternal 96 Kind SpanKind `json:"span_kind"` 97 } 98 99 func (c *SpanContext) Size() (n int) { 100 return 24 101 } 102 103 func (c *SpanContext) MarshalTo(dAtA []byte) (int, error) { 104 l := cap(dAtA) 105 if l < c.Size() { 106 return -1, io.ErrUnexpectedEOF 107 } 108 copy(dAtA, c.TraceID[:]) 109 copy(dAtA[16:], c.SpanID[:]) 110 return c.Size(), nil 111 } 112 113 // Unmarshal with default Kind: SpanKindRemote 114 func (c *SpanContext) Unmarshal(dAtA []byte) error { 115 l := cap(dAtA) 116 if l < c.Size() { 117 return io.ErrUnexpectedEOF 118 } 119 copy(c.TraceID[:], dAtA[0:16]) 120 copy(c.SpanID[:], dAtA[16:24]) 121 c.Kind = SpanKindRemote 122 return nil 123 } 124 125 func (c SpanContext) GetIDs() (TraceID, SpanID) { 126 return c.TraceID, c.SpanID 127 } 128 129 func (c *SpanContext) Reset() { 130 c.TraceID = NilTraceID 131 c.SpanID = NilSpanID 132 c.Kind = SpanKindInternal 133 } 134 135 func (c *SpanContext) IsEmpty() bool { 136 return c.TraceID.IsZero() && c.SpanID.IsZero() 137 } 138 139 // MarshalLogObject implement zapcore.ObjectMarshaler 140 func (c *SpanContext) MarshalLogObject(enc zapcore.ObjectEncoder) error { 141 if !c.TraceID.IsZero() { 142 enc.AddString("trace_id", c.TraceID.String()) 143 } 144 if !c.SpanID.IsZero() { 145 enc.AddString("span_id", c.SpanID.String()) 146 } 147 if c.Kind != SpanKindInternal { 148 enc.AddString("kind", c.Kind.String()) 149 } 150 return nil 151 } 152 153 func SpanContextWithID(id TraceID, kind SpanKind) SpanContext { 154 return SpanContext{TraceID: id, Kind: kind} 155 } 156 157 // SpanContextWithIDs with default Kind: SpanKindInternal 158 func SpanContextWithIDs(tid TraceID, sid SpanID) SpanContext { 159 return SpanContext{TraceID: tid, SpanID: sid, Kind: SpanKindInternal} 160 } 161 162 // SpanConfig is a group of options for a Span. 163 type SpanConfig struct { 164 SpanContext 165 166 // NewRoot identifies a Span as the root Span for a new trace. This is 167 // commonly used when an existing trace crosses trust boundaries and the 168 // remote parent span context should be ignored for security. 169 NewRoot bool `json:"NewRoot"` // WithNewRoot 170 Parent Span `json:"-"` 171 } 172 173 // SpanStartOption applies an option to a SpanConfig. These options are applicable 174 // only when the span is created. 175 type SpanStartOption interface { 176 ApplySpanStart(*SpanConfig) 177 } 178 179 type SpanEndOption interface { 180 ApplySpanEnd(*SpanConfig) 181 } 182 183 // SpanOption applies an option to a SpanConfig. 184 type SpanOption interface { 185 SpanStartOption 186 SpanEndOption 187 } 188 189 type spanOptionFunc func(*SpanConfig) 190 191 func (f spanOptionFunc) ApplySpanEnd(cfg *SpanConfig) { 192 f(cfg) 193 } 194 195 func (f spanOptionFunc) ApplySpanStart(cfg *SpanConfig) { 196 f(cfg) 197 } 198 199 func WithNewRoot(newRoot bool) spanOptionFunc { 200 return spanOptionFunc(func(cfg *SpanConfig) { 201 cfg.NewRoot = newRoot 202 }) 203 } 204 205 func WithKind(kind SpanKind) spanOptionFunc { 206 return spanOptionFunc(func(cfg *SpanConfig) { 207 cfg.Kind = kind 208 }) 209 } 210 211 type Resource struct { 212 m map[string]any 213 } 214 215 func NewResource() *Resource { 216 return &Resource{m: make(map[string]any)} 217 } 218 219 func (r *Resource) Put(key string, val any) { 220 r.m[key] = val 221 } 222 223 func (r *Resource) Get(key string) (any, bool) { 224 val, has := r.m[key] 225 return val, has 226 } 227 228 // String need to improve 229 func (r *Resource) String() string { 230 buf, _ := json.Marshal(r.m) 231 return string(buf) 232 233 } 234 235 const NodeTypeStandalone = "Standalone" 236 237 type MONodeResource struct { 238 NodeUuid string `json:"node_uuid"` 239 NodeType string `json:"node_type"` 240 } 241 242 // SpanKind is the role a Span plays in a Trace. 243 type SpanKind int 244 245 const ( 246 // SpanKindInternal is a SpanKind for a Span that represents an internal 247 // operation within MO. 248 SpanKindInternal SpanKind = 0 249 // SpanKindStatement is a SpanKind for a Span that represents the operation 250 // belong to statement query 251 SpanKindStatement SpanKind = 1 252 // SpanKindRemote is a SpanKind for a Span that represents the operation 253 // cross rpc 254 SpanKindRemote SpanKind = 2 255 // SpanKindSession is a SpanKind for a Span that represents the operation 256 // start from session 257 SpanKindSession SpanKind = 3 258 ) 259 260 func (k SpanKind) String() string { 261 switch k { 262 case SpanKindInternal: 263 return "internal" 264 case SpanKindStatement: 265 return "statement" 266 case SpanKindRemote: 267 return "remote" 268 case SpanKindSession: 269 return "session" 270 default: 271 return "unknown" 272 } 273 } 274 275 // TracerConfig is a group of options for a Tracer. 276 type TracerConfig struct { 277 Name string 278 } 279 280 // TracerOption applies an option to a TracerConfig. 281 type TracerOption interface { 282 Apply(*TracerConfig) 283 } 284 285 var _ TracerOption = tracerOptionFunc(nil) 286 287 type tracerOptionFunc func(*TracerConfig) 288 289 func (f tracerOptionFunc) Apply(cfg *TracerConfig) { 290 f(cfg) 291 } 292 293 const ( 294 // FlagsSampled is a bitmask with the sampled bit set. A SpanContext 295 // with the sampling bit set means the span is sampled. 296 FlagsSampled = TraceFlags(0x01) 297 ) 298 299 // TraceFlags contains flags that can be set on a SpanContext. 300 type TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`. 301 302 // IsSampled returns if the sampling bit is set in the TraceFlags. 303 func (tf TraceFlags) IsSampled() bool { 304 return tf&FlagsSampled == FlagsSampled 305 } 306 307 // WithSampled sets the sampling bit in a new copy of the TraceFlags. 308 func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive // sampled is not a control flag. 309 if sampled { 310 return tf | FlagsSampled 311 } 312 313 return tf &^ FlagsSampled 314 } 315 316 // String returns the hex string representation form of TraceFlags. 317 func (tf TraceFlags) String() string { 318 return hex.EncodeToString([]byte{byte(tf)}[:]) 319 }