Documentation
¶
Overview ¶
Package otel provides OpenTelemetry tracing and metrics middleware for celeris.
The middleware creates a server span per request, propagates context via configured propagators, and records request duration and active request count as OTel metrics.
Basic usage with global providers:
server.Use(otel.New())
Explicit providers:
server.Use(otel.New(otel.Config{
TracerProvider: tp,
MeterProvider: mp,
}))
Downstream handlers can access the span via SpanFromContext:
span := otel.SpanFromContext(c)
Spans are named "METHOD /route/pattern" by default; override with Config.SpanNameFormatter. Attributes follow OTel semconv v1.32.0.
PII controls: client.address is opt-in (Config.CollectClientIP); user_agent.original is opt-out (Config.CollectUserAgent).
Filtering: use Config.Skip, Config.SkipPaths, or Config.Filter to exclude endpoints from tracing.
Metrics recorded: http.server.request.duration (s), http.server.active_requests, http.server.request.body.size (By), http.server.response.body.size (By). Set Config.DisableMetrics for tracing-only mode. Use Config.CustomAttributes and Config.CustomMetricAttributes for per-request attribute injection.
Response Size and Compression ¶
The http.response.body.size metric records c.BytesWritten() at the point the OTel middleware runs. With the recommended ordering (otel before compress), this reflects uncompressed application-level sizes. Changing the middleware order to place otel after compress would record compressed sizes instead.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
func New(config ...Config) celeris.HandlerFunc
New creates an OpenTelemetry tracing and metrics middleware.
Example ¶
package main
import (
"github.com/goceleris/celeris/middleware/otel"
)
func main() {
// Zero-config: uses global OTel TracerProvider, MeterProvider, and Propagators.
_ = otel.New()
}
Output:
Example (Filter) ¶
package main
import (
"github.com/goceleris/celeris"
"github.com/goceleris/celeris/middleware/otel"
)
func main() {
// Allow-list filter: only trace requests to /api/*.
_ = otel.New(otel.Config{
Filter: func(c *celeris.Context) bool {
return len(c.Path()) >= 4 && c.Path()[:4] == "/api"
},
})
}
Output:
Example (WithProvider) ¶
package main
import (
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
"github.com/goceleris/celeris/middleware/otel"
)
func main() {
// Explicit TracerProvider with an in-memory exporter (for testing).
// In production, replace with an OTLP exporter.
exp := tracetest.NewInMemoryExporter()
tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exp))
_ = otel.New(otel.Config{
TracerProvider: tp,
})
}
Output:
Example (WithSkipPaths) ¶
package main
import (
"github.com/goceleris/celeris/middleware/otel"
)
func main() {
// Skip health and readiness endpoints from tracing.
_ = otel.New(otel.Config{
SkipPaths: []string{"/health", "/ready"},
})
}
Output:
Example (WithSpanNameFormatter) ¶
package main
import (
"github.com/goceleris/celeris"
"github.com/goceleris/celeris/middleware/otel"
)
func main() {
// Custom span names.
_ = otel.New(otel.Config{
SpanNameFormatter: func(c *celeris.Context) string {
return c.Method() + " " + c.Path()
},
})
}
Output:
Types ¶
type Config ¶
type Config struct {
// Skip defines a function to skip this middleware for certain requests.
// When Skip returns true, the request bypasses tracing entirely.
Skip func(c *celeris.Context) bool
// SkipPaths lists paths to skip (exact match on c.Path()).
SkipPaths []string
// TracerProvider is the OTel TracerProvider to use.
// Default: otel.GetTracerProvider().
TracerProvider trace.TracerProvider
// MeterProvider is the OTel MeterProvider to use.
// Default: otel.GetMeterProvider().
MeterProvider metric.MeterProvider
// Propagators is the propagator to use for context injection/extraction.
// Default: otel.GetTextMapPropagator().
Propagators propagation.TextMapPropagator
// SpanNameFormatter overrides the default span name ("METHOD /route").
SpanNameFormatter func(c *celeris.Context) string
// Filter provides an allow-list predicate. When non-nil, requests for
// which Filter returns false are skipped. Kept for OTel ecosystem
// convention compatibility (inverse of Skip).
Filter func(c *celeris.Context) bool
// DisableMetrics skips all metric instrument creation and recording.
// When true, only tracing is active.
DisableMetrics bool
// CollectClientIP enables recording the client IP address in the
// "client.address" span attribute. Default: false (PII opt-in).
CollectClientIP bool
// CollectUserAgent enables recording the User-Agent header in the
// "user_agent.original" span attribute. Default: true for backwards
// compatibility.
CollectUserAgent *bool
// CustomAttributes is called per-request and appended to the span attributes.
CustomAttributes func(c *celeris.Context) []attribute.KeyValue
// CustomMetricAttributes is called per-request and appended to the metric attributes.
CustomMetricAttributes func(c *celeris.Context) []attribute.KeyValue
// ServerPort, when > 0, adds the "server.port" attribute to spans and metrics.
// Negative values are clamped to 0 in validate().
ServerPort int
}
Config defines the OpenTelemetry middleware configuration.