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 build
To 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 quit
The 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 | bash
The 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.yml
The following flags are accepted:
--help
Print help and exit--version
Print version and exit--prometheus.url
Prometheus base url--config.file
Config file location, defaults to./config.yml
--batch.size
Samples per remote write request, defaults to 500--proxy.listen
Turns on the remote write listener, defaults tofalse
--proxy.listen.port
Port to receive remote write requests, defaults to 3241--environment
Print environment setup script and exit--init
Print sample config file and exit--rules
Print sample alerting rules file and exit--oidc.enabled
Enable authenticated requests--oidc.issuer
OIDC auth token issuer URL--oidc.clientId
OIDC client id--oidc.clientSecret
OIDC client secret--oidc.audience
OIDC audience--prometheus.url.suffix
Allow 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.yml
Data 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-1x50
NOTE: 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.yml
Open 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+0
This 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