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  }