-
Notifications
You must be signed in to change notification settings - Fork 216
/
observer.go
87 lines (74 loc) · 1.75 KB
/
observer.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
82
83
84
85
86
87
package observability
import (
"context"
"sync"
"time"
"go.opencensus.io/stats"
"go.opencensus.io/tag"
)
// Observable represents the the customization used by the Reporter for a given
// measurement and trace for a single method.
type Observable interface {
MethodName() string
LatencyMs() *stats.Float64Measure
}
// Reporter represents a running latency counter. When Error or OK are
// called, the latency is calculated. Error or OK are only allowed to
// be called once.
type Reporter interface {
Error()
OK()
}
type reporter struct {
ctx context.Context
on Observable
start time.Time
once sync.Once
}
// All tags used for Latency measurements.
func LatencyTags() []tag.Key {
return []tag.Key{KeyMethod, KeyResult}
}
// Deprecated. Tracing is always enabled.
func EnableTracing(enabled bool) {}
// NewReporter creates and returns a reporter wrapping the provided Observable.
func NewReporter(ctx context.Context, on Observable) (context.Context, Reporter) {
r := &reporter{
ctx: ctx,
on: on,
start: time.Now(),
}
r.tagMethod()
return ctx, r
}
func (r *reporter) tagMethod() {
var err error
r.ctx, err = tag.New(r.ctx, tag.Insert(KeyMethod, r.on.MethodName()))
if err != nil {
panic(err) // or ignore?
}
}
func (r *reporter) record() {
ms := float64(time.Since(r.start) / time.Millisecond)
stats.Record(r.ctx, r.on.LatencyMs().M(ms))
}
// Error records the result as an error.
func (r *reporter) Error() {
r.once.Do(func() {
r.result(ResultError)
})
}
// OK records the result as a success.
func (r *reporter) OK() {
r.once.Do(func() {
r.result(ResultOK)
})
}
func (r *reporter) result(v string) {
var err error
r.ctx, err = tag.New(r.ctx, tag.Insert(KeyResult, v))
if err != nil {
panic(err) // or ignore?
}
r.record()
}