-
Notifications
You must be signed in to change notification settings - Fork 5.1k
/
wrapper.go
68 lines (58 loc) · 1.61 KB
/
wrapper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package tracing
import (
"context"
"net/http"
"github.com/containous/alice"
"github.com/containous/traefik/pkg/log"
"github.com/containous/traefik/pkg/tracing"
"github.com/opentracing/opentracing-go/ext"
)
// Tracable embeds tracing information.
type Tracable interface {
GetTracingInformation() (name string, spanKind ext.SpanKindEnum)
}
// Wrap adds tracability to an alice.Constructor.
func Wrap(ctx context.Context, constructor alice.Constructor) alice.Constructor {
return func(next http.Handler) (http.Handler, error) {
if constructor == nil {
return nil, nil
}
handler, err := constructor(next)
if err != nil {
return nil, err
}
if tracableHandler, ok := handler.(Tracable); ok {
name, spanKind := tracableHandler.GetTracingInformation()
log.FromContext(ctx).WithField(log.MiddlewareName, name).Debug("Adding tracing to middleware")
return NewWrapper(handler, name, spanKind), nil
}
return handler, nil
}
}
// NewWrapper returns a http.Handler struct
func NewWrapper(next http.Handler, name string, spanKind ext.SpanKindEnum) http.Handler {
return &Wrapper{
next: next,
name: name,
spanKind: spanKind,
}
}
// Wrapper is used to wrap http handler middleware.
type Wrapper struct {
next http.Handler
name string
spanKind ext.SpanKindEnum
}
func (w *Wrapper) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
_, err := tracing.FromContext(req.Context())
if err != nil {
w.next.ServeHTTP(rw, req)
return
}
var finish func()
_, req, finish = tracing.StartSpan(req, w.name, w.spanKind)
defer finish()
if w.next != nil {
w.next.ServeHTTP(rw, req)
}
}