关于 kubesense-dashboards
kubesense-dashboards 是用于生成 KubeSense 仪表板预设的技能,供 Agent 创建仪表板或提供可导入的 JSON。它要求先验证预设结构,并建议通过 KubeSense MCP 服务发现真实指标和字段名。
主要功能
- 01生成仪表板预设或导入 JSON
- 02创建前验证预设结构
- 03按需发现指标及字段
- 04遵循面板与查询的格式要求
- 05规避字段错误导致的数据丢失
适用场景
- 01根据需求创建 KubeSense 仪表板
- 02生成供用户审阅的仪表板 JSON
- 03构造指标、日志或追踪查询
- 04诊断预设验证失败与字段问题
MCP 相关
可配合 KubeSense MCP 服务发现指标名称、指标标签以及日志和追踪字段。随后根据发现结果构造查询,并在创建前验证预设。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ kubesense-ai/ kubesense-mcp-skills --skill kubesense-dashboards安装后在 Claude Code 中输入/kubesense-dashboards确认已加载。
附带文件references/panel-config.mdreferences/variables-and-rows.md
详细介绍
KubeSense 仪表板
构建仪表板预设——其结构与 Export 按钮生成的内容相同,因此导出的仪表板可以编辑并重新导入。
有两种交付方式:
create-dashboard MCP 工具 | 预设 JSON | |
|---|---|---|
| 应用者 | Agent(写入工具,需要审批) | 用户,通过仪表板 → 导入 |
| 适用场景 | 用户要求你创建一个 | 用户要求提供 JSON,或想先审阅 |
| 输出结构 | 预设对象本身 | 导入封装,其中的 preset 是字符串化内容 |
两种方式都会经过相同的服务端架构检查,因此,通过 validate-dashboard-json 验证的预设也能被两种方式接受。
何时使用
- “创建一个……的仪表板” / “创建一个包含……面板的仪表板” →
create-dashboard - “给我……的仪表板 JSON” → 预设 JSON
- “生成一个仪表板预设” → 预设 JSON
完成前务必验证
在创建或交付预设前,调用 validate-dashboard-json 验证它。
该工具不会存储任何内容,因此可按需反复调用。
# valid=false findings=2
path rule message
/panels/0/queries/0/selectedMode shape value must be one of 'logs', 'metrics', 'traces', 'formula'
/gridLayout/0 shape must have required property 'h'
每个 path 都是指向确切待修复值的 JSON Pointer。重复验证,直到 valid=true。
将预设对象作为 document 传入,而不是包含字符串化 preset 字段的导入封装。create-dashboard 的 preset 参数也一样。
验证只检查结构,不检查数据是否存在。针对无人采集的指标编写的查询在结构上仍然有效,但渲染结果会为空,因此请先发现名称。
先发现字段
如果已连接 KubeSense MCP 服务,请先发现真实名称,再编写查询——切勿猜测指标、分组字段或筛选字段。
| 查找内容 | 工具 |
|---|---|
| 指标名称 | get-available-metrics |
指标标签(用于 by) | get-metric-labels |
| 日志/追踪字段 | get-trace-or-log-fields |
仪表板查询使用的是存储层字段名称,而非 MCP 目录中的标签——Web 应用会直接提交这些名称。如果发现结果中的存储列与标签不同,请采用存储列中的字段名称,并提醒用户在面板预览中确认。有关标签与存储字段的区别,请参阅 kubesense-mcp。
如果没有 MCP,请使用用户提供的名称,并说明这些名称需要核实。
输出格式
{
"name": "<dashboard name>",
"description": "",
"preset": "<stringified JSON of the preset object>"
}
重要
在此封装中,
preset是 JSON 字符串,不是嵌套对象。 验证器将其声明为preset: z.string(),并且只会在JSON.parse(preset)后运行预设架构验证。 如果输出对象,验证会失败,并显示 "Preset must be a valid JSON string that matches the dashboard preset schema"。这仅适用于导入封装。
create-dashboard和validate-dashboard-json接受预设对象本身——传入字符串化内容也可以,但不要将其包装在此封装中。
name 为必填项,且不能为空。description 为可选项。
要进行字符串化的对象:
{
"gridLayout": [],
"panels": [],
"variables": [],
"subGrids": [],
"subGridLayout": []
}
只有 gridLayout 和 panels 是必填项;其余字段默认值为 []。另一个可选字段 publicDashboardPath(字符串)也能通过验证。
最小有效仪表板
已通过实时验证器验证:
{
"name": "Minimal",
"description": "",
"preset": "{\"gridLayout\":[{\"i\":\"0\",\"x\":0,\"y\":0,\"w\":12,\"h\":4}],\"panels\":[{\"name\":\"Up\",\"panelType\":\"timeSeries\",\"queries\":[{\"selectedMode\":\"metrics\",\"label\":\"A\",\"selectedMetric\":\"up\",\"functions\":[]}],\"config\":{}}],\"variables\":[],\"subGrids\":[],\"subGridLayout\":[]}"
}
导入时会导致硬性失败的情况
以下情况有误时,导入会被拒绝并报错:
preset不是字符串。- 顶层
name缺失或为空。 - 缺少
gridLayout或panels。 gridLayout项缺少i、x、y、w、h中的任一项,或类型错误(例如用"6"代替6)。- 面板缺少
name,或name: ""。 - 面板缺少
queries数组(数组可以是[],但该键必须存在)。 - 查询的
selectedMode不是metrics|logs|traces|formula之一。 - 日志/追踪查询缺少
columnFields——这是这些查询唯一必需的字段。 columnFields[]项中的field: ""。- 公式缺少
expression,或包含小写字母或小数点。 - 公式引用未定义的标签、引用自身、排在其引用的查询之前,或使用多字符标签。
会悄无声息地破坏数据的情况
比硬性失败更危险——这些数据会通过验证,然后丢弃你发送的内容。
几乎每个字段都带有 .catch(),因此只要有一个值错误,整个数组或对象就会重置为默认值。
| 字段 | 值错误时的结果 |
|---|---|
functions(指标查询) | 整个数组会被清空为 []——一条格式错误的条目就会导致所有函数丢失 |
variables | 所有变量都会被删除——一个无效变量就会清空整个数组 |
subGrids | 所有子网格都会被丢弃 |
subGrids[].panels | 该行的面板会被清空 |
aggregation | 重置为 {"function": "row_count"} |
panelType | 重置为 "timeSeries" |
chart_type | 重置为 "table" |
yAxisLabelFormatter | 重置为 "auto" |
colorScheme | 重置为 {"type":"palette","palette":"default"} |
step | 非整数值(例如 60.5)会重置为 "auto" |
pagination | page_size > 500 时,整个对象会重置为 {page:1,page_size:50} |
因此,与其猜测可选字段的值,不如省略它——省略字段会使用默认值;填错值则可能导致同级字段也被丢弃。
警告
gridLayout的条目数必须不少于panels。 面板和布局是按数组索引的位置匹配,而不是根据i值匹配。gridLayout条目不足时会通过验证,但仪表板渲染时会抛出 TypeError。i字符串仅用于通过sg-前缀识别子网格行;实际导出时会将其设为索引("0"、"1"、……)。
面板
{
"name": "CPU by namespace",
"description": "",
"panelType": "timeSeries",
"queries": [],
"config": {}
}
panelType — 12 个值:timeSeries、stat、table、list、bar、pie、topList、
treemap、alert、spl、sql、slo。注意 timeSeries 使用 camelCase。
config 导入永远不会失败(整个对象都会被捕获),因此 {} 始终安全,并会继承所有默认值。完整字段列表、默认值,以及 colorScheme /
thresholds / alignColumns / columnFormatting / visualFormattingRules 的结构,请参阅
references/panel-config.md。
对于 表格 面板,每列的显示名称、可见性、单元格类型(number / bar)和阈值/范围着色都放在 config.columnFormatting[] 中——参阅参考文档。
对于 顶部列表 面板,config.topListDisplayMode 可以是 flat(默认值)或 stacked,而
stacked 需要 两个或更多 groupBy 条目——第一个是行,其余的是在行内堆叠的区块。只有一个维度时,无论字段设置为何,渲染器都会绘制为平铺模式。基于值的着色放在 config.visualFormattingRules[] 中;对于此面板类型,它会 取代 thresholds。两者都见参考文档。
对于 矩形树图 面板,为查询设置 groupBy,并保持 config 不变——除 colorScheme 和单位外,它没有自己的配置;它会为每个返回的序列绘制一个单元格,根据值确定大小,并从面板调色板中按类别着色。它是一个即时面板,类似 pie / topList,因此 config.step 不适用。它的 chart_type 是 topList(见下文),因为查询级枚举没有 treemap 分支。所有序列都会返回,因此请使用查询自身的 limit 限制结果,而不要指望面板进行裁剪。
对于 告警 面板,查询会指定规则以及用于绘制该规则的组件:
widgetType 可以是 graph、value 或 summary。graph 和 value 需要 ruleId
(并在 ruleName 中缓存规则名称);graph 还需要 vizType,可以是 timeseries
(默认值)或 topList,后者会按每个序列的最新值对规则自身的查询结果排序。value 只显示该规则当前的数值——如果某条规则在多个序列上触发,则显示超出阈值最远的那个值;对于 greater_than 规则,显示最高值;对于
less_than 规则,显示最低值。summary 则读取 filters,以及
displayFormat(count / list / both)、colorPreference(text / background)和
summaryType(monitor / group / combined)。summaryType 决定一行代表什么:
monitor 表示每条规则一行,group 表示每个触发实例一行(按 pod 分组的规则会为每个触发的 pod 显示一行),combined 表示每条规则一行,并在旁边统计其触发实例。与 Datadog 的对应功能不同,group 无法列出正常组——引擎仅在实例触发时才会将其写入,因此从未越过阈值的序列没有可显示的行。
与 slo 一样,它由告警端点提供,而不是由 /explore/query 提供,因此 config.step 不适用,其 chart_type 为 topList。Datadog 的第四种组件 Check
Status 没有对应分支:引擎只会持久化 normal 和 firing,因此四状态组件会有两个单元格无内容可显示。
旧格式中有三个配置字段不正确:
thresholdDisplayMode,不是enableThresholds。可选值:off(默认值)、lines、lines_dashed、filled_regions、filled_regions_and_lines、filled_regions_and_lines_dashed。colorScheme,不是colorPalette。这是一个包含 5 种变体的联合类型;调色板变体为{"type":"palette","palette":"default"},且调色板键只有default、success、warning、error。若要固定某个查询的颜色,不受面板方案影响,请使用该查询自身的fieldConfig.color(见查询级颜色)。mergeTables是z.literal(true),并且位于默认值中——它 始终为true,无法禁用。发送false会被静默转换为true。直接省略即可。
Y 轴单位
yAxisLabelFormatter 接受 199 个值——与 fieldConfig.unit 使用相同的枚举。常见值:auto、number、percentage、bytes、bytes/sec、nanoseconds、milliseconds、seconds、mCPU、CPU。对于聚合 trace duration 的面板,请使用 nanoseconds——格式化程序会自动将 ns 缩放为 µs/ms/s。完整列表见
references/panel-config.md。
警告
percent、percent_unit、short、ops、bps、celsius、fahrenheit和none均不存在,并会静默变为auto。请改用percentage、CPU/mCPU、bytes/sec、number。
查询
根据 selectedMode 区分:metrics | logs | traces | formula。注意,spl 不是有效的 selectedMode——请将 panelType: "spl" 与日志/trace 查询以及
filterMode: "SPL" 配合使用。
Metrics 查询
{
"selectedMode": "metrics",
"label": "A",
"selectedMetric": "container_cpu_usage_seconds_total",
"functions": [],
"filters": {},
"queryMode": "builder",
"promql": "",
"visible": true,
"labelOptions": { "type": "auto" },
"pagination": { "page": 1, "page_size": 50 },
"fieldConfig": {}
}
所有字段均为可选。queryMode 为 builder 或 code——设置 promql 时使用 code,设置 selectedMetric + functions 时使用 builder。
variables 会根据过滤条件和 promql($name 引用)自动推导——你提供的任何值都会被覆盖。无需设置。
日志 / trace 查询
{
"selectedMode": "logs",
"label": "A",
"columnFields": [],
"filters": {},
"queryMode": "builder",
"filterMode": "MFD",
"aggregation": { "function": "row_count" },
"groupBy": [],
"chart_type": "table",
"visible": true,
"sorting": {
"sortBy": { "field": "", "type": "string", "is_attribute": false },
"sortOrder": "ASC"
},
"query": "",
"pagination": { "page": 1, "page_size": 50 },
"fieldConfig": {}
}
重要
必须设置
columnFields——每个日志/trace 查询都要包含它,即使值为[]也一样。 省略它会导致导入直接失败。条目格式:{"field": "namespace", "type": "string", "is_attribute": false},可选包含alias和label。field不能为空。
chart_type——7 个值:table、stat、bar、pie、topList、timeseries、list。 使用小写的timeseries——timeSeries会静默变为table。这是查询级字段, 与面板级的panelType不同。这里有意不提供treemap分支:该面板不适用于 SPL/SQL,因此treemap面板会将chart_type设为topList,与stat面板会将其设为table一样。filterMode——MFD、ADVANCED_QUERY、SPL、SQL。对于 MFD 仅支持相等判断的过滤器无法表达的内容(例如延迟阈值),请使用ADVANCED_QUERY并设置query字符串。groupBy条目使用与columnFields相同的格式。list(数组)和value(字符串)是 SPL/SQL 列字段。没有topListLabel/topListValue。
aggregation 对 type 的要求严格:
{ "function": "p99", "fields": [ { "field": "duration", "type": "float", "is_attribute": false } ] }
row_count——不需要fields。unique_count——必须设置fields,type为"float"或"string"。avg、sum、max、min、p99、p95、p90、p75、p50——必须设置fields,且type必须是字面值"float"。
上述任意一项设置错误——缺少 fields、数值聚合设置 type: "string",或使用了无效名称 function: "count"——都会导致整个聚合静默重置为
row_count,结果是得到行数而非所请求的百分位数。
Formula 查询
{ "selectedMode": "formula", "label": "C", "expression": "A/B", "visible": true, "fieldConfig": {} }
移除空白字符后,expression 必须匹配 ^[A-Z0-9+/*()-]+$。因此:
- 仅限大写字母——
a+b会失败。 - 不能包含小数点——
A*1.5会失败。请使用A*3/2。 - 标签只能是单个字母 A–Z;两个字符的标签会破坏依赖关系检查。
- 公式必须出现在
queries数组中所引用查询的后面。 - 不能引用自身,也不能引用不存在的标签。
单查询配色
任何查询分支(指标、日志、链路追踪、公式)都可以携带 fieldConfig.color。它会为该查询生成的每个序列着色,并且优先级高于面板 colorScheme,包括统计面板的默认基础阈值。只有类型为 thresholds 的显式 colorScheme 优先级更高。查询的含义固定时(错误为红色、成功为绿色),请使用此设置,这样颜色就不会受查询在面板中的位置影响。
{ "selectedMode": "traces", "label": "A", "...": "...",
"fieldConfig": { "color": { "type": "single", "color": "#4AAD5A" } } }
{ "selectedMode": "traces", "label": "B", "...": "...",
"fieldConfig": { "color": { "type": "palette", "palette": "error" } } }
single— 单一十六进制颜色(#rgb、#rrggbb,或带 alpha)。返回多个序列的分组查询会以该颜色的不同深浅绘制,而非全部使用相同颜色。palette—default|success|warning|error,从查询的第一个序列开始循环使用。可选的offset(整数 ≥ 0)用于从后续位置开始。- 省略
color(或整个fieldConfig)即可继承面板配色方案。
导入时,非十六进制颜色或未知的调色板名称会导致验证失败;如果 UI 读取到此类值,则会回退到面板配色方案。完整结构见 references/panel-config.md。
筛选器
filters 的类型为 Record<string, string[]>:
{ "namespace": ["production"], "level": ["ERROR", "FATAL"] }
- 属性键以
@_@为前缀,例如"@[email protected]": ["abc"]。 - 排除项是在值前加
-:{"namespace": ["-kube-system"]}。 $name值表示仪表板变量引用。
指标查询函数
functions 是有序管道。只要有一个条目格式错误,整个数组就会被清空,且参数数量必须与元组完全一致,因此请谨慎构造。
| type | names | arguments |
|---|---|---|
range | rate、increase、resets | [{arg_name:"over", arg_value:"5m"}] — 可以是任意字符串 |
aggregations | sum、avg、max、min、count、No_Aggregations | [{arg_name:"by", arg_value:["namespace"]}] — 必须是数组 |
top_bottom | top、bottom | [{arg_name:"k",arg_value:5},{arg_name:"by",arg_value:"max"}] — by ∈ max|min|avg|median|last |
rollup | avg_over_time、sum_over_time、max_over_time、min_over_time、count_over_time、last_over_time、absent_over_time、present_over_time、increases_over_time、range_over_time、quantile_over_time | [{arg_name:"over", arg_value:"5m"}] — 仅限 30s|1m|5m|30m|1h|1d |
comparison | greater、lesser、greater_than_or_equal、less_than_or_equal、equal、not_equal | [{arg_name:"than"|"to", arg_value:100}] |
transform | clamp(min+max)、clamp_max(max)、clamp_min(min)、round(to_nearest)、histogram_quantile(quantile)、abs / sort / sort_desc(无) | 参数名称见括号;仍然必须提供 arguments 键 — 无参数的函数使用 [] |
警告
range.over可以接受任意字符串,但**rollup.over仅接受30s、1m、5m、30m、1h、1d**。如果rollup的over为"7m",则该查询中的所有函数都会被静默删除。
典型的时序管道:先使用 rate,再使用 aggregations。
"functions": [
{ "type": "range", "name": "rate", "arguments": [ { "arg_name": "over", "arg_value": "5m" } ] },
{ "type": "aggregations", "name": "sum", "arguments": [ { "arg_name": "by", "arg_value": ["namespace"] } ] }
]
网格布局
{ "i": "0", "x": 0, "y": 0, "w": 6, "h": 4 }
五个键都必需。网格为 12 列,rowHeight 为 100px,面板 minH 为 2。不验证边界 — 接受 w: 99,但渲染结果会出错。
x:0–11。并排布局:两列使用0, 6;三列使用0, 4, 8。y:按上一行的高度递增。i:数组索引,字符串形式。匹配按位置进行,因此gridLayout的顺序必须与panels相同,且长度至少与其相同。
变量和行
两者均为可选项,大多数仪表板都不需要 — 省略 variables、subGrids 和
subGridLayout 即可,它们默认均为 []。
如果仪表板需要模板变量(通过下拉菜单将 $name 传入查询筛选器)或行(可折叠的面板组),请阅读
references/variables-and-rows.md 了解架构。
请记住两点:变量必须提供 description(可使用 ""),一个无效变量就会静默删除所有变量。
交付
直接创建
validate-dashboard-json → valid=true → create-dashboard
create-dashboard 接受 name、preset(对象,或包含该对象的 JSON 字符串)以及可选的 description。它会返回仪表板 ID 和 UI 路径——请引用该路径,以便用户打开仪表板。
这是一个写入工具:只有在用户明确要求创建仪表板时才调用,并且要在调用前说明你将要创建什么。如果调用被拒绝,响应会列出每个问题对应的 JSON Pointer;请修复问题并重试,不要转而直接交付 JSON。
提供 JSON 供导入
- 将 JSON 复制到
.json文件中(导入 UI 要求使用application/json)。 - KubeSense → 仪表板 → 导入。
- 上传并检查,然后保存。
使用此方式时,绝不要声称仪表板已创建——由用户导入并确认。
规则
规则 0:创建或交付前,先运行 validate-dashboard-json,并修复其报告的问题。导入时会硬性失败的情况中的所有内容都会由机器检查——验证器会指出 JSON Pointer,因此这里无需列出检查清单。
此检查清单涵盖验证器无法发现的问题。 以下每条规则都能通过验证,但之后会悄无声息地丢弃你的数据,或在渲染时崩溃。验证通过不代表仪表板可用——交付前请手动检查这些问题。
gridLayout的长度必须至少与panels相同,且顺序一致——它们按位置匹配,布局过短会导致仪表板渲染时抛出 TypeError。- 数值聚合要求
fields[].type: "float"完全匹配,否则整个聚合会重置为row_count——你要求的是百分位数,结果却变成行数。 chart_type必须为小写的timeseries;panelType必须为驼峰命名的timeSeries。两者不匹配时,各自都会重置为默认值(table/timeSeries)。rollup.over只接受30s/1m/5m/30m/1h/1d;值无效会清除该查询中的所有函数。- 变量必须包含
description(使用""),且name必须符合正则表达式并且不超过 20 个字符——一个变量不符合要求就会删除所有变量。 - 使用真实的 y 轴单位(
percentage、mCPU、bytes/sec)——percent、short、none会变成auto。 - 不要输出
enableThresholds、colorPalette、mergeTables: false、topListLabel或topListValue——这些字段都不存在,未知键会被移除且不作提示。对于顶部列表,值的着色应放在visualFormattingRules中,而不是thresholds中。 - 可选字段宁可省略,也不要猜测:省略字段会使用其默认值,错误的字段则可能导致其同级字段重置。
- 验证只检查结构,不检查是否存在。编写查询前,先通过 MCP 查找指标名和字段名,并提醒用户在面板预览中确认。
唯一同时适用于两种情况的规则:在导入封装中,preset 是字符串化的 JSON 字符串;但传给 create-dashboard 或 validate-dashboard-json 时,它是普通对象。