Designs and builds Axiom dashboards via API. Covers chart types, APL and metrics/MPL query patterns, SmartFilters, layout, and configuration options. Use when creating dashboards, migrating from Splunk, or configuring chart options.
يبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
مستكشف الملفات
48 ملفات
عرض SKILL.md
SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
building-dashboards
description
Designs and builds Axiom dashboards via API. Covers chart types, APL and metrics/MPL query patterns, SmartFilters, layout, and configuration options. Use when creating dashboards, migrating from Splunk, or configuring chart options.
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
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.
Chart Unit Configuration
Pass a friendly unit string to chart-add --unit ("%", "s", "ms", "B", "req/s"). The script picks unit enum + customUnits suffix per chart type. customUnits is a label, not a formatter — scale magnitudes in MPL (| map / 1048576 for bytes → MiB, | map / 1000000 for bytes → MB, | map * 100 for 0–1 ratio → percent). For metrics charts, read the source unit from metrics-info … metrics <m> info and pass it through. Internals (advanced options the agent may merge with jq): reference/chart-config.md.
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):
**Deferred — blocked by:** <one-line reason>.
**Original spec:** <what the panel should compute, dimensions, unit>.
**To unblock:** <pointer to the fix>.
chart-add covers the common path (type, id, name, query, dataset, unit, sparkline). For options it doesn't expose — aggChartOpts variants on TimeSeries, tableSettings.columns on Table/LogStream, hideHeader, etc. — start from a chart-add output and merge the extra fields with jq. See reference/chart-config.md for the full option set, and the rejected-field list before merging anything bespoke.
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.
| summarize count() by route | top 10 by count_ // bounded
| summarize count() by user_id // unbounded — avoid
Field Escaping
Fields with dots need bracket notation:
| where ['kubernetes.pod.name'] == "frontend"
Fields with dots IN the name (not hierarchy) need escaping:
| 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.
Validate a chart MPL pipeline. Auto-injects param $__interval: Duration; and -p __interval=…; rejects inline time ranges. Use this in place of raw metrics-query when authoring chart queries.
The two axiom-api scripts are not interchangeable. scripts/axiom-api is for the dashboard app API; scripts/metrics/axiom-api is for data/metrics endpoints and edge routing. Wrong one → 404.
Targeted Chart Updates
Use scripts/dashboard-chart-patch when changing one existing chart and the dashboard layout, metadata, and other charts should remain untouched. It calls PATCH /v2/dashboards/uid/{uid}/charts/{chartId} with a JSON Merge Patch under the chart request field.
Patch files contain only the chart fields to change:
null removes an existing field. Nested objects merge recursively. If id is present in the patch, it must match the <chart-id> path argument. The server validates the resulting full dashboard before saving.
Use --version <version> for optimistic concurrency after fetching the dashboard with dashboard-get. Use --overwrite only when last-write-wins behavior is intended. Continue using dashboard-update for layout changes, multi-chart edits, dashboard metadata, owner, refresh interval, or time window updates.
Workflow
chart-add, layout-pack, and dashboard-assemble own the JSON shape. Each chart lives in its own temp file; nothing chart-shaped re-enters the agent's context.
Discover schema (axiom-sre / getschema for events; metrics-spec + metrics-info for metrics).
Write each panel query. Validate APL via axiom-sre with an explicit time filter; validate MPL via scripts/metrics/mpl-validate-chart.
chart-add --type … --apl '<APL>'orchart-add --type … --mpl '<MPL>' --dataset <name> per chart, redirected to its own file.
layout-pack <id>:<Type|WxH> … for the layout (ids in display order).
dashboard-assemble --name … --datasets … --layout LAYOUT CHART_FILES… to compose.
dashboard-validate then dashboard-create (or dashboard-update).
dashboard-link for the URL — never hand-construct.
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.
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