-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathobservability.go
More file actions
72 lines (64 loc) · 1.79 KB
/
Copy pathobservability.go
File metadata and controls
72 lines (64 loc) · 1.79 KB
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
package lago
import (
"log"
"sort"
"strconv"
)
// DefaultRateLimitThresholds is the default set of usage thresholds at which
// LoggingRateLimitObserver emits a warning.
var DefaultRateLimitThresholds = []float64{0.80, 0.90, 0.95}
// LoggingRateLimitObserver is a ready-to-use OnRateLimitInfo callback that
// logs a warning each time rate limit usage crosses one of the configured
// thresholds.
//
// Example:
//
// client := lago.New().SetApiKey("...")
// client.RetryPolicy.OnRateLimitInfo = lago.NewLoggingRateLimitObserver(nil, nil)
type LoggingRateLimitObserver struct {
thresholds []float64 // sorted descending
logger *log.Logger
}
// NewLoggingRateLimitObserver returns a LoggingRateLimitObserver as a
// RateLimitInfoCallback.
//
// Pass nil for thresholds to use DefaultRateLimitThresholds (80/90/95%).
// Pass nil for logger to use the standard logger.
func NewLoggingRateLimitObserver(thresholds []float64, logger *log.Logger) RateLimitInfoCallback {
if len(thresholds) == 0 {
thresholds = DefaultRateLimitThresholds
}
if logger == nil {
logger = log.Default()
}
sorted := make([]float64, len(thresholds))
copy(sorted, thresholds)
sort.Sort(sort.Reverse(sort.Float64Slice(sorted)))
o := &LoggingRateLimitObserver{thresholds: sorted, logger: logger}
return o.observe
}
func (o *LoggingRateLimitObserver) observe(info *RateLimitInfo) {
pct, ok := info.UsagePct()
if !ok {
return
}
for _, t := range o.thresholds {
if pct >= t {
o.logger.Printf(
"lago: rate limit at %.0f%% (limit=%s, remaining=%s, reset=%ss, %s %s)",
pct*100,
intPtrString(info.Limit),
intPtrString(info.Remaining),
intPtrString(info.Reset),
info.Method, info.URL,
)
return
}
}
}
func intPtrString(v *int) string {
if v == nil {
return "<nil>"
}
return strconv.Itoa(*v)
}