forked from elastic/beats
-
Notifications
You must be signed in to change notification settings - Fork 1
/
metrics.go
104 lines (86 loc) · 2.32 KB
/
metrics.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package logp
import (
"bytes"
"fmt"
"sort"
"time"
"github.com/elastic/beats/libbeat/monitoring"
)
// logMetrics logs at Info level the integer expvars that have changed in the
// last interval. For each expvar, the delta from the beginning of the interval
// is logged.
func logMetrics(metricsCfg *LoggingMetricsConfig) {
if metricsCfg.Enabled != nil && *metricsCfg.Enabled == false {
Info("Metrics logging disabled")
return
}
if metricsCfg.Period == nil {
metricsCfg.Period = &defaultMetricsPeriod
}
Info("Metrics logging every %s", metricsCfg.Period)
ticker := time.NewTicker(*metricsCfg.Period)
prevVals := monitoring.MakeFlatSnapshot()
for range ticker.C {
snapshot := snapshotMetrics()
delta := snapshotDelta(prevVals, snapshot)
prevVals = snapshot
if len(delta) == 0 {
Info("No non-zero metrics in the last %s", metricsCfg.Period)
continue
}
metrics := formatMetrics(delta)
Info("Non-zero metrics in the last %s:%s", metricsCfg.Period, metrics)
}
}
// LogTotalExpvars logs all registered expvar metrics.
func LogTotalExpvars(cfg *Logging) {
if cfg.Metrics.Enabled != nil && *cfg.Metrics.Enabled == false {
return
}
zero := monitoring.MakeFlatSnapshot()
metrics := formatMetrics(snapshotDelta(zero, snapshotMetrics()))
Info("Total non-zero values: %s", metrics)
Info("Uptime: %s", time.Now().Sub(startTime))
}
func snapshotMetrics() monitoring.FlatSnapshot {
return monitoring.CollectFlatSnapshot(monitoring.Default, monitoring.Full, true)
}
func snapshotDelta(prev, cur monitoring.FlatSnapshot) map[string]interface{} {
out := map[string]interface{}{}
for k, b := range cur.Bools {
if p, ok := prev.Bools[k]; !ok || p != b {
out[k] = b
}
}
for k, s := range cur.Strings {
if p, ok := prev.Strings[k]; !ok || p != s {
out[k] = s
}
}
for k, i := range cur.Ints {
if p := prev.Ints[k]; p != i {
out[k] = i - p
}
}
for k, f := range cur.Floats {
if p := prev.Floats[k]; p != f {
out[k] = f - p
}
}
return out
}
func formatMetrics(ms map[string]interface{}) string {
keys := make([]string, 0, len(ms))
for key := range ms {
keys = append(keys, key)
}
sort.Strings(keys)
var buf bytes.Buffer
for _, key := range keys {
buf.WriteByte(' ')
buf.WriteString(key)
buf.WriteString("=")
buf.WriteString(fmt.Sprintf("%v", ms[key]))
}
return buf.String()
}