goshort/internal/util/tracing/tracing.go
Gustavo Maronato 8ac3eef33a
Some checks failed
Build / build (push) Has been cancelled
implemented tracing
2023-09-21 16:19:17 -03:00

90 lines
2.2 KiB
Go

package tracing
import (
"context"
"git.maronato.dev/maronato/goshort/internal/config"
"git.maronato.dev/maronato/goshort/internal/errs"
"git.maronato.dev/maronato/goshort/internal/util/logging"
"go.opentelemetry.io/contrib/propagators/autoprop"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
"go.opentelemetry.io/otel/trace"
)
const tracerName = "goshort"
type tracerKey struct{}
func InitTracer(ctx context.Context, cfg *config.Config, version string) (context.Context, func(), error) {
var ex sdktrace.SpanExporter
shutdown := func() {}
ex, err := otlptracegrpc.New(ctx)
if err != nil {
return ctx, shutdown, errs.Errorf("failed to initialize otlptracegrpc exporter %w", err)
}
// Create a new resource with service name
env := "development"
if cfg.Prod {
env = "production"
}
r := resource.NewSchemaless(
semconv.ServiceNameKey.String("goshort"),
semconv.ServiceVersion(version),
semconv.DeploymentEnvironment(env),
semconv.ServiceName("goshort"),
)
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(ex),
sdktrace.WithResource(r),
)
// Set the global trace provider
otel.SetTracerProvider(tp)
tracer := tp.Tracer(tracerName)
// Set context tracer
ctx = context.WithValue(ctx, tracerKey{}, tracer)
// Set the global propagator
p := autoprop.NewTextMapPropagator()
otel.SetTextMapPropagator(p)
// Define shutdown function
shutdown = func() {
l := logging.FromCtx(ctx)
if err := tp.ForceFlush(ctx); err != nil {
l.Error("Failed to flush tracer provider", err)
return
}
if err := tp.Shutdown(context.WithoutCancel(ctx)); err != nil {
l.Error("Failed to shutdown tracer provider", err)
return
}
}
return ctx, shutdown, nil
}
func StartSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { //nolint:ireturn // Span is only available as an interface
tracer, ok := ctx.Value(tracerKey{}).(trace.Tracer)
if !ok {
tracer = trace.SpanFromContext(ctx).TracerProvider().Tracer("goshort")
}
return tracer.Start(ctx, name, opts...)
}