API Server: Fix stack overflow panic when tracing is disabled (#90075)

This commit is contained in:
Marcus Efraimsson 2024-07-04 18:11:59 +02:00 committed by GitHub
parent d6b39498d0
commit 06e67bc573
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 31 deletions

View File

@ -3,6 +3,7 @@ package apiserver
import (
"context"
"os"
"sync"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel"
@ -116,16 +117,17 @@ type lateInitializedTracingProvider struct {
}
func (tp lateInitializedTracingProvider) Tracer(name string, options ...trace.TracerOption) trace.Tracer {
return tp.tracer
return tp.tracer.getTracer()
}
type lateInitializedTracingService struct {
tracing.Tracer
mutex sync.RWMutex
}
func newLateInitializedTracingService() *lateInitializedTracingService {
ts := &lateInitializedTracingService{
Tracer: tracing.InitializeTracerForTest(),
Tracer: tracing.NewNoopTracerService(),
}
tp := &lateInitializedTracingProvider{
@ -137,8 +139,17 @@ func newLateInitializedTracingService() *lateInitializedTracingService {
return ts
}
func (s *lateInitializedTracingService) InitTracer(tracer tracing.Tracer) {
func (s *lateInitializedTracingService) getTracer() tracing.Tracer {
s.mutex.RLock()
t := s.Tracer
s.mutex.RUnlock()
return t
}
func (s *lateInitializedTracingService) InitTracer(tracer *tracing.TracingService) {
s.mutex.Lock()
s.Tracer = tracer
s.mutex.Unlock()
}
var _ tracing.Tracer = &lateInitializedTracingService{}

View File

@ -99,38 +99,20 @@ func ProvideService(tracingCfg *TracingConfig) (*TracingService, error) {
return ots, nil
}
func NewNoopTracerService() *TracingService {
tp := &noopTracerProvider{TracerProvider: noop.NewTracerProvider()}
otel.SetTracerProvider(tp)
cfg := NewEmptyTracingConfig()
ots := &TracingService{cfg: cfg, tracerProvider: tp}
_ = ots.initOpentelemetryTracer()
return ots
}
func (ots *TracingService) GetTracerProvider() tracerProvider {
return ots.tracerProvider
}
func TraceIDFromContext(ctx context.Context, requireSampled bool) string {
spanCtx := trace.SpanContextFromContext(ctx)
if !spanCtx.HasTraceID() || !spanCtx.IsValid() || (requireSampled && !spanCtx.IsSampled()) {
return ""
}
return spanCtx.TraceID().String()
}
// Error sets the status to error and record the error as an exception in the provided span.
func Error(span trace.Span, err error) error {
attr := []attribute.KeyValue{}
grafanaErr := errutil.Error{}
if errors.As(err, &grafanaErr) {
attr = append(attr, attribute.String("message_id", grafanaErr.MessageID))
}
span.SetStatus(codes.Error, err.Error())
span.RecordError(err, trace.WithAttributes(attr...))
return err
}
// Errorf wraps fmt.Errorf and also sets the status to error and record the error as an exception in the provided span.
func Errorf(span trace.Span, format string, args ...any) error {
err := fmt.Errorf(format, args...)
return Error(span, err)
}
type noopTracerProvider struct {
trace.TracerProvider
}
@ -389,3 +371,31 @@ func (rl *rateLimiter) ShouldSample(p tracesdk.SamplingParameters) tracesdk.Samp
}
func (rl *rateLimiter) Description() string { return rl.description }
func TraceIDFromContext(ctx context.Context, requireSampled bool) string {
spanCtx := trace.SpanContextFromContext(ctx)
if !spanCtx.HasTraceID() || !spanCtx.IsValid() || (requireSampled && !spanCtx.IsSampled()) {
return ""
}
return spanCtx.TraceID().String()
}
// Error sets the status to error and record the error as an exception in the provided span.
func Error(span trace.Span, err error) error {
attr := []attribute.KeyValue{}
grafanaErr := errutil.Error{}
if errors.As(err, &grafanaErr) {
attr = append(attr, attribute.String("message_id", grafanaErr.MessageID))
}
span.SetStatus(codes.Error, err.Error())
span.RecordError(err, trace.WithAttributes(attr...))
return err
}
// Errorf wraps fmt.Errorf and also sets the status to error and record the error as an exception in the provided span.
func Errorf(span trace.Span, format string, args ...any) error {
err := fmt.Errorf(format, args...)
return Error(span, err)
}