@@ -51,21 +51,26 @@ func Middleware(service string, opts ...Option) mux.MiddlewareFunc {
51
51
if cfg .Propagators == nil {
52
52
cfg .Propagators = otel .GetTextMapPropagator ()
53
53
}
54
+ if cfg .spanNameFormatter == nil {
55
+ cfg .spanNameFormatter = defaultSpanNameFunc
56
+ }
54
57
return func (handler http.Handler ) http.Handler {
55
58
return traceware {
56
- service : service ,
57
- tracer : tracer ,
58
- propagators : cfg .Propagators ,
59
- handler : handler ,
59
+ service : service ,
60
+ tracer : tracer ,
61
+ propagators : cfg .Propagators ,
62
+ handler : handler ,
63
+ spanNameFormatter : cfg .spanNameFormatter ,
60
64
}
61
65
}
62
66
}
63
67
64
68
type traceware struct {
65
- service string
66
- tracer oteltrace.Tracer
67
- propagators propagation.TextMapPropagator
68
- handler http.Handler
69
+ service string
70
+ tracer oteltrace.Tracer
71
+ propagators propagation.TextMapPropagator
72
+ handler http.Handler
73
+ spanNameFormatter func (string , * http.Request ) string
69
74
}
70
75
71
76
type recordingResponseWriter struct {
@@ -111,32 +116,35 @@ func putRRW(rrw *recordingResponseWriter) {
111
116
rrwPool .Put (rrw )
112
117
}
113
118
119
+ // defaultSpanNameFunc just reuses the route name as the span name.
120
+ func defaultSpanNameFunc (routeName string , _ * http.Request ) string { return routeName }
121
+
114
122
// ServeHTTP implements the http.Handler interface. It does the actual
115
123
// tracing of the request.
116
124
func (tw traceware ) ServeHTTP (w http.ResponseWriter , r * http.Request ) {
117
125
ctx := tw .propagators .Extract (r .Context (), propagation .HeaderCarrier (r .Header ))
118
- spanName := ""
126
+ routeStr := ""
119
127
route := mux .CurrentRoute (r )
120
128
if route != nil {
121
129
var err error
122
- spanName , err = route .GetPathTemplate ()
130
+ routeStr , err = route .GetPathTemplate ()
123
131
if err != nil {
124
- spanName , err = route .GetPathRegexp ()
132
+ routeStr , err = route .GetPathRegexp ()
125
133
if err != nil {
126
- spanName = ""
134
+ routeStr = ""
127
135
}
128
136
}
129
137
}
130
- routeStr := spanName
131
- if spanName == "" {
132
- spanName = fmt .Sprintf ("HTTP %s route not found" , r .Method )
138
+ if routeStr == "" {
139
+ routeStr = fmt .Sprintf ("HTTP %s route not found" , r .Method )
133
140
}
134
141
opts := []oteltrace.SpanStartOption {
135
142
oteltrace .WithAttributes (semconv .NetAttributesFromHTTPRequest ("tcp" , r )... ),
136
143
oteltrace .WithAttributes (semconv .EndUserAttributesFromHTTPRequest (r )... ),
137
144
oteltrace .WithAttributes (semconv .HTTPServerAttributesFromHTTPRequest (tw .service , routeStr , r )... ),
138
145
oteltrace .WithSpanKind (oteltrace .SpanKindServer ),
139
146
}
147
+ spanName := tw .spanNameFormatter (routeStr , r )
140
148
ctx , span := tw .tracer .Start (ctx , spanName , opts ... )
141
149
defer span .End ()
142
150
r2 := r .WithContext (ctx )
0 commit comments