Synthetic PCP archive generator from declarative YAML workload profiles
Project description
pmlogsynth
Generate synthetic PCP v3 archives from declarative YAML workload
profiles — no running pmcd, no root access, no real hardware required.
Designed for testing PCP-based monitoring pipelines, reproducing incidents at arbitrary historical timestamps, and generating load-shaped datasets for analysis tooling.
Installation
Prerequisites: PCP (python3-pcp / cpmapi) is a hard dependency — it is
required at import time for metric type and unit constants, not just for archive
writing. All tests (unit, integration, and E2E) need PCP's Python bindings available.
Linux (Debian/Ubuntu):
sudo apt-get install pcp python3-pcp
pip install pcp-pmlogsynth
Linux (RHEL/Fedora):
sudo dnf install pcp python3-pcp
pip install pcp-pmlogsynth
macOS (Homebrew): PCP compiles its Python bindings against Homebrew's Python.
The bindings are only available to that specific Python — if you run pmlogsynth
or its tests from a different Python (system, pyenv, conda), import cpmapi will fail.
Use the provided setup script, which handles venv creation correctly on all platforms:
./setup-venv.sh
source .venv/bin/activate
From source:
git clone https://github.com/tallpsmith/pmlogsynth
cd pmlogsynth
./setup-venv.sh
source .venv/bin/activate
Quick Start
1. Create a profile
docs/spike.yml is ready to use — or write your own:
# docs/spike.yml
meta:
hostname: demo-host
timezone: UTC
duration: 10m
interval: 60
host:
profile: generic-small
phases:
- name: baseline
duration: 5m
cpu:
utilization: 0.15
- name: spike
duration: 5m
cpu:
utilization: 0.90
2. Validate your profile
pmlogsynth --validate docs/spike.yml
# Exit 0 = valid, Exit 1 = error (stderr shows what's wrong)
Note:
repeat: dailycannot be combined with other phases — validation will reject it.
3. Generate the archive
pmlogsynth -o ./generated-archives/spike docs/spike.yml
# Creates: generated-archives/spike.0 spike.index spike.meta
Note:
generated-archives/is gitignored — a safe scratch space for locally generated archives.
4. Verify with PCP tools
pmlogcheck ./generated-archives/spike
pmval -a ./generated-archives/spike kernel.all.cpu.user
pmrep -a ./generated-archives/spike -o csv kernel.all.cpu.user mem.util.used
5. Explore available options
pmlogsynth --list-profiles # show hardware profiles
pmlogsynth --list-metrics # show all producible PCP metrics
pmlogsynth --show-schema # dump the full profile schema (for AI agents)
6. Generate profiles with AI
If you're using Claude Code with this repo checked out, two built-in skills can generate YAML profiles from plain-English descriptions, validate them, and generate the actual PCP archives — all in one step:
Single-host workload profiles — just describe the scenario:
> simulate a 24-hour web server with overnight quiet, morning ramp, and daytime peak
> create a 1-hour archive of a memory-constrained host under heavy disk I/O
> take docs/spike.yml and add memory pressure during the spike phase
Fleet profiles (multiple hosts with bad actors) — describe the fleet:
> generate a fleet of 20 web servers where 3 have CPU saturation problems
> I need a 50-host database cluster on memory-optimized hardware with some hosts
showing memory pressure and disk thrashing
> create a small 5-host dev cluster with normal web traffic for an hour
The skills bundle the full schema as context, validate the output, and run
pmlogsynth to generate the PCP archives — ready to inspect with pmstat,
pmval, or pmrep. All output goes to generated-archives/.
Bundled Hardware Profiles
| Name | CPUs | RAM | Disks | NICs |
|---|---|---|---|---|
generic-small |
2 | 8 GB | 1× NVMe | 1× 10GbE |
generic-medium |
4 | 16 GB | 1× NVMe | 1× 10GbE |
generic-large |
8 | 32 GB | 2× NVMe | 1× 10GbE |
generic-xlarge |
16 | 64 GB | 2× NVMe | 2× 10GbE |
compute-optimized |
8 | 16 GB | 1× NVMe | 1× 10GbE |
memory-optimized |
4 | 64 GB | 1× NVMe | 1× 10GbE |
storage-optimized |
4 | 16 GB | 4× HDD | 1× 10GbE |
Use host.profile: <name> in your profile, or add your own profiles to
~/.pcp/pmlogsynth/profiles/.
Profile Format
Full YAML schema documentation — all fields, types, defaults, valid ranges,
and constraints — is in docs/profile-format.md.
A complete, ready-to-run example covering all four stressor domains is in
docs/complete-example.yml.
Relative start times
The meta.start field accepts a relative offset in addition to absolute
ISO 8601 timestamps. A relative offset is a PCP interval string prefixed with
-, resolved against the clock at invocation time:
meta:
start: -90m # 90 minutes ago
start: -2h # 2 hours ago
start: -1h30m # 1 hour 30 minutes ago
start: -3d # 3 days ago
start: -2days # same — PCP interval strings accepted
This is useful for replaying realistic-looking archives anchored to "now" —
for example, a simulated spike that started an hour ago. Positive offsets
(+30m) and bare - are rejected with a descriptive error.
Fleet Mode
Generate a fleet of PCP archives — one per host — from a single self-contained fleet profile. All workload definitions are inline — no external files needed. Each host gets per-host stressor jitter for realistic variation across the fleet.
# Preview host assignments without generating archives
pmlogsynth fleet --dry-run fleet-profile.yml
# Generate a 20-host fleet with deterministic assignment
pmlogsynth fleet --seed 42 -o ./generated-archives/my-fleet fleet-profile.yml
The output directory contains one PCP archive per host plus a fleet.manifest
YAML file recording hostnames, roles, jitter factors, and the seed.
See docs/profile-format.md for
the full fleet YAML schema.
Metrics
71 PCP metrics — pmlogsynth --list-metrics or man pmlogsynth.
CLI Reference
Full CLI reference — man pmlogsynth.
Contributing
See CONTRIBUTING.md for dev setup, test structure, and PR conventions.
Project details
Release history Release notifications | RSS feed
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 pcp_pmlogsynth-0.5.0rc1.tar.gz.
File metadata
- Download URL: pcp_pmlogsynth-0.5.0rc1.tar.gz
- Upload date:
- Size: 585.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f7e50597070ab3c9d03e500b5fce3d6a5fafd0bdb5cf55b602c937eac6b41b7
|
|
| MD5 |
b4bdd359a503032a963efc8235f1b8cf
|
|
| BLAKE2b-256 |
a147ed88c12dc2d729a0ae66c56fd0b5635857a71d7f053c72eb6485d8dc6435
|
Provenance
The following attestation bundles were made for pcp_pmlogsynth-0.5.0rc1.tar.gz:
Publisher:
release.yml on tallpsmith/pmlogsynth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pcp_pmlogsynth-0.5.0rc1.tar.gz -
Subject digest:
3f7e50597070ab3c9d03e500b5fce3d6a5fafd0bdb5cf55b602c937eac6b41b7 - Sigstore transparency entry: 1153314758
- Sigstore integration time:
-
Permalink:
tallpsmith/pmlogsynth@eaa907ab440656205074ae76b03b55c4f9d80a31 -
Branch / Tag:
refs/tags/v0.5.0-rc1 - Owner: https://github.com/tallpsmith
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@eaa907ab440656205074ae76b03b55c4f9d80a31 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pcp_pmlogsynth-0.5.0rc1-py3-none-any.whl.
File metadata
- Download URL: pcp_pmlogsynth-0.5.0rc1-py3-none-any.whl
- Upload date:
- Size: 59.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1db77162f127870bfd36af1369a8119681f451263d5cca790d719b1575b35eea
|
|
| MD5 |
d8948c921a783d8181d5a228ec7b3c15
|
|
| BLAKE2b-256 |
9bbf80a8935735b6058f7a558908d17c1fa099ce5ac80d2c95c147bf2914c9c4
|
Provenance
The following attestation bundles were made for pcp_pmlogsynth-0.5.0rc1-py3-none-any.whl:
Publisher:
release.yml on tallpsmith/pmlogsynth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pcp_pmlogsynth-0.5.0rc1-py3-none-any.whl -
Subject digest:
1db77162f127870bfd36af1369a8119681f451263d5cca790d719b1575b35eea - Sigstore transparency entry: 1153314907
- Sigstore integration time:
-
Permalink:
tallpsmith/pmlogsynth@eaa907ab440656205074ae76b03b55c4f9d80a31 -
Branch / Tag:
refs/tags/v0.5.0-rc1 - Owner: https://github.com/tallpsmith
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@eaa907ab440656205074ae76b03b55c4f9d80a31 -
Trigger Event:
release
-
Statement type: