promcsv
Turn Prometheus metrics into CSV files - and deliver them to S3 or SFTP.
pip install promcsv
What it does
promcsv turns Prometheus metrics into CSV files for systems that do not speak
Prometheus. It scrapes a configured set of /metrics endpoints on a fixed
interval and writes one CSV file per target per cycle - target outputs are
never combined. Files land atomically in a ready/ directory, are optionally
gzip-compressed and uploaded to S3 or SFTP, and are cleaned up by a retention
sweep so disk usage stays bounded.
It is built to run unattended for months as a systemd service, but it runs just as well in the foreground or from cron.
Supported features
- One CSV per target per cycle with a fixed 5-column schema
(
timestamp,metric,type,labels,value) that never changes shape - Wall-clock-aligned scraping (a 5m interval fires at :00, :05, :10, ...), targets scraped concurrently, one failing target never affects the others
- Optional gzip compression (
.csv.gz), applied once at write time - Upload to S3 (including S3-compatible stores like MinIO; SSE/KMS and
storage class supported) or SFTP (key or password auth, strict host-key
verification), or no upload - consumers pick files up from
ready/ - Flat or per-target remote layout, one config switch
- Atomic file handling everywhere - no partial files, local or remote
- Automatic retention cleanup; upload outages self-recover by draining the backlog once the endpoint returns
status.jsonhealth file for external monitoring and alerting- systemd-native:
Type=notifywatchdog, hardened unit, journald logging - Strict config validation with did-you-mean hints (
--validate-config) - Small footprint: one RPM or wheel; only
requestsandPyYAMLrequired (boto3/paramiko only for the upload target you actually use)
Install
Two options - pick one, do not mix them on one host:
- Option 1 - RPM (Rocky/RHEL 8+): recommended for servers; one command installs everything, including the systemd service.
- Option 2 - pip (any Linux): from PyPI or a wheel file; systemd setup is a short manual step.
Option 1 - install from RPM (Rocky/RHEL 8+, recommended)
Download the RPM from the latest release, then:
dnf install ./python3.12-promcsv-<version>-1.el8.noarch.rpm
vi /etc/promcsv/config.yaml
promcsv -c /etc/promcsv/config.yaml --validate-config
systemctl enable --now promcsv
For S3 or SFTP upload, also install the extra package (it has no python3.12
RPM): python3.12 -m pip install boto3 (S3) or paramiko (SFTP).
Option 2 - install with pip (any Linux)
Prerequisite: Python 3.12 or newer. On Rocky/RHEL 8:
dnf install python3.12 python3.12-pip
Install as root (system-wide), straight from PyPI:
sudo python3.12 -m pip install promcsv
# S3 / SFTP upload extras:
sudo python3.12 -m pip install boto3 # when upload.target is s3
sudo python3.12 -m pip install paramiko # when upload.target is sftp
Offline hosts: download the wheel from the
latest release and
sudo python3.12 -m pip install ./promcsv-<version>-py3-none-any.whl.
Note: on hosts with a hardened root umask (0027/0077) pip creates
unreadable package directories and other users then get
ModuleNotFoundError - install with
sudo sh -c 'umask 022 && python3.12 -m pip install promcsv'.
Create the configuration from the built-in example and validate it:
install -d -m 0755 /etc/promcsv
promcsv --print-config > /etc/promcsv/config.yaml # then edit
promcsv -c /etc/promcsv/config.yaml --validate-config
The tool is now fully usable from the command line
(promcsv -c /etc/promcsv/config.yaml, or --once from cron). To run it as
a systemd service, complete the one-time setup below - the RPM path does all
of this automatically.
Run as a systemd service (pip installs)
One-time host setup:
# service user and directories
useradd -r -s /sbin/nologin promcsv
install -d -o promcsv -g promcsv /var/data/promcsv
chgrp promcsv /etc/promcsv /etc/promcsv/config.yaml
chmod 0750 /etc/promcsv; chmod 0640 /etc/promcsv/config.yaml
# verify the service user can load the package (catches permission problems)
sudo -u promcsv /usr/bin/python3.12 -c "import promcsv" # must print nothing
# unit, log rotation and credentials template
promcsv --print-unit > /usr/lib/systemd/system/promcsv.service
promcsv --print-logrotate > /etc/logrotate.d/promcsv
promcsv --print-env > /etc/promcsv/env && chmod 0600 /etc/promcsv/env
systemctl daemon-reload
systemctl enable --now promcsv
The printed unit's ExecStart= assumes /usr/local/bin/promcsv; if
command -v promcsv shows a different path (e.g. a venv), edit ExecStart=
in the installed unit accordingly.
CLI
promcsv -c /etc/promcsv/config.yaml [--validate-config | --once]
-c, --config FILE- path to the YAML config (required).--validate-config- load and validate the config, print a report, and exit 0 (valid) or 2 (invalid). Read-only; touches nothing.--once- run a single scrape cycle and exit: 0 if at least one target was scraped successfully, 1 otherwise. Cron fallback / smoke test.--print-config- print the example configuration and exit.--print-unit- print the systemd unit and exit. The printedExecStart=assumes/usr/local/bin/promcsv; ifcommand -v promcsvshows a different path (e.g. a venv), editExecStart=accordingly.--print-logrotate- print the logrotate snippet and exit.--print-env- print the/etc/promcsv/envtemplate and exit.--version- print version and exit.
The --print-* flags need no configuration file and are mutually exclusive
with each other and with --once/--validate-config.
Exit codes:
| Code | Meaning |
|---|---|
| 0 | clean shutdown / successful --once cycle |
| 1 | runtime fatal (lock held, stuck scrape threads, unhandled error) |
| 2 | configuration error |
The unit sets RestartPreventExitStatus=2: a broken config exits 2 and is
not restarted, so systemd does not loop on an error no retry can fix.
Runtime failures exit 1 and are restarted after RestartSec.
Documentation
- Usage guide - the CSV format specification for consumers, the directory lifecycle, S3 and SFTP upload setup, monitoring and alerting, and operational best practices.
- Annotated example configuration -
every parameter documented in place (also available via
promcsv --print-config).
Build
Build the RPM (Rocky/RHEL 8+)
One-time build-host prerequisites:
dnf install rpm-build python3.12-devel python3.12-pip \
python3.12-setuptools python3.12-wheel systemd
python3.12 -m pip install build
Then:
./packaging/build-rpm.sh
The artifacts are written to dist/:
python3.12-promcsv-<version>-1.el8.noarch.rpm (install this) and the
matching .src.rpm (for rebuilding on other EL releases).
Build the wheel
No prerequisites beyond Python 3.12 - no venv, no test dependencies:
python3.12 -m pip install build
python3.12 -m build --wheel
The artifact is written to dist/:
promcsv-<version>-py3-none-any.whl - that single file is what you copy to
the target host.
Development
Running the tests requires a one-time setup (a virtualenv with the package and the test tools):
python3.12 -m venv .venv
. .venv/bin/activate
pip install -e ".[dev]"
Then:
pytest -q -m "not slow" # default run (fast, skips the soak test)
pytest -q # everything, including the slow soak test
pytest -q -m "not slow" --cov=promcsv --cov-branch --cov-report=term-missing # with coverage
To build the RPM or the wheel, see the Build section - neither needs the virtualenv or the test dependencies.
Releasing
Releases are fully automated by GitHub Actions on tag push:
# 1. bump the version in pyproject.toml, src/promcsv/__init__.py and the RPM
# spec (new changelog entry), and update the two tag-pinned README links -
# the test suite fails if any of these is missed
# 2. then:
git commit -am "promcsv vX.Y.Z: ..."
git tag vX.Y.Z
git push origin main vX.Y.Z
The release workflow verifies the tag (matches the version, commit is on main), runs the full test suite, builds the wheel/sdist and the RPM (in a Rocky Linux 8 container), publishes to PyPI via Trusted Publishing (after the required environment approval), and creates the GitHub release with the wheel and RPM attached. The manual Build instructions above remain as a fallback.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file promcsv-1.4.2.tar.gz.
File metadata
- Download URL: promcsv-1.4.2.tar.gz
- Upload date:
- Size: 88.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72c4a0033c5f5e9ae136db5aeda5ff1141bf8b4b99718b8c8fda9dcc12946a65
|
|
| MD5 |
54afbb751b9963701c7ddc174f4da75b
|
|
| BLAKE2b-256 |
809ce6a5f59ef7f3b159cc8748b15ae6b9d159ca94570b5ff04ec953b213f143
|
Provenance
The following attestation bundles were made for promcsv-1.4.2.tar.gz:
Publisher:
release.yml on bennybrit/promcsv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promcsv-1.4.2.tar.gz -
Subject digest:
72c4a0033c5f5e9ae136db5aeda5ff1141bf8b4b99718b8c8fda9dcc12946a65 - Sigstore transparency entry: 2255973511
- Sigstore integration time:
-
Permalink:
bennybrit/promcsv@9f0ecffc2820c319b79606c8764b30eeb3dc3110 -
Branch / Tag:
refs/tags/v1.4.2 - Owner: https://github.com/bennybrit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9f0ecffc2820c319b79606c8764b30eeb3dc3110 -
Trigger Event:
push
-
Statement type:
File details
Details for the file promcsv-1.4.2-py3-none-any.whl.
File metadata
- Download URL: promcsv-1.4.2-py3-none-any.whl
- Upload date:
- Size: 40.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44803838966b69143e6c06896525887729a2832917e20d9f15fc9a79aac4c6d6
|
|
| MD5 |
f3e201103d8baa85fdb7b2ce50c114a3
|
|
| BLAKE2b-256 |
98a65e02733b1eed9fba9728bb9eb4a16d3c17a72582126aa0854f3da0c6ea94
|
Provenance
The following attestation bundles were made for promcsv-1.4.2-py3-none-any.whl:
Publisher:
release.yml on bennybrit/promcsv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promcsv-1.4.2-py3-none-any.whl -
Subject digest:
44803838966b69143e6c06896525887729a2832917e20d9f15fc9a79aac4c6d6 - Sigstore transparency entry: 2255973516
- Sigstore integration time:
-
Permalink:
bennybrit/promcsv@9f0ecffc2820c319b79606c8764b30eeb3dc3110 -
Branch / Tag:
refs/tags/v1.4.2 - Owner: https://github.com/bennybrit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9f0ecffc2820c319b79606c8764b30eeb3dc3110 -
Trigger Event:
push
-
Statement type: