/
metric_template.go
95 lines (87 loc) · 2.1 KB
/
metric_template.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
package report
import (
"math"
"sort"
)
// MetricTemplate extracts a metric row from a node
type MetricTemplate struct {
ID string `json:"id"`
Label string `json:"label,omitempty"`
Format string `json:"format,omitempty"`
Group string `json:"group,omitempty"`
Priority float64 `json:"priority,omitempty"`
}
// MetricRow returns the row for a node
func (t MetricTemplate) MetricRow(n Node) (MetricRow, bool) {
metric, ok := n.Metrics.Lookup(t.ID)
if !ok {
return MetricRow{}, false
}
row := MetricRow{
ID: t.ID,
Label: t.Label,
Format: t.Format,
Group: t.Group,
Priority: t.Priority,
Metric: &metric,
}
if s, ok := metric.LastSample(); ok {
row.Value = toFixed(s.Value, 2)
}
return row, true
}
// MetricTemplates is a mergeable set of metric templates
type MetricTemplates map[string]MetricTemplate
// MetricRows returns the rows for a node
func (e MetricTemplates) MetricRows(n Node) []MetricRow {
if len(e) == 0 {
return nil
}
rows := make([]MetricRow, 0, len(e))
for _, template := range e {
if row, ok := template.MetricRow(n); ok {
rows = append(rows, row)
}
}
if len(rows) == 0 {
return nil
}
sort.Sort(MetricRowsByPriority(rows))
return rows
}
// Copy returns a value copy of the metadata templates
func (e MetricTemplates) Copy() MetricTemplates {
if e == nil {
return nil
}
result := make(MetricTemplates, len(e))
for k, v := range e {
result[k] = v
}
return result
}
// Merge merges two sets of MetricTemplates so far just ignores based
// on duplicate id key
func (e MetricTemplates) Merge(other MetricTemplates) MetricTemplates {
if e == nil && other == nil {
return nil
}
if len(other) > len(e) {
e, other = other, e
}
if len(other) == 0 {
return e
}
result := e.Copy()
for k, v := range other {
if existing, ok := result[k]; !ok || existing.Priority < v.Priority {
result[k] = v
}
}
return result
}
// toFixed truncates decimals of float64 down to specified precision
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(int64(num*output)) / output
}