github.com/gogf/gf@v1.16.9/net/gtrace/gtrace.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 // Package gtrace provides convenience wrapping functionality for tracing feature using OpenTelemetry. 8 package gtrace 9 10 import ( 11 "context" 12 "github.com/gogf/gf/container/gmap" 13 "github.com/gogf/gf/container/gvar" 14 "github.com/gogf/gf/net/gipv4" 15 "github.com/gogf/gf/os/gcmd" 16 "go.opentelemetry.io/otel" 17 "go.opentelemetry.io/otel/attribute" 18 "go.opentelemetry.io/otel/propagation" 19 "go.opentelemetry.io/otel/trace" 20 "os" 21 "strings" 22 ) 23 24 const ( 25 tracingCommonKeyIpIntranet = `ip.intranet` 26 tracingCommonKeyIpHostname = `hostname` 27 commandEnvKeyForMaxContentLogSize = "gf.gtrace.maxcontentlogsize" 28 commandEnvKeyForTracingInternal = "gf.gtrace.tracinginternal" 29 ) 30 31 var ( 32 intranetIps, _ = gipv4.GetIntranetIpArray() 33 intranetIpStr = strings.Join(intranetIps, ",") 34 hostname, _ = os.Hostname() 35 tracingInternal = true // tracingInternal enables tracing for internal type spans. 36 tracingMaxContentLogSize = 256 * 1024 // Max log size for request and response body, especially for HTTP/RPC request. 37 // defaultTextMapPropagator is the default propagator for context propagation between peers. 38 defaultTextMapPropagator = propagation.NewCompositeTextMapPropagator( 39 propagation.TraceContext{}, 40 propagation.Baggage{}, 41 ) 42 ) 43 44 func init() { 45 tracingInternal = gcmd.GetOptWithEnv(commandEnvKeyForTracingInternal, true).Bool() 46 if maxContentLogSize := gcmd.GetOptWithEnv(commandEnvKeyForMaxContentLogSize).Int(); maxContentLogSize > 0 { 47 tracingMaxContentLogSize = maxContentLogSize 48 } 49 CheckSetDefaultTextMapPropagator() 50 } 51 52 // IsTracingInternal returns whether tracing spans of internal components. 53 func IsTracingInternal() bool { 54 return tracingInternal 55 } 56 57 // MaxContentLogSize returns the max log size for request and response body, especially for HTTP/RPC request. 58 func MaxContentLogSize() int { 59 return tracingMaxContentLogSize 60 } 61 62 // CommonLabels returns common used attribute labels: 63 // ip.intranet, hostname. 64 func CommonLabels() []attribute.KeyValue { 65 return []attribute.KeyValue{ 66 attribute.String(tracingCommonKeyIpHostname, hostname), 67 attribute.String(tracingCommonKeyIpIntranet, intranetIpStr), 68 } 69 } 70 71 // IsActivated checks and returns if tracing feature is activated. 72 func IsActivated(ctx context.Context) bool { 73 return GetTraceId(ctx) != "" 74 } 75 76 // CheckSetDefaultTextMapPropagator sets the default TextMapPropagator if it is not set previously. 77 func CheckSetDefaultTextMapPropagator() { 78 p := otel.GetTextMapPropagator() 79 if len(p.Fields()) == 0 { 80 otel.SetTextMapPropagator(GetDefaultTextMapPropagator()) 81 } 82 } 83 84 // GetDefaultTextMapPropagator returns the default propagator for context propagation between peers. 85 func GetDefaultTextMapPropagator() propagation.TextMapPropagator { 86 return defaultTextMapPropagator 87 } 88 89 // GetTraceId retrieves and returns TraceId from context. 90 // It returns an empty string is tracing feature is not activated. 91 func GetTraceId(ctx context.Context) string { 92 if ctx == nil { 93 return "" 94 } 95 traceId := trace.SpanContextFromContext(ctx).TraceID() 96 if traceId.IsValid() { 97 return traceId.String() 98 } 99 return "" 100 } 101 102 // GetSpanId retrieves and returns SpanId from context. 103 // It returns an empty string is tracing feature is not activated. 104 func GetSpanId(ctx context.Context) string { 105 if ctx == nil { 106 return "" 107 } 108 spanId := trace.SpanContextFromContext(ctx).SpanID() 109 if spanId.IsValid() { 110 return spanId.String() 111 } 112 return "" 113 } 114 115 // SetBaggageValue is a convenient function for adding one key-value pair to baggage. 116 // Note that it uses attribute.Any to set the key-value pair. 117 func SetBaggageValue(ctx context.Context, key string, value interface{}) context.Context { 118 return NewBaggage(ctx).SetValue(key, value) 119 } 120 121 // SetBaggageMap is a convenient function for adding map key-value pairs to baggage. 122 // Note that it uses attribute.Any to set the key-value pair. 123 func SetBaggageMap(ctx context.Context, data map[string]interface{}) context.Context { 124 return NewBaggage(ctx).SetMap(data) 125 } 126 127 // GetBaggageMap retrieves and returns the baggage values as map. 128 func GetBaggageMap(ctx context.Context) *gmap.StrAnyMap { 129 return NewBaggage(ctx).GetMap() 130 } 131 132 // GetBaggageVar retrieves value and returns a *gvar.Var for specified key from baggage. 133 func GetBaggageVar(ctx context.Context, key string) *gvar.Var { 134 return NewBaggage(ctx).GetVar(key) 135 }