Skip to content

Commit 5e7947c

Browse files
committed
Add support for filtering request being traced
1 parent 3d63966 commit 5e7947c

File tree

4 files changed

+43
-21
lines changed

4 files changed

+43
-21
lines changed

foxtrace.go

+23-16
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ package otelfox
33
import (
44
"fmt"
55
"github.com/tigerwill90/fox"
6-
"go.opentelemetry.io/otel/propagation"
76
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
87
"go.opentelemetry.io/otel/semconv/v1.18.0/httpconv"
98
"go.opentelemetry.io/otel/trace"
10-
"net/http"
119
)
1210

1311
const (
@@ -16,11 +14,9 @@ const (
1614

1715
// Tracer is a Fox middleware that traces HTTP requests using OpenTelemetry.
1816
type Tracer struct {
19-
service string
20-
tracer trace.Tracer
21-
propagator propagation.TextMapPropagator
22-
carrier func(r *http.Request) propagation.TextMapCarrier
23-
spanFmt func(r *http.Request) string
17+
service string
18+
tracer trace.Tracer
19+
cfg *config
2420
}
2521

2622
// New creates a new Tracer middleware for the given service.
@@ -33,39 +29,50 @@ func New(service string, opts ...Option) *Tracer {
3329

3430
tracer := cfg.provider.Tracer(tracerName, trace.WithInstrumentationVersion(SemVersion()))
3531
return &Tracer{
36-
service: service,
37-
tracer: tracer,
38-
propagator: cfg.propagator,
39-
carrier: cfg.carrier,
40-
spanFmt: cfg.spanFmt,
32+
service: service,
33+
tracer: tracer,
34+
cfg: cfg,
4135
}
4236
}
4337

38+
// Middleware is a convenience function that creates a new Tracer middleware instance
39+
// for the specified service and returns the Trace middleware function.
40+
// Options can be provided to configure the tracer.
4441
func Middleware(service string, opts ...Option) fox.MiddlewareFunc {
4542
tracer := New(service, opts...)
4643
return tracer.Trace
4744
}
4845

46+
// Trace is a middleware function that wraps the provided HandlerFunc with tracing capabilities.
47+
// It captures and records HTTP request information using OpenTelemetry.
4948
func (t *Tracer) Trace(next fox.HandlerFunc) fox.HandlerFunc {
5049
return func(c fox.Context) {
5150

5251
req := c.Request()
53-
ctx := t.propagator.Extract(req.Context(), t.carrier(req))
52+
53+
for _, f := range t.cfg.filters {
54+
if !f(req) {
55+
next(c)
56+
return
57+
}
58+
}
59+
60+
ctx := t.cfg.propagator.Extract(req.Context(), t.cfg.carrier(req))
5461

5562
opts := []trace.SpanStartOption{
5663
trace.WithAttributes(httpconv.ServerRequest(t.service, req)...),
5764
trace.WithSpanKind(trace.SpanKindServer),
5865
}
5966

6067
var spanName string
61-
if t.spanFmt == nil {
68+
if t.cfg.spanFmt == nil {
6269
spanName = c.Path()
6370
} else {
64-
spanName = t.spanFmt(req)
71+
spanName = t.cfg.spanFmt(req)
6572
}
6673

6774
if spanName == "" {
68-
spanName = fmt.Sprintf("HTTP %s route not found", c.Request().Method)
75+
spanName = fmt.Sprintf("HTTP %s route not found", req.Method)
6976
} else {
7077
opts = append(opts, trace.WithAttributes(semconv.HTTPRoute(spanName)))
7178
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.19
44

55
require (
66
github.com/stretchr/testify v1.8.2
7-
github.com/tigerwill90/fox v0.7.6
7+
github.com/tigerwill90/fox v0.8.0
88
go.opentelemetry.io/contrib/propagators/b3 v1.15.0
99
go.opentelemetry.io/otel v1.14.0
1010
go.opentelemetry.io/otel/trace v1.14.0

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
2222
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
2323
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
2424
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
25-
github.com/tigerwill90/fox v0.7.6 h1:SuDVuygis0nOcRdmq/dxiJCWhJ33fzh2VwIW7KuKZSA=
26-
github.com/tigerwill90/fox v0.7.6/go.mod h1:MdAVSWOSSlp+MExhsvqWF1kedhAnMsV90VTcaaQdKWo=
25+
github.com/tigerwill90/fox v0.8.0 h1:07oGL4H75PR/uK6GIwSSVJpvXYTGr17KPssbSNL7HpA=
26+
github.com/tigerwill90/fox v0.8.0/go.mod h1:MdAVSWOSSlp+MExhsvqWF1kedhAnMsV90VTcaaQdKWo=
2727
go.opentelemetry.io/contrib/propagators/b3 v1.15.0 h1:bMaonPyFcAvZ4EVzkUNkfnUHP5Zi63CIDlA3dRsEg8Q=
2828
go.opentelemetry.io/contrib/propagators/b3 v1.15.0/go.mod h1:VjU0g2v6HSQ+NwfifambSLAeBgevjIcqmceaKWEzl0c=
2929
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=

option.go

+17-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ func (o optionFunc) apply(c *config) {
1717
o(c)
1818
}
1919

20+
type Filter func(r *http.Request) bool
21+
22+
type SpanNameFormatter func(r *http.Request) string
23+
2024
type config struct {
2125
provider trace.TracerProvider
2226
propagator propagation.TextMapPropagator
2327
carrier func(r *http.Request) propagation.TextMapCarrier
24-
spanFmt func(r *http.Request) string
28+
spanFmt SpanNameFormatter
29+
filters []Filter
2530
}
2631

2732
func defaultConfig() *config {
@@ -67,8 +72,18 @@ func WithTextMapCarrier(fn func(r *http.Request) propagation.TextMapCarrier) Opt
6772

6873
// WithSpanNameFormatter takes a function that will be called on every request
6974
// and the returned string will become the Span Name.
70-
func WithSpanNameFormatter(fn func(r *http.Request) string) Option {
75+
func WithSpanNameFormatter(fn SpanNameFormatter) Option {
7176
return optionFunc(func(c *config) {
7277
c.spanFmt = fn
7378
})
7479
}
80+
81+
// WithFilter appends the provided filters to the middleware's filter list.
82+
// A filter returning false will exclude the request from being traced. If no filters
83+
// are provided, all requests will be traced. Keep in mind that filters are invoked for each request,
84+
// so they should be simple and efficient.
85+
func WithFilter(f ...Filter) Option {
86+
return optionFunc(func(c *config) {
87+
c.filters = append(c.filters, f...)
88+
})
89+
}

0 commit comments

Comments
 (0)