后端与接口
用 Axiom API 设计并构建仪表盘(含…
当需要通过 Axiom API 创建仪表盘、从 Splunk/Grafana 迁移仪表盘或配置图表选项时,按决策优先、概览→下钻→证据的结构化流程构建。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
用 Axiom API 设计并构建仪表盘特定
解决思路
- 遵循设计哲学:每个面板回答一个导向行动的问题;按概览→下钻→证据组织;用速率和百分位数而非平均值;每个面板只问一个问题、保持简洁;先用数据验证字段、绝不猜测 schema;无法计算时用 Note 记录阻塞点而非替换为其他量。
- 根据起点选择工作流:模糊描述走 Intake→检查 dataset kind→设计蓝图(APL 或 MPL)→逐面板查询→部署;模板则选模板并定制 dataset/service/env;Splunk 仪表盘先提取 SPL 再经 spl-to-apl 翻译并映射图表类型;Grafana 仪表盘先投影规范面板字段(expr、legendFormat、unit、title、description)再翻译 PromQL 并映射图表类型;探索阶段用 axiom-sre 发现 schema/信号后产品化为面板。
- Intake 阶段先问清:受众与决策(oncall 分诊/团队健康/高管汇报)、范围(服务、环境、区域、集群、端点;单服务或跨服务)、dataset kind、黄金信号(流量、错误、延迟、饱和度)、下钻维度(service、route、status、pod、customer_id)。
- 用 `scripts/metrics/datasets <deploy>` 检查 `kind`:`otel:metrics:v1` 走 Metrics 路径,其他走 APL 路径;绝不对 metrics dataset 运行 `getschema`(会无错返回 0 行)。
- APL 路径:用 `['dataset'] | where _time between (ago(1h) .. now()) | getschema` 发现字段,然后按 APL 蓝图构建。
- Metrics 路径:先运行 `scripts/metrics/metrics-spec <deploy> <dataset>`(任何 MPL 查询前必需);用 `scripts/metrics/metrics-info <deploy> <dataset> metrics | tags | tags <tag> values` 做发现;若发现为空用 `--start` 7 天前重试;`find-metrics <value>` 只搜索 tag 值而非指标名,仅在已知实体名时使用;然后按 Metrics/MPL 蓝图构建。
- APL 蓝图四层:At-a-Glance 用 Statistic 面板展示错误率、p95 延迟、请求速率、活跃告警;Trends 用 TimeSeries 展示流量/错误率/延迟百分位随时间变化并按 status/service 堆叠;Breakdowns 用 Table/Pie 展示 Top 10 失败路由、Top 10 错误消息、最差 pod、状态分布;Evidence 用 LogStream + SmartFilter 展示过滤后的原始事件并投影关键字段。
- Metrics/MPL 蓝图四层:At-a-Glance 用 `group using avg`(gauge)或 `group using last`(counter),从 `metrics-info … metrics <m> info` 读取 unit 传给 `chart-add --unit`,0–1 比率需 `| map * 100` 后再传 `--unit "%"`;Trends 用 `align to $__interval using avg|sum|last`,只按低基数 tag 分组(每图 ≤10 条序列),在 `--name` 中嵌入单位并在 MPL 中缩放量级;Breakdowns 按实体(host、pod、service)拆分并过滤控制序列数,每面板一个维度;Entity State 用 `align to $__interval using last`,稀疏状态指标可用固定更宽区间(1h+)。
- MPL 分桶统一用 `align to $__interval using …`(`$__interval` 由仪表盘运行时提供),硬编码窗口会过度或不足解析;每个 pipeline 用 `scripts/metrics/mpl-validate-chart` 验证,它和 `chart-add --mpl` 都拒绝内联时间范围(`[1h..]`);稀疏指标若 `$__interval` 取整为空桶,可用固定更宽窗口(如 `1h`)但需在图表上记录原因。
- 每个图表需要唯一的 kebab-case `id`(如 `error-rate`、`p95-latency`),每个 layout 的 `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`);metrics 图表从 `metrics-info … metrics <m> info` 读取源单位并透传。
- Compute or Defer 原则:每个面板要么计算所请求的量,要么替换为记录阻塞点的 `Note`(用 `chart-add --type Note`),绝不替换为其他量;Note 模板包含 `**Deferred — blocked by:**`、`**Original spec:**`、`**To unblock:**` 三部分;常见阻塞包括 MPL 解析器限制、缺少 tag 且无反向 tag 等价物、缺少指标且无 OTel 重命名匹配。
- 按图表类型选择并遵守约束: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`);Monitor List 用于监控状态(无 APL,在 UI 选择监控);Note 用于 Markdown 上下文、标题、runbook 链接。
- 图表配置:`chart-add` 覆盖常见路径(type、id、name、query、dataset、unit、sparkline);对未暴露的选项(TimeSeries 的 `aggChartOpts` 变体、Table/LogStream 的 `tableSettings.columns`、`hideHeader` 等),从 `chart-add` 输出开始用 `jq` 合并额外字段,合并前先查看被拒字段列表。
- APL 时间过滤:仪表盘图表查询从选择器继承时间,省略 `_time` 过滤;临时查询(Axiom Query 标签页、`axiom-sre`)需要显式 `where _time between (ago(1h) .. now())`。
- APL 分桶用 `bin_auto(_time)` 自动适应仪表盘时间窗口;手动 `bin(_time, …)` 仅用于非标准场景(如匹配上游批处理间隔)并记录原因。
- 基数护栏:用 `top N` 或过滤限定 `summarize … by …`;绝不对高基数字段(`user_id`、`trace_id`)做无界分组。
- 字段转义:带点的字段用方括号表示法(`['kubernetes.pod.name']`);名字中本身含点(非层级)的字段需转义(`['kubernetes.labels.app\\.kubernetes\\.io/name']`)。
- 布局:用 `layout-pack` 按行优先打包进 12 列网格,使用按类型默认尺寸(Statistic 3×3、TimeSeries 6×4、Table 6×5、LogStream 12×6、Note 12×2),需要时用 `id:WxH` 覆盖。
- 仪表盘设置:刷新率用 `dashboard-assemble --refresh oncall|team|exec`(60/300/900s)或显式整数(≥60),短刷新+长时间范围=昂贵查询,exec/周报选更长端;API token 只能创建共享仪表盘(`owner: "X-AXIOM-EVERYONE"`),不支持私有仪表盘,但按用户的数据可见性仍由 dataset 权限强制;URL 时间范围参数 `?t_qr=24h`(快速范围)、`?t_ts=...&t_te=...`(自定义)、`?t_against=-1d`(对比)。
- 部署脚本:`scripts/chart-add --type <T> --id <id> --name <n> [--apl <q> | --mpl <q> --dataset <d>] [--unit <u>]` 输出单个图表 JSON 到 stdout(区分 APL/MPL,检查 MPL 内联时间范围,按图表类型应用单位字段);`scripts/layout-pack <id>:<Type|WxH> ...` 输出布局 JSON 数组到 stdout;`scripts/dashboard-assemble --name … --datasets … --layout F.json [opts] CHART_FILES…` 从图表文件+布局组合完整仪表盘 JSON(负责 envelope:`owner`、`schemaVersion`、`qr-` 前缀、`refreshTime` 校验、id 交叉校验);`scripts/dashboard-list/get/validate/create/update/delete/copy/link` 分别用于列出、获取、校验、创建、更新、删除、克隆、获取分享链接;`scripts/dashboard-chart-patch <deploy> <id> <chart-id> <patch-file> (--version <version> | --overwrite)` 修补单个图表;`scripts/axiom-api` 仅用于仪表盘/app API(重写到 `app.*`),`scripts/metrics/axiom-api` 用于数据/指标端点(支持 `AXIOM_URL_OVERRIDE` 边缘路由),两者不可互换,用错会 404。
- 定向图表更新:只改一个现有图表且布局、元数据和其他图表不变时用 `scripts/dashboard-chart-patch`,它调用 `PATCH /v2/dashboards/uid/{uid}/charts/{chartId}` 并在 `chart` 请求字段下用 JSON Merge Patch;补丁文件只含要改的图表字段,`null` 删除现有字段,嵌套对象递归合并,若补丁含 `id` 必须匹配 `<chart-id>` 路径参数,服务器保存前校验完整仪表盘;用 `--version <version>` 做乐观并发(先用 `dashboard-get` 获取),仅在意图为 last-write-wins 时用 `--overwrite`;布局变更、多图表编辑、仪表盘元数据、owner、刷新间隔或时间窗口更新仍用 `dashboard-update`。
- 部署工作流:1) 发现 schema(事件用 `axiom-sre`/`getschema`,指标用 `metrics-spec`+`metrics-info`);2) 写每个面板查询,APL 用 `axiom-sre` 加显式时间过滤验证,MPL 用 `scripts/metrics/mpl-validate-chart` 验证;3) 逐图表运行 `chart-add --type … --apl '<APL>'` 或 `chart-add --type … --mpl '<MPL>' --dataset <name>` 重定向到各自文件;4) `layout-pack <id>:<Type|WxH> …` 生成布局(id 按显示顺序);5) `dashboard-assemble --name … --datasets … --layout LAYOUT CHART_FILES…` 组合;6) `dashboard-validate` 后 `dashboard-create`(或 `dashboard-update`);7) `dashboard-link` 获取 URL,绝不手工构造。
- 与兄弟技能集成:spl-to-apl 做 Splunk SPL→APL(`timechart`→TimeSeries,`stats`→Statistic/Table);axiom-sre 做 `getschema` schema 发现和基线探索;query-metrics 做指标 dataset/tag/value 发现(相同脚本 vendored 在 `scripts/metrics/` 下)。
- 模板:用 `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`,改用 `scripts/metrics/metrics-info`;指标发现为空说明稀疏指标在 24h 默认窗口外,用 `--start` 7 天前重试;指标 API 404 说明用了 `scripts/axiom-api`,改用 `scripts/metrics/axiom-api`;0–1 比率 Statistic 显示 `1` 而非 `100%` 说明 `Percent` 枚举不自动乘,在 MPL 中 `| map * 100` 再 `--unit "%"`;OTel 直方图显示异常说明被当标量对齐,用 `bucket … using interpolate_cumulative_histogram`(或按 `temporality` 用 `_delta`);Grafana 迁移过滤/分组错误说明只读了 `expr` 或 `description`,需先投影全部五个面板字段;PromQL 指标名找不到说明跳过了 OTel 重命名规则,需去掉 `_total`、分解直方图、规范化单位并用 `metrics-info` 验证,标签需反向 tag 发现;MPL 图表跨 PromQL 过滤/分组的维度聚合说明翻译时丢了选择器或 `by(...)`,每个 `{label=…}` → `where`,每个 `by(…)` → `group by`;面板交付了不同量说明用了替换而非延迟,替换为记录阻塞点的 `Note`;403 "creating private dashboards" 说明 API token 只能创建共享仪表盘,保持 `owner` 为 `dashboard-assemble` 默认值(`X-AXIOM-EVERYONE`)。
适用边界 · 注意事项
- 需要私有仪表盘时(API token 只能创建共享仪表盘,`owner` 固定为 `X-AXIOM-EVERYONE`)。
- 对 `otel:metrics:v1` 的 metrics dataset 运行 `getschema` 或使用 APL 路径时(应走 Metrics/MPL 路径)。
- 无法计算所请求的量时不应替换为其他量(应替换为记录阻塞点的 Note)。