refactor: remove Sentry integration and replace with OpenTelemetry
Remove Sentry dependencies and configuration. Introduce monitoring setup for OpenTelemetry. Update logging to include log format options, and replace Sentry error handling middleware with monitoring handlers for GraphQL playground. Adjust environment variable handling to enhance configuration clarity and flexibility.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package monitoring
|
||||
|
||||
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))
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user