This repository has been archived by the owner on Aug 23, 2023. It is now read-only.
/
builder.go
150 lines (133 loc) · 3.72 KB
/
builder.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// package metricbuilder provides various methods to build metrics, or more specifically MetricData structures
// be aware of this behavior when it comes to the MetricName property:
// | mpo | metricName has %d directive? | outcome |
// |-----|------------------------------|-----------------------------------|
// | 1 | Yes | use directive to always print 1 |
// | >1 | Yes | use directive to print the number |
// | 1 | No | don't use directive |
// | >1 | No | invalid: will panic |
//
package metricbuilder
import (
"fmt"
"strconv"
"strings"
"github.com/grafana/metrictank/schema"
)
type Builder interface {
Info() string
// Build builds a slice of slices of MetricData's( per orgid), with time and value not set yet.
Build(orgs, mpo, period int) [][]schema.MetricData
}
// Simple builds simple metrics by name
type Simple struct {
MetricName string
}
func (s Simple) Info() string {
return "metricName=" + s.MetricName
}
func (s Simple) Build(orgs, mpo, period int) [][]schema.MetricData {
hasDirective := strings.Contains(s.MetricName, "%d")
if mpo > 1 && !hasDirective {
panic("MetricName directive must contain %d when using mpo >1")
}
out := make([][]schema.MetricData, orgs)
for o := 0; o < orgs; o++ {
metrics := make([]schema.MetricData, mpo)
for m := 0; m < mpo; m++ {
name := s.MetricName
if hasDirective {
name = fmt.Sprintf(name, m+1)
}
metrics[m] = schema.MetricData{
Name: name,
OrgId: o + 1,
Interval: period,
Unit: "ms",
Mtype: "gauge",
}
metrics[m].SetId()
}
out[o] = metrics
}
return out
}
// Tagged builds metrics with a name and various tag related options
type Tagged struct {
MetricName string
CustomTags []string
AddTags bool
NumUniqueCustomTags int
NumUniqueTags int
}
func (tb Tagged) Info() string {
return "metricName=" + tb.MetricName
}
func (tb Tagged) Build(orgs, mpo, period int) [][]schema.MetricData {
hasDirective := strings.Contains(tb.MetricName, "%d")
if mpo > 1 && !hasDirective {
panic("MetricName directive must contain %d when using mpo >1")
}
out := make([][]schema.MetricData, orgs)
for o := 0; o < orgs; o++ {
metrics := make([]schema.MetricData, mpo)
for m := 0; m < mpo; m++ {
var tags []string
name := tb.MetricName
if hasDirective {
name = fmt.Sprintf(name, m+1)
}
localTags := []string{
"secondkey=anothervalue",
"thirdkey=onemorevalue",
"region=west",
"os=ubuntu",
"anothertag=somelongervalue",
"manymoreother=lotsoftagstointern",
"afewmoretags=forgoodmeasure",
"onetwothreefourfivesix=seveneightnineten",
"lotsandlotsoftags=morefunforeveryone",
"goodforpeoplewhojustusetags=forbasicallyeverything",
}
if len(tb.CustomTags) > 0 {
if tb.NumUniqueCustomTags > 0 {
var j int
for j = 0; j < tb.NumUniqueCustomTags; j++ {
tags = append(tags, tb.CustomTags[j]+strconv.Itoa(m+1))
}
for j < len(tb.CustomTags) {
tags = append(tags, tb.CustomTags[j])
j++
}
} else {
tags = tb.CustomTags
}
}
if tb.AddTags {
if tb.NumUniqueTags > 0 {
var j int
for j = 0; j < tb.NumUniqueTags; j++ {
tags = append(tags, localTags[j]+strconv.Itoa(m+1))
}
for j < len(localTags) {
tags = append(tags, localTags[j])
j++
}
} else {
tags = localTags
}
}
metrics[m] = schema.MetricData{
Name: name,
OrgId: o + 1,
Interval: period,
Unit: "ms",
Mtype: "gauge",
Tags: tags,
}
metrics[m].SetId()
}
out[o] = metrics
}
return out
}