pkg/rules/otel-sdk/trace-context/otel_trace_context.go (132 lines of code) (raw):

//go:build ignore // Copyright (c) 2024 Alibaba Group Holding Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package trace_context import ( "fmt" trace "go.opentelemetry.io/otel/trace" ) const maxSpans = 300 type traceContext struct { sw *spanWrapper n int lcs trace.Span } type spanWrapper struct { span trace.Span prev *spanWrapper } func (tc *traceContext) size() int { return tc.n } func (tc *traceContext) add(span trace.Span) bool { if tc.n > 0 { if tc.n >= maxSpans { return false } } wrapper := &spanWrapper{span, tc.sw} // local root span if tc.n == 0 { tc.lcs = span } tc.sw = wrapper tc.n++ return true } //go:norace func (tc *traceContext) tail() trace.Span { if tc.n == 0 { return nil } else { return tc.sw.span } } func (tc *traceContext) localRootSpan() trace.Span { if tc.n == 0 { return nil } else { return tc.lcs } } func (tc *traceContext) del(span trace.Span) { if tc.n == 0 { return } addr := &tc.sw cur := tc.sw for cur != nil { sc1 := cur.span.SpanContext() sc2 := span.SpanContext() if sc1.TraceID() == sc2.TraceID() && sc1.SpanID() == sc2.SpanID() { *addr = cur.prev tc.n-- break } addr = &cur.prev cur = cur.prev } } func (tc *traceContext) clear() { tc.sw = nil tc.n = 0 SetBaggageContainerToGLS(nil) } //go:norace func (tc *traceContext) TakeSnapShot() interface{} { // take a deep copy to avoid reading & writing the same map at the same time if tc.n == 0 { return &traceContext{nil, 0, nil} } last := tc.tail() sw := &spanWrapper{last, nil} return &traceContext{sw, 1, nil} } func GetGLocalData(key string) interface{} { //todo set key into traceContext struct //t := getOrInitTraceContext() return nil } func SetGLocalData(key string, value interface{}) { t := getOrInitTraceContext() setTraceContext(t) } func getOrInitTraceContext() *traceContext { tc := GetTraceContextFromGLS() if tc == nil { newTc := &traceContext{nil, 0, nil} setTraceContext(newTc) return newTc } else { return tc.(*traceContext) } } func setTraceContext(tc *traceContext) { SetTraceContextToGLS(tc) } func traceContextAddSpan(span trace.Span) { tc := getOrInitTraceContext() if !tc.add(span) { fmt.Println("Failed to add span to TraceContext") } } func GetTraceAndSpanId() (string, string) { tc := GetTraceContextFromGLS() if tc == nil || tc.(*traceContext).tail() == nil { return "", "" } ctx := tc.(*traceContext).tail().SpanContext() return ctx.TraceID().String(), ctx.SpanID().String() } func traceContextDelSpan(span trace.Span) { ctx := getOrInitTraceContext() ctx.del(span) } func clearTraceContext() { getOrInitTraceContext().clear() } func SpanFromGLS() trace.Span { gls := GetTraceContextFromGLS() if gls == nil { return nil } return gls.(*traceContext).tail() } func LocalRootSpanFromGLS() trace.Span { gls := GetTraceContextFromGLS() if gls == nil { return nil } return gls.(*traceContext).lcs }