Stop overriding the global OTEL error handler (#11551)

## What changed?

Stop installing Temporal-specific process-global OTEL error handlers.
OTEL errors now use the default ie stderr.

## Why?

The process-global OTEL handler retained the Temporal server logger
after shutdown; ie it leaked.
This commit is contained in:
Stephan Behnke
2026-08-27 13:58:40 -07:00
committed by GitHub
parent 1863fbe665
commit c7cd6e263e
2 changed files with 2 additions and 21 deletions

View File

@@ -6,11 +6,9 @@ import (
"fmt" "fmt"
"maps" "maps"
"os" "os"
"sync/atomic"
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
otellog "go.opentelemetry.io/otel/log" otellog "go.opentelemetry.io/otel/log"
lognoop "go.opentelemetry.io/otel/log/noop" lognoop "go.opentelemetry.io/otel/log/noop"
@@ -966,7 +964,6 @@ func verifyPersistenceCompatibleVersion(
type SpanExporterInputs struct { type SpanExporterInputs struct {
fx.In fx.In
Lifecycyle fx.Lifecycle Lifecycyle fx.Lifecycle
Logger log.Logger
Config *config.Config `optional:"true"` Config *config.Config `optional:"true"`
} }
@@ -977,13 +974,6 @@ type SpanExporterInputs struct {
// - []go.opentelemetry.io/otel/sdk/trace.SpanExporter // - []go.opentelemetry.io/otel/sdk/trace.SpanExporter
var TraceExportModule = fx.Options( var TraceExportModule = fx.Options(
fx.Provide(func(inputs SpanExporterInputs) ([]otelsdktrace.SpanExporter, error) { fx.Provide(func(inputs SpanExporterInputs) ([]otelsdktrace.SpanExporter, error) {
var tracingReady atomic.Bool
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) {
if tracingReady.Load() { // ignore errors during startup
inputs.Logger.Warn("OTEL error", tag.Error(err), tag.ServiceErrorType(err))
}
}))
// (1) Exporters from config. // (1) Exporters from config.
exportersByType := map[telemetry.SpanExporterType]otelsdktrace.SpanExporter{} exportersByType := map[telemetry.SpanExporterType]otelsdktrace.SpanExporter{}
if inputs.Config != nil { if inputs.Config != nil {
@@ -1010,12 +1000,8 @@ var TraceExportModule = fx.Options(
// Configure exporters' lifecycle hooks. // Configure exporters' lifecycle hooks.
inputs.Lifecycyle.Append(fx.Hook{ inputs.Lifecycyle.Append(fx.Hook{
OnStart: func(ctx context.Context) error { OnStart: startAll(exporters),
err = startAll(exporters)(ctx) OnStop: shutdownAll(exporters),
tracingReady.Store(true)
return err
},
OnStop: shutdownAll(exporters),
}) })
return exporters, nil return exporters, nil
}), }),
@@ -1086,10 +1072,6 @@ var ServiceTracingModule = fx.Options(
tp := otelsdktrace.NewTracerProvider(opts...) tp := otelsdktrace.NewTracerProvider(opts...)
lc.Append(fx.Hook{ lc.Append(fx.Hook{
OnStop: func(ctx context.Context) error { OnStop: func(ctx context.Context) error {
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) {
// ignore errors during shutdown
}))
shutdownCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) shutdownCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel() defer cancel()

View File

@@ -29,7 +29,6 @@ var goleakOpts = []goleak.Option{
var objectLeakOpts = []objectleak.Option{ var objectLeakOpts = []objectleak.Option{
objectleak.WithPruneType("google.golang.org/protobuf/internal/impl.*"), objectleak.WithPruneType("google.golang.org/protobuf/internal/impl.*"),
objectleak.WithExpected("FunctionalTestBase.Logger*"),
objectleak.WithExpected("FunctionalTestBase.testCluster.host*"), objectleak.WithExpected("FunctionalTestBase.testCluster.host*"),
objectleak.WithExpected("FunctionalTestBase.testCluster.testBase*"), objectleak.WithExpected("FunctionalTestBase.testCluster.testBase*"),
} }