-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathreqlatencycounter.go
70 lines (61 loc) · 2.06 KB
/
reqlatencycounter.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
package web
import (
"context"
"sync/atomic"
"time"
"github.com/signalfx/golib/v3/datapoint"
"github.com/signalfx/golib/v3/timekeeper"
)
// FastRequestLimitDuration is the interface for getting the cutoff time for bad requests.
type FastRequestLimitDuration interface {
Get() time.Duration
}
// ReqLatencyCounter hold static data for the request latency tracking.
type ReqLatencyCounter struct {
fastRequestLimitDuration FastRequestLimitDuration
fastRequests int64
slowRequests int64
timeKeeper timekeeper.TimeKeeper
}
// NewReqLatencyCounter creates a new ReqLatencyCounter
func NewReqLatencyCounter(fastRequestDurationLimit FastRequestLimitDuration) ReqLatencyCounter {
return ReqLatencyCounter{
fastRequestLimitDuration: fastRequestDurationLimit,
timeKeeper: timekeeper.RealTime{},
}
}
// ModStats modifies the metric values for the ReqLatencyCounter.
func (a *ReqLatencyCounter) ModStats(ctx context.Context) {
a.ModStatsTime(RequestTime(ctx))
}
// ModStatsTime modifies the metric values for the ReqLatencyCounter.
func (a *ReqLatencyCounter) ModStatsTime(start time.Time) {
totalDur := a.timeKeeper.Now().Sub(start)
if totalDur > a.fastRequestLimitDuration.Get() {
atomic.AddInt64(&a.slowRequests, 1)
} else {
atomic.AddInt64(&a.fastRequests, 1)
}
}
// appendDimension will blah blah blah
func appendDimensions(dimensions map[string]string, key string, value string) map[string]string {
r := make(map[string]string, len(dimensions)+1)
for k, v := range dimensions {
r[k] = v
}
r[key] = value
return r
}
// Stats gets the metrics for a ReqLatencyCounter.
func (a *ReqLatencyCounter) Stats(dimensions map[string]string) []*datapoint.Datapoint {
now := a.timeKeeper.Now()
getDp := func(key string, value int64) *datapoint.Datapoint {
return datapoint.New(
"ReqLatencyCounter.requestCounts", appendDimensions(dimensions, "requestClass", key),
datapoint.NewIntValue(value), datapoint.Counter, now)
}
return []*datapoint.Datapoint{
getDp("fast", a.fastRequests),
getDp("slow", a.slowRequests),
}
}