observer/pkg/fiber_tracing/fiber_tracing.go

98 lines
2.8 KiB
Go

package fiber_tracing
import (
"context"
"log"
"git.ma-al.com/maal-libraries/observer/pkg/exporters"
"github.com/gofiber/fiber/v2"
fiberOpentelemetry "github.com/psmarcin/fiber-opentelemetry/pkg/fiber-otel"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/resource"
trc "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
trace "go.opentelemetry.io/otel/trace"
)
var (
TracingError error = nil
TP trc.TracerProvider
)
type Config struct {
AppName string
Version string
// Name of an organization providing the service
ServiceProvider string
Exporters []exporters.TraceExporter
}
func newResource(config Config) *resource.Resource {
r := resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(config.AppName),
semconv.ServiceVersionKey.String(config.Version),
attribute.String("service.provider", config.ServiceProvider),
)
return r
}
// NOTE: You can use [trace.WithAttributes] as a parameter to opts argument
func Start(ctx context.Context, spanName string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
return fiberOpentelemetry.Tracer.Start(ctx, spanName, opts...)
}
// NOTE: You can use [trace.WithAttributes] as a parameter to opts argument
// Returns [c.UserContext] as [context.Context]
func FStart(c *fiber.Ctx, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
span := trace.SpanFromContext(fiberOpentelemetry.FromCtx(c))
c.SetUserContext(trace.ContextWithSpan(c.UserContext(), span))
return fiberOpentelemetry.Tracer.Start(c.UserContext(), c.Method()+" "+c.Path(), opts...)
}
// Retrieve span using [fiber.Ctx]
func SpanFromContext(c *fiber.Ctx) trace.Span {
ctx := fiberOpentelemetry.FromCtx(c)
c.SetUserContext(trace.ContextWithSpan(c.UserContext(), trace.SpanFromContext(ctx)))
return trace.SpanFromContext(ctx)
}
func NewMiddleware(config Config) func(*fiber.Ctx) error {
var tracerProviders []trc.TracerProviderOption
for _, exp := range config.Exporters {
tracerProviders = append(tracerProviders, exp.IntoTraceProviderOption())
}
tracerProviders = append(tracerProviders, trc.WithResource(newResource(config)))
TP = *trc.NewTracerProvider(tracerProviders...)
otel.SetTracerProvider(&TP)
otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) {
if err != TracingError {
TracingError = err
log.Println(err)
}
}))
tracer := TP.Tracer("_maal-fiber-otel_")
return fiberOpentelemetry.New(
fiberOpentelemetry.Config{
Tracer: tracer,
SpanName: "{{ .Method }} {{ .Path }}",
TracerStartAttributes: []trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindServer),
trace.WithNewRoot(),
},
},
)
}
func ShutdownTracer() {
if err := TP.Shutdown(context.Background()); err != nil {
log.Fatal(err)
}
}