observer/pkg/fiber_tracing/fiber_tracing.go

97 lines
2.6 KiB
Go

package fiber_tracing
import (
"context"
"log"
"git.ma-al.com/maal-libraries/observer/pkg/exporters"
"github.com/gofiber/fiber/v2"
"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 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) {
return Tracer.Start(c.UserContext(), c.Method()+" "+c.Route().Path, opts...)
}
// Just like [FStart] but makes it possible to assign custom span name.
func FStartRenamed(c *fiber.Ctx, spanName string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
return Tracer.Start(c.UserContext(), spanName, opts...)
}
// Retrieve span using [fiber.Ctx]
func SpanFromContext(c *fiber.Ctx) trace.Span {
return trace.SpanFromContext(c.UserContext())
}
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 new(
middlewareConfig{
Tracer: tracer,
TracerStartAttributes: []trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindServer),
trace.WithNewRoot(),
},
},
)
}
func ShutdownTracer() {
if err := TP.Shutdown(context.Background()); err != nil {
log.Fatal(err)
}
}