
Description
Render Axiom metrics query results (application/vnd.metrics.v3+json) as line charts. Zero-dependency Unicode/ASCII by default; upgrades to inline PNG/SVG/sixel via gnuplot when present. Use when you have a metrics v3 query response and want to see the series as a chart in the terminal or transcript.
SKILL.md
metrics-chart
Turns a metrics query response into a multi-series line chart.
Input is exactly the body the Axiom metrics query service returns for
application/vnd.metrics.v3+json — defined in the metrics query service
(service/query, JsonV3QueryResponse in src/server.rs). It is a
regularly-sampled, multi-series time series; this skill draws it.
TL;DR
# From a file, stdout picks the best renderer for your terminal:
python3 scripts/metrics_chart.py response.json
# From a pipe (e.g. straight off the query API):
curl ... -H 'Accept: application/vnd.metrics.v3+json' | python3 scripts/metrics_chart.py
# Force a zero-dependency ASCII chart (always works, anywhere):
python3 scripts/metrics_chart.py --format ascii response.json
Aggregate first. Charts are only readable with a handful of series. The cleanest result comes from a query that already groups/aggregates to a few lines (e.g.
group by statusrather than per-pod). This skill's series reduction (below) is a safety net for high-cardinality results, not a substitute for aggregating in the query.
Input format (vnd.metrics.v3+json)
{
"metadata": {
"group_keys": ["code", "method"],
"warnings": [],
"unit": "ms",
"custom_unit": "millisec"
},
"series": [
{
"metric": "http_requests",
"tags": { "code": 200, "method": "GET", "path": "/" },
"start": 1750753164,
"resolution": 60,
"data": [420.0, 42.0, 30.0, 9.0, 15.0, 18.0]
}
]
}
| Field | Meaning |
|---|---|
metadata.group_keys | Tags the query grouped on → used to build legend labels. |
metadata.warnings | Shown as ⚠ captions under the chart. |
metadata.unit | Canonical y-axis unit (ms, bytes, …). |
metadata.custom_unit | Human y-axis label; preferred over unit when present. |
series[].start | Unix seconds (UTC) of data[0]. |
series[].resolution | Seconds per point; x[i] = start + resolution*i (uniform spacing). |
series[].data | Y values; null = gap (the line breaks, it is not drawn as 0). |
The parser also accepts v2/v2a (same shape with an extra per-series summary,
ignored) and the v0/v1 bare-array form, so you can feed older responses too.
Behaviour
- Labels come from
group_keysvalues joined with|→200 | GET(notcode=200,method=GET). Withoutgroup_keys, falls back tok=vtags. - Local time axis by default;
--tz UTCor--tz Europe/Berlinto override. - Gaps:
nullpoints break the line. - Series reduction (unless
--all), in order:- Collapse overlapping series whose lines essentially coincide (within
--eps, default 2% of the y-range); the most prominent is kept. - Top-N by peak value (
--top, default 8). - The legend prints how many were dropped, e.g.
showing 8 of 30 series (5 overlapping, 17 low/hidden), plus the aggregate-your-query tip.
- Collapse overlapping series whose lines essentially coincide (within
Output formats
--format auto (default) picks the best renderer for the context:
- an inline image when
gnuplotis installed and the terminal supports images (Kitty/Ghostty, iTerm2); - a PNG file plus a "display this file" instruction when output is
piped/captured (e.g. an AI agent harness) and
gnuplotis installed — the agent then displays the file; - ASCII in a plain terminal, or whenever
gnuplotis unavailable.
Force a specific backend with --format:
--format | Needs | Output |
|---|---|---|
auto | — | inline image, else a PNG file + display instruction when piped, else ASCII |
ascii | nothing | Unicode braille line chart; renders in any terminal/transcript/CI log. |
png | gnuplot | PNG; displayed inline (Kitty/iTerm2) or written to --output/temp. |
svg | gnuplot | SVG written to --output or a temp file (path printed). |
sixel | gnuplot | sixel stream to stdout (terminals with sixel support). |
If an image format is requested but gnuplot is missing, it prints a note and
falls back to ASCII — it never hard-fails.
Using from an AI agent / harness
Terminal harnesses (e.g. pi) collapse tool output and don't repaint inline
ANSI, so ASCII charts come out monochrome and folded. Prefer images: render
a file and let the agent display it. With --format auto (the default) this is
automatic whenever output is piped and gnuplot is installed — the skill
writes a PNG and prints:
metrics-chart: wrote image to /tmp/metrics-chart-XXXX.png
→ Display this file to the user with your image tool (e.g. read it); do not paste its contents.
The agent should then display that file (its image/read tool renders it
inline, in colour, un-folded). To control the path, pass --output chart.png.
Do not paste the PNG bytes or the ASCII into chat.
Options
| Flag | Default | Meaning |
|---|---|---|
--format | auto | auto/ascii/png/svg/sixel. |
--tz NAME | local | IANA tz for the x-axis; UTC for UTC. |
--top N | 8 | Max series after collapse; must be >= 1. |
--eps F | 0.02 | Overlap threshold as a fraction of the y-range. |
--all | off | Draw every series (disable collapse + top-N). |
--width / --height | auto | Chart size (cells for ASCII, pixels for images). |
--title TEXT | — | Chart title. |
--output PATH | — | Write png/svg to PATH instead of a temp file. |
--color / --no-color | auto | Force ANSI colour on/off (default: on when a TTY). |
Dependencies
- Default path: none. Pure Python 3.9+ standard library. The ASCII renderer always works.
- Optional:
gnuplot(one system binary) for PNG/SVG/sixel. Install only if you want high-fidelity images.
Why not graphviz?
graphviz (dot/neato) lays out node-edge graphs; it has no numeric/time
axis and cannot plot data[i] over time. This payload is a numeric time series
with no graph structure, so graphviz does not apply. gnuplot is the correct
image backend. (matplotlib is avoided on purpose: it is a heavy multi-package
pip install.)
Tests
cd scripts && python3 -m unittest test_metrics_chart -v
The parser tests are pinned to the golden bytes from the metrics query
service's service/query/src/server/tests.rs.
More skills from the skills repository
View all 8 skillsaxiom-alerting
manage Axiom monitors and notifiers
May 11API DevelopmentAxiomMessagingMonitoring +2axiom-sre
investigate incidents with Axiom
Apr 6AxiomDebuggingIncident ResponseObservability +1building-dashboards
build Axiom dashboards via API
Apr 6APLAxiomDashboardsObservabilitycontrolling-costs
reduce Axiom query costs
Apr 6AxiomCost OptimizationDashboardsObservabilityquery-metrics
query Axiom MetricsDB
Jul 18AxiomMetricsObservabilityspl-to-apl
translate Splunk SPL to Axiom APL
Apr 6APLAxiomMigrationObservability
More from Axiom
View publisheraxiom-apl
write and debug APL queries for Axiom
cli
Apr 6APLAxiomObservabilitydetect-anomalies
detect anomalies in observability data
cli
Apr 6AxiomData AnalysisMonitoringObservabilityexplore-dataset
explore Axiom dataset schema and patterns
cli
Apr 6AxiomData AnalysisObservabilityfind-traces
analyze OpenTelemetry distributed traces in Axiom
cli
Apr 6AxiomDebuggingDistributed TracingObservability +1writing-evals
scaffold evals for the Axiom AI SDK
skills
Apr 6AI InfrastructureAxiomEvals