-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerator.go
135 lines (113 loc) · 2.75 KB
/
generator.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
package main
import (
"fmt"
"math/rand"
"strings"
"sync"
"time"
"github.com/m3db/prometheus_remote_client_golang/promremote"
)
type timeSeries struct {
promremote.TSList
}
func (ts *timeSeries) String() string {
lines := []string{}
for _, row := range ts.TSList {
var (
metricName = ""
labelVals = []string{}
)
for _, label := range row.Labels {
if label.Name == "__name__" {
metricName = label.Value
continue
}
labelVals = append(labelVals, fmt.Sprintf("%s=\"%s\"", label.Name, label.Value))
}
lines = append(lines, fmt.Sprintf(
"%s{%s} %d",
metricName, strings.Join(labelVals, ","), int64(row.Datapoint.Value),
))
}
return strings.Join(lines, "\n")
}
// generateMetrics generates random metrics data in open metrics format
func generateMetrics(conf *Config) *timeSeries {
var (
ts = promremote.TSList{}
wg = sync.WaitGroup{}
)
wg.Add(len(conf.Metrics))
for _, m := range conf.Metrics {
go func(mt Metric) {
defer wg.Done()
labels := labelCombos(mt.Labels)
maxCardinality := len(labels)
if mt.MaxCardinality > 0 && mt.MaxCardinality < maxCardinality {
maxCardinality = mt.MaxCardinality
}
for i := 0; i < maxCardinality; i++ {
currLabels := []promremote.Label{
{
Name: "__name__",
Value: mt.Name,
},
}
for key, value := range labels[i] {
currLabels = append(currLabels, promremote.Label{
Name: key,
Value: value,
})
}
randIn := mt.ValueMax - mt.ValueMin
if randIn <= 0 {
randIn = 10
}
val := float64(rand.Intn(randIn) + mt.ValueMin)
if mt.Value != nil {
val = *mt.Value
}
ts = append(ts, promremote.TimeSeries{
Labels: currLabels,
Datapoint: promremote.Datapoint{
Timestamp: time.Now(),
Value: val,
},
})
}
}(m)
}
wg.Wait()
return &timeSeries{ts}
}
func labelCombos(labels map[string][]string) []map[string]string {
var res []map[string]string
labelComboHelper(labels, []string{}, map[string]string{}, &res)
return res
}
func labelComboHelper(labels map[string][]string, keys []string, cur map[string]string, res *[]map[string]string) {
if len(cur) == len(labels) {
// Make a copy of the current combination before appending it to the result
copy := make(map[string]string)
for k, v := range cur {
copy[k] = v
}
*res = append(*res, copy)
return
}
// Iterate over the label keys in sorted order
var sortedKeys []string
for k := range labels {
sortedKeys = append(sortedKeys, k)
}
for _, k := range sortedKeys {
if _, ok := cur[k]; !ok {
for _, v := range labels[k] {
cur[k] = v
labelComboHelper(labels, append(keys, k), cur, res)
}
// Remove the current label from the current combination
delete(cur, k)
}
}
}