关于 building-dashboards
building-dashboards 是一套用于规划和构建 Axiom 仪表板的技能,面向需要把日志或指标转化为可执行视图的人员。它按数据集类型选择 APL 或 MPL 路径,并强调先验证数据,再设计面板和布局。
主要功能
- 01按数据类型选择 APL 或 MPL
- 02以决策问题组织面板
- 03提供多种图表配置指南
- 04支持面板布局与分组
- 05缺少数据时用说明面板延期
适用场景
- 01从模糊需求设计服务健康仪表板
- 02将 Grafana 或 Splunk 仪表板迁移
- 03把数据探索结果整理成面板
MCP 相关
技能说明在指标发现与查询流程中使用 Axiom MCP。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ axiomhq/ skills --skill building-dashboards安装后在 Claude Code 中输入/building-dashboards确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.md.meta/.gitkeepreference/chart-config.mdchart-cookbook.mddesign-playbook.mdgrafana-migration.mdlayout-recipes.mdmetrics-mpl.mdpromql-to-mpl.mdsmartfilter.mdsplunk-migration.mdreference/templates/api-health.jsonblank.jsonorg-usage-cost-control.jsonservice-overview-with-filters.jsonservice-overview.jsonscripts/axiom-apichart-adddashboard-assembledashboard-chart-patchdashboard-copydashboard-createdashboard-deletedashboard-from-templatedashboard-getdashboard-linkdashboard-listdashboard-newdashboard-normalize.jqdashboard-update详细介绍
构建仪表板
理念
- 决策优先。 每个面板都要回答一个能引导行动的问题。
- 概览 → 下钻 → 证据。 从全局视图开始,通过点击/筛选缩小范围,最后查看原始日志。
- 使用速率和百分位数,而非平均值。 平均值会掩盖问题;p95/p99 能将其显现出来。
- 简单胜过繁杂。 每个面板只回答一个问题。不要加入无关图表元素。
- 用数据验证。 绝不猜测字段——先发现架构。
- 计算所需内容,否则暂缓。 如果无法计算某个面板,就用一条记录阻碍因素的
Note替代。即使说明情况,也绝不要用其他指标替代。参见计算或暂缓。
入口
| 起点 | 工作流 |
|---|---|
| 模糊描述 | 收集需求 → 检查数据集类型 → 设计蓝图(APL 或 MPL)→ 为每个面板编写查询 → 部署 |
| 模板 | 选择模板 → 自定义数据集/服务/环境 → 部署 |
| Splunk 仪表板 | 提取 SPL → 通过 spl-to-apl 转换 → 映射图表类型 → 部署 |
| Grafana 仪表板 | 提取规范面板规格(expr、legendFormat、unit、title、description)→ 转换 PromQL → 映射图表类型 → 部署。参见 reference/grafana-migration.md。 |
| 探索 | 使用 axiom-sre 发现架构/信号 → 将其产品化为面板 |
需求收集:首先要问什么
-
受众与决策
- 值班故障分诊?(快速刷新,以错误为重点)
- 团队健康状况?(每日趋势、SLO 跟踪)
- 高管报告?(每周摘要、高层概览)
-
范围
- 服务、环境、区域、集群、端点?
- 单个服务视图还是跨服务视图?
-
数据集类型。 使用 MCP
listDatasets并检查kind。对于单独配置的部署,请使用scripts/metrics/datasets <deploy>。otel:metrics:v1/otel-metrics-v1→ 指标数据集,遵循指标路径。- 其他任何类型 → 事件/日志数据集,遵循 APL 路径。
绝不要对指标数据集运行
getschema。 它会返回 0 行,且不报错。APL 路径: 使用
['dataset'] | where _time between (ago(1h) .. now()) | getschema发现字段。继续执行步骤 4–5。指标路径: 使用 Axiom MCP 发现并查询指标,然后遵循 指标/MPL 蓝图。
-
黄金信号(APL 路径)
- 流量:请求数/秒、事件数/分钟
- 错误:错误率、5xx 数量
- 延迟:p50、p95、p99 时长
- 饱和度:CPU、内存、队列深度、连接数
-
下钻维度(APL 路径)
- 用户会按哪些条件筛选/分组?(服务、路由、状态、Pod、customer_id)
仪表板蓝图
选择与数据集类型匹配的蓝图。
APL 蓝图(事件/日志数据集)
1. 一目了然(统计面板)
用单个数字回答“现在是否出故障?”
- 错误率(最近 5 分钟)
- p95 延迟(最近 5 分钟)
- 请求速率(最近 5 分钟)
- 活跃告警(如适用)
2. 趋势(时序面板)
通过时间模式回答“发生了什么变化?”
- 随时间变化的流量
- 随时间变化的错误率
- 随时间变化的延迟百分位数
- 按状态/服务堆叠,以便比较
3. 拆分分析(表格/饼图面板)
通过 Top-N 分析回答“我该从哪里着手?”
- 失败最多的前 10 个路由
- 出现最多的前 10 条错误消息
- 按错误率排列最差的 Pod
- 按状态分布的请求
4. 证据(LogStream + SmartFilter)
通过原始事件回答“具体发生了什么?”
- 将 LogStream 筛选为错误
- 使用 SmartFilter 筛选服务/环境/路由
- 展示关键字段,以便阅读
Metrics/MPL 蓝图(指标数据集)
使用 align to $__interval using … 进行分桶——$__interval 由仪表板运行时提供。硬编码的时间窗口会导致分辨率过高或过低。请遵循 Metrics/MPL 图表规范 进行发现和验证。chart-add --mpl 不接受内联时间范围([1h..])。
例外:对于 $__interval 取整后会产生空桶的稀疏指标,可以使用固定的较宽窗口(例如 1h);请在图表中说明原因。
1. 一目了然(统计面板)
当前值——“现在是什么状态?”
- 根据面板需要展示各个序列的方式选择
group函数。 - 从指标元数据中读取指标的
unit,并传给chart-add --unit。比例指标(0–1)需要在 MPL 中使用| map * 100,然后再传入--unit "%"。
2. 趋势(TimeSeries 面板)
随时间变化的趋势——“发生了什么变化?”
- 根据每个时间间隔需要展示的内容选择
align函数。 - 仅按低基数标签分组(每张图表 ≤10 个序列)。
- 在
--name中注明单位("P95 Latency (ms)"、"Memory (MiB)");在 MPL 中缩放数值(字节转换为 MiB:| map / 1048576)。
3. 细分(TimeSeries 或 Table 面板)
按实体查看详情——“应该查看哪里?”
- 按实体(主机、Pod、服务)细分指标。
- 使用筛选器控制序列数量。
- 每个面板只展示一个维度;不要让单张图表承载过多信息。
4. 实体状态(TimeSeries 或 Table 面板)
布尔值/状态指标——回答“什么处于开启/关闭/活动状态?”
- 根据每个时间间隔要回答的状态问题选择
align函数。 - 稀疏状态指标可能需要使用固定的较宽间隔(1h+)。
必需的图表结构
每张图表都需要唯一的 kebab-case id(error-rate、p95-latency);每个布局 i 都必须与其中一个匹配。将同一个 id 传给 chart-add --id 和 layout-pack <id>:…。dashboard-assemble 会在输出前进行交叉检查。
图表单位配置
向 chart-add --unit 传入易读的单位字符串("%"、"s"、"ms"、"B"、"req/s")。脚本会根据图表类型选择 unit 枚举值和 customUnits 后缀。customUnits 是标签,不是格式化器——请在 MPL 中缩放数值(字节转换为 MiB:| map / 1048576;字节转换为 MB:| map / 1000000;0–1 比例转换为百分比:| map * 100)。对于指标图表,请从指标元数据中读取源单位,并将其传入。内部配置(Agent 可使用 jq 合并的高级选项):reference/chart-config.md。
计算或暂缓
每个面板都必须计算请求的数值,否则就用 Note 记录阻碍因素。绝不能用其他数值替代——免责声明不会传达给需要根据数值采取行动的人。
暂缓模板(使用 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>.
常见阻碍:MPL 解析器限制、缺少标签且没有对应的反向标签、缺少指标且没有匹配的 OTel 重命名项。完整说明:reference/design-playbook.md § Substituting a Different Quantity。
图表类型
| 类型 | 适用场景 | 主要限制 |
|---|---|---|
| Statistic | 单个 KPI、当前值 | 查询必须返回一行。 |
| TimeSeries | 随时间变化的趋势、百分位数叠加 | bin_auto(_time);多百分位数使用 percentiles_array()。 |
| Table | Top-N 列表、细分 | 使用 top N 限定;通过 project 控制列。 |
| Pie | 占比(≤6 个类别) | 汇总为 ≤6 个扇区;绝不能使用高基数数据。 |
| LogStream | 原始事件检查 | 使用 take 100–500;用 project-keep 保留相关字段;严格过滤。 |
| Heatmap | 分布 / 延迟密度 | summarize histogram(field, buckets) by bin_auto(_time)。 |
| Scatter Plot | 按组关联两个指标 | summarize avg(x), avg(y) by group。 |
| SmartFilter | 交互式筛选栏 | 每个面板查询都需要 declare query_parameters。参见 reference/smartfilter.md。 |
| Monitor List | 监控状态显示 | 不使用 APL — 在 UI 中选择监控项。 |
| Note | Markdown 上下文、标题、运行手册链接 | chart-add --type Note --text "<md>"。 |
各类型的 APL 配方:reference/chart-cookbook.md。
图表配置
chart-add 涵盖常见用法(类型、id、名称、查询、数据集、单位、迷你图)。对于它未公开的选项 — TimeSeries 上的 aggChartOpts 变体、Table/LogStream 上的 tableSettings.columns、hideHeader 等 — 请先从 chart-add 输出开始,然后使用 jq 合并额外字段。完整选项集请参见 reference/chart-config.md;合并任何自定义内容前,请先查看不接受的字段列表。
APL 模式
时间筛选
仪表板图表查询会继承时间选择器的设置 — 省略 _time 筛选条件。临时查询(Axiom Query 标签页、axiom-sre)需要显式使用 where _time between (ago(1h) .. now())。
分桶大小选择
使用 bin_auto(_time) — 它会根据仪表板的时间范围自动调整。只有在非标准情况下(例如匹配上游批处理间隔)才有必要手动使用 bin(_time, …);请说明原因。
基数限制
使用 top N 或筛选条件限制 summarize … by …。对高基数字段(user_id、trace_id)进行无限制分组会导致问题。
| summarize count() by route | top 10 by count_ // bounded
| summarize count() by user_id // unbounded — avoid
字段转义
包含点号的字段需要使用方括号表示法:
| where ['kubernetes.pod.name'] == "frontend"
名称中包含点号(并非层级结构)的字段需要转义:
| where ['kubernetes.labels.app\\.kubernetes\\.io/name'] == "frontend"
配方
流量、错误率、延迟百分位数和其他黄金信号的 APL 配方:reference/chart-cookbook.md。
布局组合
layout-pack 使用各类型的默认尺寸(Statistic 3×3、TimeSeries 6×4、Table 6×5、LogStream 12×6、Note 12×2),按行优先顺序将图表放入 12 列网格。需要时使用 id:WxH 覆盖。网格配方:reference/layout-recipes.md。命名和面板排序规范:reference/design-playbook.md。
分组
可折叠分组是顶层的 sections 数组。将其传递给 dashboard-assemble。不要在图表文件中臆造 sectionId,也不要通过发送无效更新来探查结构。
dashboard-assemble \
--name "API" \
--datasets logs \
--layout /tmp/d/layout.json \
--section "Requests:err-rate,traffic-ts" \
--section-collapsed "Errors:top-errors" \
/tmp/d/c-err-rate.json /tmp/d/c-traffic-ts.json /tmp/d/c-top-errors.json
- 标题是第一个
:之前的文本。后面是以逗号分隔的图表 ID,且必须与图表id匹配。 - 标记的顺序就是显示顺序。
--section-collapsed会设置defaultCollapsed: true。 - 分组
id是根据标题生成的 UUID,因此下次运行时,相同标题会保留相同 ID。 - 未包含在任何
--section中的图表会保持未分组状态。所有 SmartFilter 图表都应保持未分组状态。 - 用作网格标题的 Note 属于布局,而不是分组。如果希望仪表板能够折叠分组并停止查询,请使用
--section。
仪表板设置
刷新频率
dashboard-assemble --refresh oncall|team|exec(60/300/900s),或传入一个明确的整数(≥60)。较短的刷新间隔加上较长的时间范围会导致查询开销较大;对于 exec/每周仪表板,请选择较长的刷新间隔。
共享
API 令牌只能创建共享仪表板(owner: "X-AXIOM-EVERYONE");不支持私有仪表板。仍会根据数据集权限强制执行逐用户的数据可见性。
URL 时间范围参数
?t_qr=24h(快捷范围),?t_ts=...&t_te=...(自定义范围),?t_against=-1d(对比)
设置
工具、先决条件和 ~/.axiom.toml 配置:请参阅 README.md。运行 scripts/setup 进行验证。
部署
脚本
| 脚本 | 用法 |
|---|---|
scripts/chart-add --type <T> --id <id> --name <n> [--apl <q> | --mpl <q> --dataset <d>] [--unit <u>] | **将单个图表 JSON 输出到标准输出。**区分 APL 与 MPL;检查 MPL 查询是否包含内联时间范围;按图表类型应用单位字段。 |
scripts/layout-pack <id>:<Type|WxH> ... | **将布局 JSON 数组输出到标准输出。**按行优先排列到 12 列网格中;类型名称映射到默认尺寸。 |
scripts/dashboard-assemble --name … --datasets … --layout F.json [--section TITLE:id,id ...] [opts] CHART_FILES… | **根据图表文件和布局合成完整的仪表板 JSON。**负责封装字段(owner、schemaVersion、qr- 前缀、refreshTime 验证、ID 交叉检查、sections)。 |
scripts/dashboard-list <deploy> | 列出所有仪表板 |
scripts/dashboard-get <deploy> <id> | 获取仪表板 JSON |
scripts/dashboard-validate <file> | 验证 JSON 结构 |
scripts/dashboard-create <deploy> <file> | 创建仪表板 |
scripts/dashboard-update <deploy> <id> <file> | 更新(需要版本) |
scripts/dashboard-chart-patch <deploy> <id> <chart-id> <patch-file> (--version <version> | --overwrite) | 修改单个图表 |
scripts/dashboard-copy <deploy> <id> | 克隆仪表板 |
scripts/dashboard-link <deploy> <id> | 获取可分享的 URL |
scripts/dashboard-delete <deploy> <id> | 删除(需确认) |
scripts/axiom-api <deploy> <method> <path> | 仅限仪表板/应用 API(重写为 app.*)。数据/指标端点请使用 scripts/metrics/axiom-api |
scripts/metrics/axiom-api <deploy> <method> <path> | 数据/指标 API(支持用于边缘路由的 AXIOM_URL_OVERRIDE) |
scripts/metrics/datasets <deploy> | 列出数据集及其 kind 和边缘部署信息 |
scripts/metrics/metrics-spec | 获取 MPL 查询规范 |
scripts/metrics/metrics-info <deploy> <dataset> ... | 发现指标、标签和值 |
scripts/metrics/metrics-query <deploy> <mpl> <start> <end> | 执行指标查询(原始查询——不注入 $__interval) |
scripts/metrics/mpl-validate-chart <deploy> '<MPL>' [start] [end] [--interval D] | **验证图表 MPL 管道。**自动注入 param $__interval: Duration; 和 -p __interval=…;拒绝内联时间范围。编写图表查询时,请用此命令代替原始的 metrics-query。 |
两个
axiom-api脚本不能互换。scripts/axiom-api用于仪表板应用 API;scripts/metrics/axiom-api用于数据/指标端点和边缘路由。用错会导致 404。
定向更新图表
如果只需更改一个现有图表,且应保持仪表板布局、元数据和其他图表不变,请使用 scripts/dashboard-chart-patch。它会在 chart 请求字段下使用 JSON Merge Patch 调用 PATCH /v2/dashboards/uid/{uid}/charts/{chartId}。
补丁文件仅包含要更改的图表字段:
{
"name": "Error Rate (5m)",
"query": { "apl": "['logs'] | summarize errors=countif(status >= 500)" },
"config": { "stale": null }
}
null 会移除现有字段。嵌套对象会递归合并。如果补丁中包含 id,则其值必须与 <chart-id> 路径参数匹配。服务器会在保存前验证生成的完整仪表板。
使用 --version <version> 可在通过 dashboard-get 获取仪表板后进行乐观并发控制。仅在预期采用最后写入者优先行为时使用 --overwrite。若要更改布局、编辑多个图表、修改仪表板元数据、所有者、刷新间隔或时间窗口,请继续使用 dashboard-update。
工作流
chart-add、layout-pack 和 dashboard-assemble 负责 JSON 结构。每个图表都存放在各自的临时文件中;任何图表结构都不会重新进入 Agent 的上下文。
- 发现架构(事件使用
axiom-sre/getschema;指标使用 Axiom MCP)。 - 编写每个面板的查询。使用
axiom-sre并指定明确的时间过滤器来验证 APL;对于 MPL,请遵循 Metrics/MPL 图表约定。 - 每个图表分别执行
chart-add --type … --apl '<APL>'或chart-add --type … --mpl '<MPL>' --dataset <name>,并将输出重定向到各自的文件。 - 使用
layout-pack <id>:<Type|WxH> …设定布局(按显示顺序排列 ID)。 - 使用
dashboard-assemble --name … --datasets … --layout LAYOUT [--section TITLE:id,id ...] CHART_FILES…进行组合。每个可折叠分组都要重复指定--section。如果分组应默认折叠,请使用--section-collapsed。 - 然后运行
dashboard-validate,再运行dashboard-create(或dashboard-update)。 - 使用
dashboard-link获取 URL — 切勿手动构造。
同级技能集成
- spl-to-apl — 将 Splunk SPL 转换为 APL(
timechart→ TimeSeries,stats→ Statistic/Table)。参见reference/splunk-migration.md。 - axiom-sre — 通过
getschema发现架构、进行基线探索。
模板
使用 chart-add + layout-pack + dashboard-assemble 进行组合。预构建模板仍保留在 reference/templates/ 下(blank.json、service-overview.json、service-overview-with-filters.json、api-health.json),供旧版用法使用;dashboard-from-template 可实例化这些模板,但假定字段名固定为 service、status、route、duration_ms,且需要通过 sed 修正。新任务请优先使用组合方式。
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
getschema 返回 0 行 | 数据集是 otel:metrics:v1 或 otel-metrics-v1 | 使用 MCP listMetrics 发现指标。 |
| 指标 API 调用返回 404 | 使用了 scripts/axiom-api(仪表板),而不是 scripts/metrics/axiom-api | 对于 /v1/query/*、/v1/datasets,请使用 scripts/metrics/axiom-api。 |
对于 0–1 的比率,Statistic 显示 1 而不是 100% | Percent 枚举不会自动乘以 100 | 在 MPL 中使用 | map * 100,然后执行 chart-add --unit "%"。 |
| OTel 直方图图表显示异常 | 直方图被当作标量进行对齐 | 使用 bucket … using interpolate_cumulative_histogram(或根据 temporality 使用 _delta)。参见 promql-to-mpl.md § 直方图转换。 |
| Grafana 迁移在错误的子集上筛选或分组 | 读取了 expr,却没读取 description,或反之 | 编写内容前先投影全部五个面板字段;参见 reference/grafana-migration.md。 |
| 找不到 PromQL 指标名称 | 跳过了 OTel 重命名规则 | 去掉 _total,分解直方图,并规范化单位;使用 listMetrics 验证。标签需要反向发现标签映射。参见 grafana-migration.md § 名称映射。 |
| MPL 图表聚合了 PromQL 曾筛选或分组的维度 | 转换时丢弃了选择器或 by(...) | 每个 {label=…} 都转换为 where;每个 by(…) 都转换为 group by。参见 reference/promql-to-mpl.md。 |
| 面板交付的指标与要求不符 | 用替代方案代替了推迟处理 | 改为使用 Note 说明阻碍因素。参见 计算或暂缓。 |
| 创建私有仪表板时出现 403 | API 令牌只能创建共享仪表板 | 将 owner 保留为 dashboard-assemble 的默认值(X-AXIOM-EVERYONE)。 |
添加分组时出现 400 invalid_dashboard | 图表 JSON 自行添加了 sections 或 sectionId | 将 --section / --section-collapsed 传给 dashboard-assemble。不要探查 API。 |
参考
reference/chart-config.md— 所有图表配置选项(JSON)reference/metrics-mpl.md— 指标/MPL 图表约定与发现脚本reference/smartfilter.md— SmartFilter/FilterBar 完整配置reference/chart-cookbook.md— 各图表类型的 APL 模式reference/layout-recipes.md— 网格布局与分区蓝图reference/splunk-migration.md— Splunk 面板 → Axiom 映射reference/grafana-migration.md— Grafana 面板 → Axiom 映射(规范规格映射、PromQL→MPL 参考、OTel 重命名规则)reference/promql-to-mpl.md— PromQL → MPL 转换规则(选择器、分组、速率、直方图、比率、反向标签发现)reference/design-playbook.md— 决策优先的设计原则reference/templates/— 可直接使用的仪表板 JSON 文件