otel.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
package main import ( "context" "errors" "time" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/stdout/stdoutlog" "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "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. // If it does not return an error, make sure to call shutdown for proper cleanup. func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, err error) { var shutdownFuncs []func(context.Context) error // shutdown calls cleanup functions registered via shutdownFuncs. // The errors from the calls are joined. // Each registered cleanup will be invoked once. 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) { err = errors.Join(inErr, shutdown(ctx)) } // Set up propagator. prop := newPropagator() otel.SetTextMapPropagator(prop) // Set up trace provider. tracerProvider, err := newTraceProvider() if err != nil { handleErr(err) return } shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown) otel.SetTracerProvider(tracerProvider) // Set up meter provider. meterProvider, err := newMeterProvider() if err != nil { handleErr(err) return } shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown) otel.SetMeterProvider(meterProvider) // Set up logger provider. loggerProvider, err := newLoggerProvider() if err != nil { handleErr(err) return } shutdownFuncs = append(shutdownFuncs, loggerProvider.Shutdown) global.SetLoggerProvider(loggerProvider) return } func newPropagator() propagation.TextMapPropagator { return propagation.NewCompositeTextMapPropagator( propagation.TraceContext{}, propagation.Baggage{}, ) } func newTraceProvider() (*trace.TracerProvider, error) { traceExporter, err := stdouttrace.New( stdouttrace.WithPrettyPrint()) if err != nil { return nil, err } traceProvider := trace.NewTracerProvider( trace.WithBatcher(traceExporter, // Default is 5s. Set to 1s for demonstrative purposes. trace.WithBatchTimeout(time.Second)), ) return traceProvider, nil } func newMeterProvider() (*metric.MeterProvider, error) { metricExporter, err := stdoutmetric.New() if err != nil { return nil, err } meterProvider := metric.NewMeterProvider( metric.WithReader(metric.NewPeriodicReader(metricExporter, // Default is 1m. Set to 3s for demonstrative purposes. metric.WithInterval(3*time.Second))), ) return meterProvider, nil } func newLoggerProvider() (*log.LoggerProvider, error) { logExporter, err := stdoutlog.New() if err != nil { return nil, err } loggerProvider := log.NewLoggerProvider( log.WithProcessor(log.NewBatchProcessor(logExporter)), ) return loggerProvider, nil } |