forked from st3v/go-plugins
/
tracker.go
81 lines (65 loc) · 1.85 KB
/
tracker.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
69
70
71
72
73
74
75
76
77
78
79
80
81
package opencensus
import (
"context"
"fmt"
"strconv"
"time"
"go.opencensus.io/stats"
"go.opencensus.io/tag"
"go.opencensus.io/trace"
)
type tracker struct {
startedAt time.Time
profile *StatsProfile
span *trace.Span
method string
service string
}
type requestDescriptor interface {
Service() string
Endpoint() string
}
type publicationDescriptor interface {
Topic() string
}
// newRequestTracker creates a new tracker for an RPC request (client or server).
func newRequestTracker(req requestDescriptor, profile *StatsProfile) *tracker {
return &tracker{
profile: profile,
method: req.Endpoint(),
service: req.Service(),
}
}
// newPublicationTracker creates a new tracker for a publication (client or server).
func newPublicationTracker(pub publicationDescriptor, profile *StatsProfile) *tracker {
return &tracker{
profile: profile,
method: pub.Topic(),
service: "pubsub",
}
}
// start monitoring a request. You can choose to let this method
// start a span for the request or attach one later.
func (t *tracker) start(ctx context.Context, startSpan bool) context.Context {
t.startedAt = time.Now()
ctx, _ = tag.New(ctx, tag.Upsert(Service, t.service), tag.Upsert(Endpoint, t.method))
stats.Record(ctx, t.profile.CountMeasure.M(1))
if startSpan {
ctx, t.span = trace.StartSpan(
ctx,
fmt.Sprintf("rpc/%s/%s/%s", t.profile.Role, t.service, t.method),
)
}
return ctx
}
// end a request's monitoring session. If there is a span ongoing, it will
// be ended and metrics will be recorded.
func (t *tracker) end(ctx context.Context, err error) {
status := getResponseStatus(err)
ctx, _ = tag.New(ctx, tag.Upsert(StatusCode, strconv.Itoa(int(status.Code))))
stats.Record(ctx, t.profile.LatencyMeasure.M(float64(time.Since(t.startedAt))/float64(time.Millisecond)))
if t.span != nil {
t.span.SetStatus(status)
t.span.End()
}
}