Skip to content

Commit 9caa882

Browse files
authored
Merge pull request #64 from yomek33/dynamic-series-adjustment
Dynamic series adjustment
2 parents 63ee448 + a41aecf commit 9caa882

File tree

5 files changed

+370
-64
lines changed

5 files changed

+370
-64
lines changed

cmd/avalanche.go

+53-21
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"log"
2020
"math/rand"
21+
"os"
2122
"strconv"
2223
"sync"
2324
"time"
@@ -30,36 +31,67 @@ import (
3031
)
3132

3233
var (
33-
metricCount = kingpin.Flag("metric-count", "Number of metrics to serve.").Default("500").Int()
34-
labelCount = kingpin.Flag("label-count", "Number of labels per-metric.").Default("10").Int()
35-
seriesCount = kingpin.Flag("series-count", "Number of series per-metric.").Default("10").Int()
36-
metricLength = kingpin.Flag("metricname-length", "Modify length of metric names.").Default("5").Int()
37-
labelLength = kingpin.Flag("labelname-length", "Modify length of label names.").Default("5").Int()
38-
constLabels = kingpin.Flag("const-label", "Constant label to add to every metric. Format is labelName=labelValue. Flag can be specified multiple times.").Strings()
39-
valueInterval = kingpin.Flag("value-interval", "Change series values every {interval} seconds.").Default("30").Int()
40-
labelInterval = kingpin.Flag("series-interval", "Change series_id label values every {interval} seconds.").Default("60").Int()
41-
metricInterval = kingpin.Flag("metric-interval", "Change __name__ label values every {interval} seconds.").Default("120").Int()
42-
port = kingpin.Flag("port", "Port to serve at").Default("9001").Int()
43-
remoteURL = kingpin.Flag("remote-url", "URL to send samples via remote_write API.").URL()
44-
remotePprofURLs = kingpin.Flag("remote-pprof-urls", "a list of urls to download pprofs during the remote write: --remote-pprof-urls=http://127.0.0.1:10902/debug/pprof/heap --remote-pprof-urls=http://127.0.0.1:10902/debug/pprof/profile").URLList()
45-
remotePprofInterval = kingpin.Flag("remote-pprof-interval", "how often to download pprof profiles.When not provided it will download a profile once before the end of the test.").Duration()
46-
remoteBatchSize = kingpin.Flag("remote-batch-size", "how many samples to send with each remote_write API request.").Default("2000").Int()
47-
remoteRequestCount = kingpin.Flag("remote-requests-count", "how many requests to send in total to the remote_write API.").Default("100").Int()
48-
remoteReqsInterval = kingpin.Flag("remote-write-interval", "delay between each remote write request.").Default("100ms").Duration()
49-
remoteTenant = kingpin.Flag("remote-tenant", "Tenant ID to include in remote_write send").Default("0").String()
50-
tlsClientInsecure = kingpin.Flag("tls-client-insecure", "Skip certificate check on tls connection").Default("false").Bool()
51-
remoteTenantHeader = kingpin.Flag("remote-tenant-header", "Tenant ID to include in remote_write send. The default, is the default tenant header expected by Cortex.").Default("X-Scope-OrgID").String()
34+
metricCount = kingpin.Flag("metric-count", "Number of metrics to serve.").Default("500").Int()
35+
labelCount = kingpin.Flag("label-count", "Number of labels per-metric.").Default("10").Int()
36+
seriesCount = kingpin.Flag("series-count", "Number of series per-metric.").Default("100").Int()
37+
seriesChangeRate = kingpin.Flag("series-change-rate", "The rate at which the number of active series changes over time. Applies to 'gradual-change' mode.").Default("100").Int()
38+
maxSeriesCount = kingpin.Flag("max-series-count", "Maximum number of series to serve. Applies to 'gradual-change' mode.").Default("1000").Int()
39+
minSeriesCount = kingpin.Flag("min-series-count", "Minimum number of series to serve. Applies to 'gradual-change' mode.").Default("100").Int()
40+
metricLength = kingpin.Flag("metricname-length", "Modify length of metric names.").Default("5").Int()
41+
labelLength = kingpin.Flag("labelname-length", "Modify length of label names.").Default("5").Int()
42+
constLabels = kingpin.Flag("const-label", "Constant label to add to every metric. Format is labelName=labelValue. Flag can be specified multiple times.").Strings()
43+
valueInterval = kingpin.Flag("value-interval", "Change series values every {interval} seconds.").Default("30").Int()
44+
labelInterval = kingpin.Flag("series-interval", "Change series_id label values every {interval} seconds.").Default("60").Int()
45+
metricInterval = kingpin.Flag("metric-interval", "Change __name__ label values every {interval} seconds.").Default("120").Int()
46+
seriesChangeInterval = kingpin.Flag("series-change-interval", "Change the number of series every {interval} seconds. Applies to 'gradual-change' and 'double-halve' modes.").Default("10").Int()
47+
seriesOperationMode = kingpin.Flag("series-operation-mode", "Mode of operation: 'gradual-change', 'double-halve'").Default("default").String()
48+
port = kingpin.Flag("port", "Port to serve at").Default("9001").Int()
49+
remoteURL = kingpin.Flag("remote-url", "URL to send samples via remote_write API.").URL()
50+
remotePprofURLs = kingpin.Flag("remote-pprof-urls", "a list of urls to download pprofs during the remote write: --remote-pprof-urls=http://127.0.0.1:10902/debug/pprof/heap --remote-pprof-urls=http://127.0.0.1:10902/debug/pprof/profile").URLList()
51+
remotePprofInterval = kingpin.Flag("remote-pprof-interval", "how often to download pprof profiles.When not provided it will download a profile once before the end of the test.").Duration()
52+
remoteBatchSize = kingpin.Flag("remote-batch-size", "how many samples to send with each remote_write API request.").Default("2000").Int()
53+
remoteRequestCount = kingpin.Flag("remote-requests-count", "how many requests to send in total to the remote_write API.").Default("100").Int()
54+
remoteReqsInterval = kingpin.Flag("remote-write-interval", "delay between each remote write request.").Default("100ms").Duration()
55+
remoteTenant = kingpin.Flag("remote-tenant", "Tenant ID to include in remote_write send").Default("0").String()
56+
tlsClientInsecure = kingpin.Flag("tls-client-insecure", "Skip certificate check on tls connection").Default("false").Bool()
57+
remoteTenantHeader = kingpin.Flag("remote-tenant-header", "Tenant ID to include in remote_write send. The default, is the default tenant header expected by Cortex.").Default("X-Scope-OrgID").String()
5258
)
5359

5460
func main() {
5561
kingpin.Version(version.Print("avalanche"))
5662
log.SetFlags(log.Ltime | log.Lshortfile) // Show file name and line in logs.
57-
kingpin.CommandLine.Help = "avalanche - metrics test server"
63+
kingpin.CommandLine.Help = "avalanche - metrics test server\n" +
64+
"\nSeries Operation Modes:\n" +
65+
" double-halve:\n" +
66+
" Alternately doubles and halves the series count at regular intervals.\n" +
67+
" Usage: ./avalanche --operation-mode=double-halve --series-change-interval=30 --series-count=20\n" +
68+
" Description: This mode alternately doubles and halves the series count at regular intervals.\n" +
69+
" The series count is doubled on one tick and halved on the next, ensuring it never drops below 1.\n" +
70+
"\n" +
71+
" gradual-change:\n" +
72+
" Gradually changes the series count by a fixed rate at regular intervals.\n" +
73+
" Usage: ./avalanche --operation-mode=gradual-change --series-change-interval=30 --series-change-rate=10 --series-count=20\n" +
74+
" Description: This mode gradually increases the series count by seriesChangeRate on each tick up to maxSeriesCount,\n" +
75+
" then decreases it back to the starting value, and repeats this cycle indefinitely.\n" +
76+
" The series count is incremented by seriesChangeRate on each tick, ensuring it never drops below 1."
77+
5878
kingpin.Parse()
79+
if *maxSeriesCount <= *minSeriesCount {
80+
fmt.Fprintf(os.Stderr, "Error: --max-series-count (%d) must be greater than --min-series-count (%d)\n", *maxSeriesCount, *minSeriesCount)
81+
os.Exit(1)
82+
}
83+
if *minSeriesCount < 0 {
84+
fmt.Fprintf(os.Stderr, "Error: --min-series-count must be 0 or higher, got %d\n", *minSeriesCount)
85+
os.Exit(1)
86+
}
87+
if *seriesChangeRate <= 0 {
88+
fmt.Fprintf(os.Stderr, "Error: --series-change-rate must be greater than 0, got %d\n", *seriesChangeRate)
89+
os.Exit(1)
90+
}
5991

6092
stop := make(chan struct{})
6193
defer close(stop)
62-
updateNotify, err := metrics.RunMetrics(*metricCount, *labelCount, *seriesCount, *metricLength, *labelLength, *valueInterval, *labelInterval, *metricInterval, *constLabels, stop)
94+
updateNotify, err := metrics.RunMetrics(*metricCount, *labelCount, *seriesCount, *seriesChangeRate, *maxSeriesCount, *minSeriesCount, *metricLength, *labelLength, *valueInterval, *labelInterval, *metricInterval, *seriesChangeInterval, *seriesOperationMode, *constLabels, stop)
6395
if err != nil {
6496
log.Fatal(err)
6597
}

go.mod

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/prometheus/client_model v0.6.1
1111
github.com/prometheus/common v0.54.0
1212
github.com/prometheus/prometheus v0.53.1
13+
github.com/stretchr/testify v1.9.0
1314
gopkg.in/alecthomas/kingpin.v2 v2.2.6
1415
)
1516

@@ -18,8 +19,11 @@ require (
1819
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect
1920
github.com/beorn7/perks v1.0.1 // indirect
2021
github.com/cespare/xxhash/v2 v2.3.0 // indirect
22+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2123
github.com/nelkinda/http-go v0.0.1 // indirect
24+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
2225
github.com/prometheus/procfs v0.12.0 // indirect
2326
golang.org/x/sys v0.21.0 // indirect
2427
google.golang.org/protobuf v1.34.1 // indirect
28+
gopkg.in/yaml.v3 v3.0.1 // indirect
2529
)

go.sum

+7
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
7171
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
7272
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
7373
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
74+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
75+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
7476
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
7577
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
78+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
7679
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
7780
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
7881
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
@@ -102,6 +105,8 @@ github.com/prometheus/prometheus v0.53.1/go.mod h1:RZDkzs+ShMBDkAPQkLEaLBXpjmDcj
102105
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
103106
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
104107
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
108+
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
109+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
105110
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
106111
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
107112
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -176,6 +181,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
176181
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
177182
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
178183
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
184+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
185+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
179186
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
180187
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
181188
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 commit comments

Comments
 (0)