-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetrics.go
121 lines (113 loc) · 3.25 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package mkrg
import (
"sort"
"strings"
"github.com/mackerelio/mackerel-client-go"
)
type metricsByName map[string][]mackerel.MetricValue
func (ms metricsByName) Add(metricName string, metricValues []mackerel.MetricValue) {
ms[metricName] = metricValues
}
func (ms metricsByName) MaxValue() float64 {
maxValue := 0.0
for _, metrics := range ms {
for _, m := range metrics {
v := m.Value.(float64)
if v > maxValue {
maxValue = v
}
}
}
return maxValue
}
func (ms metricsByName) Stack(graph graph) {
stackedValue := make(map[int64]float64)
for _, metric := range graph.metrics {
if !metric.stacked {
continue
}
if metrics, ok := ms[metric.name]; ok {
for i, m := range metrics {
w := metrics[i].Value.(float64)
if v, ok := stackedValue[m.Time]; ok {
stackedValue[m.Time] = v + w
metrics[i].Value = v + w
} else {
stackedValue[m.Time] = w
}
}
}
}
}
func (ms metricsByName) ListMetricNames(graph graph) []string {
metricNames := make([]string, 0, len(ms))
for name := range ms {
metricNames = append(metricNames, name)
}
var groupNames []string
groupNameByName := make(map[string]string, len(ms))
metricPriorityByName := make(map[string]int, len(ms))
for i, metric := range graph.metrics {
if strings.ContainsRune(metric.name, '#') {
namePattern := metricNamePattern(metric.name)
for _, name := range metricNames {
match := namePattern.FindStringSubmatch(name)
if len(match) > 1 {
newGroupName, found := match[1], false
groupNameByName[name] = newGroupName
metricPriorityByName[name] = i
for _, groupName := range groupNames {
if groupName == newGroupName {
found = true
break
}
}
if !found {
groupNames = append(groupNames, newGroupName)
}
}
}
} else if _, ok := ms[metric.name]; ok {
metricPriorityByName[metric.name] = i
}
}
sort.Strings(groupNames)
priorityByGroupName := make(map[string]int, len(groupNames))
for i, groupName := range groupNames {
priorityByGroupName[groupName] = i
}
priorityByName := make(map[string]int, len(ms))
for _, metricName := range metricNames {
priorityByName[metricName] = metricPriorityByName[metricName]
if groupName, ok := groupNameByName[metricName]; ok {
priorityByName[metricName] += priorityByGroupName[groupName] * 100
}
}
sort.Slice(metricNames, func(i, j int) bool {
return priorityByName[metricNames[i]] < priorityByName[metricNames[j]]
})
return metricNames
}
func (ms metricsByName) AddMemorySwapUsed() {
if totalMetrics, ok := ms["memory.swap_total"]; ok {
if freeMetrics, ok := ms["memory.swap_free"]; ok {
usedMetrics := make([]mackerel.MetricValue, 0, len(totalMetrics))
for i, j := 0, 0; i < len(totalMetrics) && j < len(freeMetrics); i++ {
for j < len(freeMetrics) && totalMetrics[i].Time > freeMetrics[j].Time {
j++
}
if totalMetrics[i].Time == freeMetrics[j].Time {
usedMetrics = append(usedMetrics, mackerel.MetricValue{
Time: totalMetrics[i].Time,
Value: totalMetrics[i].Value.(float64) - freeMetrics[j].Value.(float64),
})
}
for j < len(freeMetrics) && totalMetrics[i].Time >= freeMetrics[j].Time {
j++
}
}
delete(ms, "memory.swap_free")
ms.Add("memory.swap_used", usedMetrics)
}
}
}