A CLI tool to generate metrics data for the Prometheus monitorig system. It allows you to define time series and values and send them directly to Prometheus using the remote write protocol.
I found this very useful for testing PromQL queries and alerts. Sometimes you don't have the right data in Prometheus or simply no access. This tool lets you simulate the data you need and test your queries against it.
The latest version:
GOPROXY=direct go install github.com/pb82/prometheus-toolbox@latest
A specific version:
GOPROXY=direct go install github.com/pb82/prometheus-toolbox@<version>
NOTE: Go must be installed
Build directly for your platform with go:
$ go buildTo start a local development environment including Prometheus and Grafana use the built-in --environment command.
This prints out a shell script to spin up containers for both applications.
It also sets up a data source in Grafana to connect it to Prometheus.
Either podman or docker, as well as curl are required.
Example:
$ prometheus-toolbox --environment | bash
detected runtime is podman, starting containers. this can take some time...
starting prometheus container from image docker.io/prom/prometheus:latest
starting grafana container from image docker.io/grafana/grafana-oss:latest
creating prometheus datasource
Prometheus is running on port 9090
Grafana is running on port 3000
Grafana credentials are admin/admin
press ctrl-c to quitThe Prometheus and Grafana images can be overridden by exporting the PROMETHEUS_IMAGE or GRAFANA_IMAGE variables:
$ export GRAFANA_IMAGE=docker.io/grafana/grafana-oss:8.5.15 && ./prometheus-toolbox --environment | bashThe environment script checks for the presence of a file with the name rules.yml in the directory it's running.
If present, Prometheus is configured to import alerting and recording rules from it.
A sample rules file can be generated with the following command:
$ prometheus-toolbox --rules > rules.ymlThe following flags are accepted:
--helpPrint help and exit--versionPrint version and exit--prometheus.urlPrometheus base url--config.fileConfig file location, defaults to./config.yml--batch.sizeSamples per remote write request, defaults to 500--proxy.listenTurns on the remote write listener, defaults tofalse--proxy.listen.portPort to receive remote write requests, defaults to 3241--environmentPrint environment setup script and exit--initPrint sample config file and exit--rulesPrint sample alerting rules file and exit--oidc.enabledEnable authenticated requests--oidc.issuerOIDC auth token issuer URL--oidc.clientIdOIDC client id--oidc.clientSecretOIDC client secret--oidc.audienceOIDC audience--prometheus.url.suffixAllow alternate remote write endpoints, in case your receiver uses a different endpoint than the default/api/v1/write
This tool reads from a config file where the simulated time series and values are defined. The format is:
interval: "10s" # Interval between samples, in this case 10 seconds
time_series: # List of time series to simulate
- series: metric_a{label="a"} # Time series (metric name and label list)
values: 1+1x100 # Precalculated samples
- series: metric_a{label="a"} # Another time series
stream: 1+0 # Realtime samples
- series: metric_b{label="a"} #
values: 1+1x50 50+0x50 # Multiple value sequences are possible
- series: metric_c{l1="a",l2="b"} # Multiple labels are possible
values: _x50 1+0x50 # The underscore represents an empty value (no data received). Time still advances. The format for precalculated samples is:
values: 1+1x100 # <initial>(plus or minus)<increment>x<how many samples>
The format for realtime samples is:
stream: 1+1 # <initial>(plus or minus)<increment>
Streaming realtime samples only ends when the user interrupts the program, thus no number of samples is needed.
A basic config file can be created using the --init command:
$ prometheus-toolbox --init > config.ymlData generator: write precalculated samples.
Streaming samples: write realtime data.
Remote write inspector: inspect remote write requests.
Generates data and sends it to a Prometheus instance using the remote write protocol.
NOTE: remote write needs to be specifically enabled in Prometheus with the flag --web.enable-remote-write-receiver
Provide the base URL of the Prometheus instance and a config file, for example:
$ cat config.yaml
---
interval: 10s
time_series:
- series: metric_a{label="a"}
values: 1+0x100 _x50
- series: metric_b{label="b"}
values: 1+1x50 50+0x50 50-1x50NOTE: if you're not familiar with the series and values notation, it is similar to how unit tests with promtool are written. For more information, have a look here.
Run the CLI with the following options:
$ ./prometheus-toolbox --prometheus.url=http://localhost:9090 --config.file=./config.ymlOpen the Prometheus UI and run a query like {__name__~="metric_a|metric_b"}, or go to the graph view.
Samples for both time series should be visible.
Samples are always generated for the past. The time series that produces the most samples (in the above example it is metrics_a) determines how far back in time the samples go.
In the above case 100 samples are generated with an interval of ten seconds between them.
So both series will start at a point in time 1000 seconds in the past.
Samples are batched to avoid sending one huge remote write request. The default batch size is 500.
You can stream continuous samples for series to a Prometheus instances:
$ cat example/config.yaml
---
interval: 10s
time_series:
- series: up{label="a"}
stream: 1+0This will send a sample generated from the field stream every ten seconds.
NOTE: in contrast to values, when providing stream you can't specify the number of samples. Data is generated continuously.
NOTE: you can have both, values and stream for the same series.
This tool can receive remote write requests and expose insights as metrics.
To enable the remote write listener, pass the --proxy.listen flag.
By default, remote write requests are received on port 3241, but this can be overridden using the --proxy.listen.port flag.
When remote write requests are received, prometheus-toolbox will collect data and expose it as metrics.
The metrics can be viewed on the same port as the listener with a GET request.
The following data is collected:
- Request count - how many write requests have been received
- Compressed size - snappy compressed size of the write request in bytes
- Uncompressed size - uncompressed size of the write request in bytes
- Timeseries count - number of time series in write request
- Http headers - present http headers
For example:
Configure prometheus to send write requests to prometheus-toolbox, by adding a remote_write section to prometheus.yaml:
remote_write:
- name: "self"
url: "http://localhost:3241"NOTE: This is assuming that both Prometheus and prometheus-toolbox are running locally.
Then send a GET request to the --proxy.listen endpoint:
$ curl -XGET http://localhost:3241
# HELP prometheus_toolbox_remote_write_compressed_size compressed remote write request size in bytes
# TYPE prometheus_toolbox_remote_write_compressed_size gauge
prometheus_toolbox_remote_write_compressed_size{origin="[::1]:58060"} 112
# HELP prometheus_toolbox_remote_write_header present http headers in remote write requests
# TYPE prometheus_toolbox_remote_write_header gauge
prometheus_toolbox_remote_write_header{header="Authorization",origin="[::1]:58060",value="Bearer 92MO6wrerqwoLWlJZfhunRIRGwl2QgsGl9rkJRI5Ts3mr1oYLBsjw92dREb2QRpfrGn5xvZFC4pwKdSupMTcBHZVRien6oXg8VSFCuAaquF9Wcagem6aHVyewDejqXFfg0m0pgTAf6hqbfNFFe5ysnygnaZfaGNHpKR5SC2VpscTKeHElEvhJUqSHxc6TO9RMzJBXjL2XPi0GMAshLMrP23clY9y9UtByF2cbobH3eYqrbRUocXog..."} 1
prometheus_toolbox_remote_write_header{header="Content-Encoding",origin="[::1]:58060",value="snappy"} 1
prometheus_toolbox_remote_write_header{header="Content-Type",origin="[::1]:58060",value="application/x-protobuf"} 1
prometheus_toolbox_remote_write_header{header="User-Agent",origin="[::1]:58060",value="Prometheus/2.39.1"} 1
prometheus_toolbox_remote_write_header{header="X-Prometheus-Remote-Write-Version",origin="[::1]:58060",value="0.1.0"} 1
# HELP prometheus_toolbox_remote_write_request_count number of received remote write requests
# TYPE prometheus_toolbox_remote_write_request_count counter
prometheus_toolbox_remote_write_request_count{origin="[::1]:58060"} 3
# HELP prometheus_toolbox_remote_write_timeseries_count number of time series in remote write request
# TYPE prometheus_toolbox_remote_write_timeseries_count gauge
prometheus_toolbox_remote_write_timeseries_count{origin="[::1]:58060"} 2
# HELP prometheus_toolbox_remote_write_uncompressed_size uncompressed remote write request size in bytes
# TYPE prometheus_toolbox_remote_write_uncompressed_size gauge
prometheus_toolbox_remote_write_uncompressed_size{origin="[::1]:58060"} 143