2024-05-16 16:19:36 +00:00
|
|
|
package fiber_tracing
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"log"
|
|
|
|
|
2024-05-20 06:20:13 +00:00
|
|
|
"git.ma-al.com/maal-libraries/observer/pkg/exporters"
|
2024-05-16 16:19:36 +00:00
|
|
|
"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 {
|
2024-05-17 08:37:05 +00:00
|
|
|
AppName string
|
|
|
|
Version string
|
|
|
|
// Name of an organization providing the service
|
2024-05-16 16:19:36 +00:00
|
|
|
ServiceProvider string
|
2024-05-17 13:31:35 +00:00
|
|
|
Exporters []exporters.TraceExporter
|
2024-05-16 16:19:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-05-17 13:31:35 +00:00
|
|
|
// 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
|
2024-05-20 09:45:27 +00:00
|
|
|
// Returns [c.UserContext] as [context.Context]
|
2024-05-17 13:31:35 +00:00
|
|
|
func FStart(c *fiber.Ctx, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
2024-05-20 17:35:21 +00:00
|
|
|
span := trace.SpanFromContext(fiberOpentelemetry.FromCtx(c))
|
|
|
|
c.SetUserContext(trace.ContextWithSpan(c.UserContext(), span))
|
2024-05-20 17:43:39 +00:00
|
|
|
return fiberOpentelemetry.Tracer.Start(c.UserContext(), c.Method()+" "+c.Route().Path, opts...)
|
2024-05-17 13:31:35 +00:00
|
|
|
}
|
|
|
|
|
2024-05-20 09:04:36 +00:00
|
|
|
// Retrieve span using [fiber.Ctx]
|
|
|
|
func SpanFromContext(c *fiber.Ctx) trace.Span {
|
|
|
|
ctx := fiberOpentelemetry.FromCtx(c)
|
2024-05-20 17:35:21 +00:00
|
|
|
c.SetUserContext(trace.ContextWithSpan(c.UserContext(), trace.SpanFromContext(ctx)))
|
2024-05-20 09:04:36 +00:00
|
|
|
return trace.SpanFromContext(ctx)
|
|
|
|
}
|
|
|
|
|
2024-05-16 16:19:36 +00:00
|
|
|
func NewMiddleware(config Config) func(*fiber.Ctx) error {
|
|
|
|
var tracerProviders []trc.TracerProviderOption
|
|
|
|
|
2024-05-17 08:37:05 +00:00
|
|
|
for _, exp := range config.Exporters {
|
|
|
|
tracerProviders = append(tracerProviders, exp.IntoTraceProviderOption())
|
|
|
|
}
|
2024-05-16 16:19:36 +00:00
|
|
|
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,
|
2024-05-20 17:43:39 +00:00
|
|
|
SpanName: "{{ .Method }} {{ .Route.Path }}",
|
2024-05-16 16:19:36 +00:00
|
|
|
TracerStartAttributes: []trace.SpanStartOption{
|
|
|
|
trace.WithSpanKind(trace.SpanKindServer),
|
|
|
|
trace.WithNewRoot(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ShutdownTracer() {
|
|
|
|
if err := TP.Shutdown(context.Background()); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|