func ConfigureOpenTelemetryTracer()

in frontend/pkg/frontend/otel_sdk.go [53:102]


func ConfigureOpenTelemetryTracer(ctx context.Context, logger *slog.Logger, resourceAttrs ...attribute.KeyValue) (
	func(context.Context) error,
	error,
) {
	exp, err := autoexport.NewSpanExporter(ctx, autoexport.WithFallbackSpanExporter(newNoopFactory))
	if err != nil {
		return nil, fmt.Errorf("failed to create OTEL exporter: %w", err)
	}

	var isNoop bool
	if _, isNoop = exp.(*noopSpanExporter); !isNoop || autoexport.IsNoneSpanExporter(exp) {
		isNoop = true
	}
	logger.InfoContext(ctx, "initialising OpenTelemetry tracer", "isNoop", isNoop)

	opts := []resource.Option{resource.WithHost()}
	if len(resourceAttrs) > 0 {
		opts = append(opts, resource.WithAttributes(resourceAttrs...))
	}
	opts = append(opts, resource.WithAttributes(
		semconv.ServiceNameKey.String(ProgramName),
		semconv.ServiceVersionKey.String(version.CommitSHA),
		semconv.CloudProviderAzure,
	))
	resources, err := resource.New(ctx, opts...)
	if err != nil {
		return nil, fmt.Errorf("failed to initialise trace resources: %w", err)
	}

	tp := trace.NewTracerProvider(
		trace.WithBatcher(exp),
		trace.WithResource(resources),
	)
	otel.SetTracerProvider(tp)

	shutdown := func(ctx context.Context) error {
		ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
		defer cancel()
		return tp.Shutdown(ctx)
	}

	propagator := propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})
	otel.SetTextMapPropagator(propagator)

	otel.SetErrorHandler(otelErrorHandlerFunc(func(err error) {
		logger.ErrorContext(ctx, fmt.Sprintf("OpenTelemetry.ErrorHandler: %v", err))
	}))

	return shutdown, nil
}