Skip to content

Commit e618047

Browse files
committed
promtorture v0.2
Switch to metric vectors. Greatly speeds startup, though still takes 30s to scrape 6.5M metrics with wide labels.
1 parent f4ebd81 commit e618047

File tree

1 file changed

+77
-63
lines changed

1 file changed

+77
-63
lines changed

testcases/promtorture/internal/generator/generator.go

Lines changed: 77 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,23 @@ type Config struct {
1919
}
2020

2121
type target struct {
22-
targetNumber int
23-
targetIndexes []int
24-
targetLabels prometheus.Labels
25-
infoMetric *prometheus.Gauge
26-
gaugeMetrics []prometheus.Gauge
22+
targetNumber int
23+
}
24+
25+
func (t target) targetIndexes(m metrics) []int {
26+
indexes := make([]int, len(m.cfg.Targets))
27+
remainder := t.targetNumber
28+
for i := 0; i < len(m.cfg.Targets); i++ {
29+
indexes[i] = remainder % m.cfg.Targets[i]
30+
remainder = remainder / m.cfg.Targets[i]
31+
}
32+
return indexes
2733
}
2834

2935
// string representation of the target labels
30-
func (t *target) indexesString() string {
36+
func (t *target) indexesString(m metrics) string {
3137
s := ""
32-
for i, v := range t.targetIndexes {
38+
for i, v := range t.targetIndexes(m) {
3339
if i > 0 {
3440
s += ","
3541
}
@@ -38,62 +44,38 @@ func (t *target) indexesString() string {
3844
return s
3945
}
4046

41-
func createTarget(cfg Config, targetNumber int, targetIndexes []int) target {
42-
t := target{
43-
targetNumber: targetNumber,
44-
targetIndexes: targetIndexes,
45-
}
46-
t.targetLabels = prometheus.Labels{}
47-
for i, v := range targetIndexes {
48-
t.targetLabels["target_label_"+strconv.Itoa(i)] = strconv.Itoa(v)
47+
func (t target) targetLabels(m metrics) []string {
48+
indexes := t.targetIndexes(m)
49+
labels := make([]string, len(indexes))
50+
for i, v := range indexes {
51+
labels[i] = strconv.Itoa(v)
4952
}
53+
return labels
54+
}
5055

51-
log.Printf("Creating target %d with indexes %v, labels %v", targetNumber, targetIndexes, t.targetLabels)
52-
53-
indexesStr := t.indexesString()
54-
55-
if cfg.InfoMetricsLabels > 0 {
56-
infoMetricLabels := prometheus.Labels{}
57-
// copy the target labels to the info metric label set
58-
for k, v := range t.targetLabels {
59-
infoMetricLabels[k] = v
60-
}
61-
// add info labels. The names must be consistent for each
62-
// target, and the values should differ since we presume the
63-
// targets are unique. So the target indexes will be used for
64-
// the info-metric values.
65-
for i := 0; i < cfg.InfoMetricsLabels; i++ {
66-
infoMetricLabels["info_label_"+strconv.Itoa(i)] = indexesStr
67-
}
68-
infoMetric := prometheus.NewGauge(prometheus.GaugeOpts{
69-
Name: "info_metric",
70-
Help: "Info metric",
71-
ConstLabels: infoMetricLabels,
72-
})
73-
t.infoMetric = &infoMetric
74-
//log.Printf("Created info-metric %s", (*t.infoMetric).Desc().String())
56+
func (t target) setValues(m metrics, gaugeValue float64) {
57+
if m.cfg.InfoMetricsLabels > 0 {
58+
labels := t.infoLabels(m)
59+
m.infoMetric.WithLabelValues(labels...).Set(1)
7560
}
76-
77-
t.gaugeMetrics = make([]prometheus.Gauge, cfg.GaugeMetrics)
78-
for i := 0; i < cfg.GaugeMetrics; i++ {
79-
t.gaugeMetrics[i] = prometheus.NewGauge(prometheus.GaugeOpts{
80-
Name: fmt.Sprintf("gauge_metric_%d", i),
81-
Help: fmt.Sprintf("Gauge metric %d", i),
82-
ConstLabels: t.targetLabels,
83-
})
84-
//log.Printf("Created gauge metric %s", t.gaugeMetrics[i].Desc().String())
61+
for i := 0; i < m.cfg.GaugeMetrics; i++ {
62+
labels := t.targetLabels(m)
63+
m.gaugeMetrics[i].WithLabelValues(labels...).Set(gaugeValue)
8564
}
86-
87-
return t
8865
}
8966

90-
func (t *target) register(reg *prometheus.Registry) {
91-
if t.infoMetric != nil {
92-
reg.MustRegister(*t.infoMetric)
93-
}
94-
for _, m := range t.gaugeMetrics {
95-
reg.MustRegister(m)
67+
func (t target) infoLabels(m metrics) []string {
68+
labels := t.targetLabels(m)
69+
for i := 0; i < m.cfg.InfoMetricsLabels; i++ {
70+
labels = append(labels, fmt.Sprintf("t_%d_i_%d", t.targetNumber, i))
9671
}
72+
return labels
73+
}
74+
75+
type metrics struct {
76+
cfg Config
77+
infoMetric *prometheus.GaugeVec
78+
gaugeMetrics []*prometheus.GaugeVec
9779
}
9880

9981
func CreateRegistry(cfg Config) *prometheus.Registry {
@@ -113,15 +95,47 @@ func CreateRegistry(cfg Config) *prometheus.Registry {
11395

11496
reg := prometheus.NewRegistry()
11597

98+
targetLabelNames := make([]string, len(cfg.Targets))
99+
infoMetricLabelNames := make([]string, len(targetLabelNames)+cfg.InfoMetricsLabels)
100+
for i, _ := range cfg.Targets {
101+
targetLabelNames[i] = fmt.Sprintf("target_label_%d", i)
102+
infoMetricLabelNames[i] = targetLabelNames[i]
103+
}
104+
for i := len(cfg.Targets); i < (cfg.InfoMetricsLabels + len(cfg.Targets)); i++ {
105+
infoMetricLabelNames[i] = fmt.Sprintf("info_label_%d", i)
106+
}
107+
108+
metrics := metrics{
109+
cfg: cfg,
110+
infoMetric: prometheus.NewGaugeVec(prometheus.GaugeOpts{
111+
Name: "info_metric",
112+
Help: "Info metric",
113+
}, infoMetricLabelNames),
114+
gaugeMetrics: make([]*prometheus.GaugeVec, cfg.GaugeMetrics),
115+
}
116+
for i := 0; i < cfg.GaugeMetrics; i++ {
117+
metrics.gaugeMetrics[i] = prometheus.NewGaugeVec(prometheus.GaugeOpts{
118+
Name: fmt.Sprintf("gauge_metric_%d", i),
119+
Help: fmt.Sprintf("Gauge metric %d", i),
120+
}, targetLabelNames)
121+
}
122+
123+
targets := make([]target, totalTargets)
116124
for targetNumber := 0; targetNumber < totalTargets; targetNumber++ {
117-
remainder := targetNumber
118-
for i := 0; i < len(targetCounters); i++ {
119-
targetCounters[i] = remainder % cfg.Targets[i]
120-
remainder = remainder / cfg.Targets[i]
121-
}
125+
// Yeah, this is pointless memory use for now to duplicate the
126+
// array index as a field in each struct. But it'll make it
127+
// easier when I want to give the targets some more brains
128+
// later.
129+
t := targets[targetNumber]
130+
t.targetNumber = targetNumber
131+
t.setValues(metrics, float64(t.targetNumber))
132+
}
122133

123-
t := createTarget(cfg, targetNumber, targetCounters)
124-
t.register(reg)
134+
if cfg.InfoMetricsLabels > 0 {
135+
reg.MustRegister(metrics.infoMetric)
136+
}
137+
for i := 0; i < cfg.GaugeMetrics; i++ {
138+
reg.MustRegister(metrics.gaugeMetrics[i])
125139
}
126140

127141
return reg

0 commit comments

Comments
 (0)