dbec05bdf7
Updates the SetupOTelSDK function to include an environment parameter. This change ensures that the OpenTelemetry setup now captures and sets the service environment along with the service name and version. It enhances observability by providing more context about the application's deployment environment.
101 lines
2.9 KiB
Go
101 lines
2.9 KiB
Go
package otelsetup
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
|
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
|
|
"go.opentelemetry.io/otel/log/global"
|
|
"go.opentelemetry.io/otel/propagation"
|
|
"go.opentelemetry.io/otel/sdk/log"
|
|
"go.opentelemetry.io/otel/sdk/metric"
|
|
"go.opentelemetry.io/otel/sdk/trace"
|
|
)
|
|
|
|
// SetupOTelSDK bootstraps the OpenTelemetry pipeline.
|
|
func SetupOTelSDK(ctx context.Context, enabled bool, serviceName, buildVersion, environment string) (func(context.Context) error, error) {
|
|
if os.Getenv("OTEL_RESOURCE_ATTRIBUTES") == "" {
|
|
if err := os.Setenv("OTEL_RESOURCE_ATTRIBUTES", fmt.Sprintf("service.name=%s,service.version=%s,service.environment=%s", serviceName, buildVersion, environment)); err != nil {
|
|
return func(context.Context) error {
|
|
return nil
|
|
}, err
|
|
}
|
|
}
|
|
var shutdownFuncs []func(context.Context) error
|
|
if !enabled {
|
|
return func(context.Context) error {
|
|
return nil
|
|
}, nil
|
|
}
|
|
shutdown := func(ctx context.Context) error {
|
|
var err error
|
|
for _, fn := range shutdownFuncs {
|
|
err = errors.Join(err, fn(ctx))
|
|
}
|
|
shutdownFuncs = nil
|
|
return err
|
|
}
|
|
|
|
// handleErr calls shutdown for cleanup and makes sure that all errors are returned.
|
|
handleErr := func(inErr error) (func(context.Context) error, error) {
|
|
return nil, errors.Join(inErr, shutdown(ctx))
|
|
}
|
|
|
|
// Set up the propagator.
|
|
prop := propagation.NewCompositeTextMapPropagator(
|
|
propagation.TraceContext{},
|
|
propagation.Baggage{},
|
|
)
|
|
otel.SetTextMapPropagator(prop)
|
|
|
|
traceExporter, err := otlptracehttp.New(ctx)
|
|
if err != nil {
|
|
return handleErr(err)
|
|
}
|
|
shutdownFuncs = append(shutdownFuncs, traceExporter.Shutdown)
|
|
|
|
tracerProvider := trace.NewTracerProvider(
|
|
trace.WithBatcher(traceExporter,
|
|
trace.WithBatchTimeout(5*time.Second)),
|
|
)
|
|
shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown)
|
|
otel.SetTracerProvider(tracerProvider)
|
|
|
|
logExporter, err := stdoutlog.New()
|
|
if err != nil {
|
|
return handleErr(err)
|
|
}
|
|
processor := log.NewSimpleProcessor(logExporter)
|
|
logProvider := log.NewLoggerProvider(log.WithProcessor(processor))
|
|
|
|
global.SetLoggerProvider(logProvider)
|
|
shutdownFuncs = append(shutdownFuncs, logProvider.Shutdown)
|
|
|
|
exp, err := otlpmetrichttp.New(ctx)
|
|
if err != nil {
|
|
return handleErr(err)
|
|
}
|
|
meterProvider := metric.NewMeterProvider(metric.WithReader(metric.NewPeriodicReader(exp)))
|
|
shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown)
|
|
|
|
otel.SetMeterProvider(meterProvider)
|
|
return shutdown, err
|
|
}
|
|
|
|
func Handler(h http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))
|
|
spanCtx, s := StartSpan(ctx, "http")
|
|
defer s.Finish()
|
|
|
|
h.ServeHTTP(w, r.WithContext(spanCtx))
|
|
})
|
|
}
|