Labsco
axiomhq logo

building-dashboards

10

by axiomhq · part of axiomhq/skills

Designs and builds Axiom dashboards via API. Covers chart types, APL and metrics/MPL query patterns, SmartFilters, layout, and configuration options. Use when…

🔥🔥🔥✓ VerifiedFreeQuick setup
🧩 One of 6 skills in the axiomhq/skills package — works on its own, and pairs well with its siblings.

Designs and builds Axiom dashboards via API. Covers chart types, APL and metrics/MPL query patterns, SmartFilters, layout, and configuration options. Use when…

Inspect the full instructions your agent will receiveExpand

This is the exact playbook injected into your agent when the skill activates — shown here so you can audit it before installing. You don't need to read it to use the skill.

by axiomhq

Designs and builds Axiom dashboards via API. Covers chart types, APL and metrics/MPL query patterns, SmartFilters, layout, and configuration options. Use when… npx skills add https://github.com/axiomhq/skills --skill building-dashboards Download ZIPGitHub10

Building Dashboards

Philosophy

  • Decisions first. Every panel answers a question that leads to an action.

  • Overview → drilldown → evidence. Start broad, narrow on click/filter, end with raw logs.

  • Rates and percentiles over averages. Averages hide problems; p95/p99 expose them.

  • Simple beats dense. One question per panel. No chart junk.

  • Validate with data. Never guess fields—discover schema first.

  • Compute what's asked, or defer. If a panel can't be computed, replace it with a Note documenting the blocker. Never substitute a different quantity, even disclosed. See Compute or Defer .

Entry Points

Starting from Workflow Vague description Intake → check dataset kind → design blueprint (APL or MPL) → queries per panel → deploy Template Pick template → customize dataset/service/env → deploy Splunk dashboard Extract SPL → translate via spl-to-apl → map to chart types → deploy Grafana dashboard Project canonical panel spec (expr, legendFormat, unit, title, description) → translate PromQL → map chart types → deploy. See reference/grafana-migration.md. Exploration Use axiom-sre to discover schema/signals → productize into panels

Intake: What to Ask First

Audience & decision

  • Oncall triage? (fast refresh, error-focused)

  • Team health? (daily trends, SLO tracking)

  • Exec reporting? (weekly summaries, high-level)

Scope

  • Service, environment, region, cluster, endpoint?

  • Single service or cross-service view?

Dataset kind. Run scripts/metrics/datasets <deploy> and check kind.

  • otel:metrics:v1 → metrics dataset, follow the Metrics path.

  • anything else → events/logs dataset, follow the APL path.

Never run getschema on a metrics dataset. It returns 0 rows without error.

APL path: discover fields with ['dataset'] | where _time between (ago(1h) .. now()) | getschema. Continue to steps 4–5.

Metrics path:

  • scripts/metrics/metrics-spec <deploy> <dataset> — required before any MPL query.

  • scripts/metrics/metrics-info <deploy> <dataset> metrics | tags | tags <tag> values for discovery.

  • If discovery is empty, retry with --start 7 days ago (sparse metrics).

  • find-metrics <value> searches tag values , not metric names — use it only with a known entity name.

  • Skip to the Metrics/MPL Blueprint.

Golden signals (APL path)

  • Traffic: requests/sec, events/min

  • Errors: error rate, 5xx count

  • Latency: p50, p95, p99 duration

  • Saturation: CPU, memory, queue depth, connections

Drilldown dimensions (APL path)

  • What do users filter/group by? (service, route, status, pod, customer_id)

Dashboard Blueprint

Pick the blueprint matching the dataset kind.

APL Blueprint (events/logs datasets)

1. At-a-Glance (Statistic panels)

Single numbers that answer "is it broken right now?"

  • Error rate (last 5m)

  • p95 latency (last 5m)

  • Request rate (last 5m)

  • Active alerts (if applicable)

2. Trends (TimeSeries panels)

Time-based patterns that answer "what changed?"

  • Traffic over time

  • Error rate over time

  • Latency percentiles over time

  • Stacked by status/service for comparison

3. Breakdowns (Table/Pie panels)

Top-N analysis that answers "where should I look?"

  • Top 10 failing routes

  • Top 10 error messages

  • Worst pods by error rate

  • Request distribution by status

4. Evidence (LogStream + SmartFilter)

Raw events that answer "what exactly happened?"

  • LogStream filtered to errors

  • SmartFilter for service/env/route

  • Key fields projected for readability

Metrics/MPL Blueprint (metrics datasets)

Use align to $__interval using … for bucketing — $__interval is supplied by the dashboard runtime. Hard-coded windows over- or under-resolve. Validate every pipeline with scripts/metrics/mpl-validate-chart; both it and chart-add --mpl reject inline time ranges ([1h..]).

Exception: for sparse metrics where $__interval rounds to empty buckets, a fixed wider window (e.g. 1h) is acceptable; document why on the chart.

1. At-a-Glance (Statistic panels)

Current values — "what's the state right now?"

  • Use group using avg (gauges) or group using last (counters).

  • Read the metric's unit via metrics-info … metrics <m> info and pass it to chart-add --unit. Ratio metrics (0–1) need | map * 100 in MPL before --unit "%".

2. Trends (TimeSeries panels)

Trends over time — "what changed?"

  • align to $__interval using avg|sum|last.

  • Group by low-cardinality tags only (≤10 series per chart).

  • Embed the unit in --name ("P95 Latency (ms)", "Memory (MiB)"); scale magnitudes in MPL (| map / 1048576 for bytes → MiB).

3. Breakdowns (TimeSeries or Table panels)

Per-entity detail — "where should I look?"

  • Metrics broken down by entity (host, pod, service).

  • Filter to keep series count manageable.

  • One dimension per panel; don't overload a single chart.

4. Entity State (TimeSeries or Table panels)

Boolean/state metrics — answer "what is on/off/active?"

  • Use align to $__interval using last.

  • Sparse state metrics may need a fixed wider interval (1h+).

Required Chart Structure

Each chart needs a unique kebab-case id (error-rate, p95-latency); every layout i must match one. Pass the same id to chart-add --id and layout-pack <id>:…. dashboard-assemble cross-checks before emit.

Compute or Defer

Each panel either computes the requested quantity, or it's replaced by a Note documenting the blocker. Substituting a different quantity is never acceptable — disclaimers don't reach whoever acts on the number.

Defer template (use chart-add --type Note):

Copy & paste — that's it
**Deferred — blocked by:** .

**Original spec:** .

**To unblock:** .

Common blockers: MPL parser limits, missing tag with no reverse-tag equivalent, missing metric with no OTel rename match. Full rationale: reference/design-playbook.md § Substituting a Different Quantity.

Chart Types

Type When Key constraint Statistic Single KPI, current value Query must return one row. TimeSeries Trends over time, percentile overlays bin_auto(_time); percentiles_array() for multi-percentile. Table Top-N lists, breakdowns Bound with top N; control columns via project. Pie Share-of-total for ≤6 categories Aggregate to ≤6 slices; never high-cardinality. LogStream Raw event inspection take 100–500; project-keep to relevant fields; filter hard. Heatmap Distribution / latency density summarize histogram(field, buckets) by bin_auto(_time). Scatter Plot Correlate two metrics per group summarize avg(x), avg(y) by group. SmartFilter Interactive filter bar Each panel query needs declare query_parameters. See reference/smartfilter.md. Monitor List Monitor status display No APL — select monitors in UI. Note Markdown context, headers, runbook links chart-add --type Note --text "<md>".

Per-type APL recipes: reference/chart-cookbook.md.

APL Patterns

Time Filtering

Dashboard chart queries inherit time from the picker — omit _time filters. Ad-hoc queries (Axiom Query tab, axiom-sre) need an explicit where _time between (ago(1h) .. now()).

Bin Size Selection

Use bin_auto(_time) — it adjusts to the dashboard time window. Manual bin(_time, …) is only justified for non-standard cases (e.g. matching an upstream batch interval); document why.

Cardinality Guardrails

Bound summarize … by … with top N or a filter. Unbounded grouping on high-cardinality fields (user_id, trace_id) blows up.

Copy & paste — that's it
| summarize count() by route | top 10 by count_ // bounded
| summarize count() by user_id // unbounded — avoid

Field Escaping

Fields with dots need bracket notation:

Copy & paste — that's it
| where ['kubernetes.pod.name'] == "frontend"

Fields with dots IN the name (not hierarchy) need escaping:

Copy & paste — that's it
| where ['kubernetes.labels.app\\.kubernetes\\.io/name'] == "frontend"

Recipes

Traffic, error-rate, latency-percentile, and other golden-signal APL recipes: reference/chart-cookbook.md.

Layout Composition

layout-pack packs charts row-major into the 12-column grid using per-type defaults (Statistic 3×3, TimeSeries 6×4, Table 6×5, LogStream 12×6, Note 12×2). Override with id:WxH when needed. Section blueprints: reference/layout-recipes.md. Naming and panel-ordering conventions: reference/design-playbook.md.

Dashboard Settings

Refresh Rate

dashboard-assemble --refresh oncall|team|exec (60/300/900s) or pass an explicit integer (≥60). Short refresh + long time range = expensive queries; pick the longer end for exec/weekly boards.

Sharing

API tokens create shared dashboards only (owner: "X-AXIOM-EVERYONE"); private dashboards aren't supported. Per-user data visibility is still enforced by dataset permissions.

URL Time Range Parameters

?t_qr=24h (quick range), ?t_ts=...&t_te=... (custom), ?t_against=-1d (comparison)

Sibling Skill Integration

  • spl-to-apl — Splunk SPL → APL (timechart → TimeSeries, stats → Statistic/Table). See reference/splunk-migration.md.

  • axiom-sre — schema discovery via getschema, baseline exploration.

  • query-metrics — metrics dataset/tag/value discovery; same scripts vendored under scripts/metrics/.

Templates

Compose with chart-add + layout-pack + dashboard-assemble. Pre-built templates remain under reference/templates/ (blank.json, service-overview.json, service-overview-with-filters.json, api-health.json) for legacy use; dashboard-from-template instantiates them but assumes specific field names (service, status, route, duration_ms) and needs sed-fixing. Prefer composition for new work.

Common Pitfalls

Problem Cause Solution getschema returns 0 rows Dataset is otel:metrics:v1 Use scripts/metrics/metrics-info for metrics discovery. Metrics discovery returns empty Sparse metrics outside the 24h default window Retry with --start 7 days ago. 404 from metrics API calls Used scripts/axiom-api (dashboard) instead of scripts/metrics/axiom-api Use scripts/metrics/axiom-api for /v1/query/*, /v1/datasets. Statistic shows 1 instead of 100% for a 0–1 ratio Percent enum doesn't auto-multiply | map * 100 in MPL, then chart-add --unit "%". OTel histogram chart shows nonsense Histogram aligned as a scalar Use bucket … using interpolate_cumulative_histogram (or _delta per temporality). See promql-to-mpl.md § Histogram translation. Grafana migration filters/groups on the wrong subset Read expr without description, or vice versa Project all five panel fields before authoring; see reference/grafana-migration.md. PromQL metric name not found Skipped OTel rename rules Drop _total, decompose histograms, normalise units; validate with metrics-info. Labels need reverse-tag discovery. See grafana-migration.md § Name Mapping. MPL chart aggregates across a dimension PromQL filtered/grouped on Dropped a selector or by(...) during translation Every {label=…}where; every by(…)group by. See reference/promql-to-mpl.md. Panel shipped a different quantity than asked Substituted instead of deferring Replace with a Note documenting the blocker. See Compute or Defer . 403 "creating private dashboards" API tokens only create shared dashboards Leave owner as dashboard-assemble's default (X-AXIOM-EVERYONE).

Reference

  • reference/chart-config.md — All chart configuration options (JSON)

  • reference/metrics-mpl.md — Metrics/MPL chart contract and discovery scripts

  • reference/smartfilter.md — SmartFilter/FilterBar full configuration

  • reference/chart-cookbook.md — APL patterns per chart type

  • reference/layout-recipes.md — Grid layouts and section blueprints

  • reference/splunk-migration.md — Splunk panel → Axiom mapping

  • reference/grafana-migration.md — Grafana panel → Axiom mapping (canonical-spec projection, PromQL→MPL pointers, OTel rename rules)

  • reference/promql-to-mpl.md — PromQL → MPL translation rules (selectors, groupings, rate, histograms, ratios, reverse-tag discovery)

  • reference/design-playbook.md — Decision-first design principles

  • reference/templates/ — Ready-to-use dashboard JSON files

For APL syntax: https://axiom.co/docs/apl/introduction