关于 signoz-modifying-dashboards
通过 SigNoz MCP 工具修改现有 SigNoz 仪表板的技能,面向需要调整仪表板的 Agent。它涵盖目标识别、状态保留、变更规划,以及面板、查询、变量和布局的更新。
主要功能
- 01编辑面板与查询
- 02管理变量和元数据
- 03调整面板布局与尺寸
- 04事先确认破坏性或含糊的变更
- 05通过试运行验证变更后的查询
适用场景
- 01修改面板标题、查询或显示类型
- 02添加或删除仪表板面板
- 03调整变量、标签或面板阈值
- 04重新排列各区段中的面板
MCP 相关
使用 SigNoz MCP 工具检查仪表板、查找字段和指标、应用变更并验证更新后的查询。若工具尚未配置,技能会引导通过 `signoz-mcp-setup` 完成设置。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ signoz/ agent-skills --skill signoz-modifying-dashboards安装后在 Claude Code 中输入/signoz-modifying-dashboards确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/files/dry-run-validation-error.jsonenvironment-variable-scope-context.jsonnon-final-row-dashboard.jsonpromql-timeout-retry.jsontarget-on-second-page.jsonupdate-payload-contract.json详细介绍
仪表板修改
前提条件
此技能会调用 SigNoz MCP 服务工具(signoz_get_dashboard、
signoz_patch_dashboard、signoz_update_dashboard、signoz_list_dashboards、
signoz_list_metrics、signoz_get_field_keys、signoz_get_field_values、
signoz_execute_builder_query)。
运行工作流前,请确认 signoz_* 工具可用。
如果这些工具不可用,说明 SigNoz MCP 服务尚未安装或配置;
请先运行 signoz-mcp-setup,以初始化或修复 MCP 连接。请勿
改用原始 HTTP 调用或在没有 MCP 工具的情况下手动编辑仪表板 JSON。
适用场景
当用户要求以下操作时,使用此技能:
- 在现有仪表板上添加、移除或编辑面板/小组件
- 更改面板的查询、标题、类型或显示设置
- 添加、移除或编辑仪表板变量
- 重命名仪表板或更改其描述
- 调整面板布局或调整面板尺寸
- 更改面板类型(例如,从图表改为表格,从数值改为图表)
- 在面板上添加或修改阈值
- 更新仪表板上的标签
请勿在以下情况使用:
- 用户想了解仪表板展示的内容 →
signoz-explaining-dashboards - 用户想创建新仪表板 →
signoz-creating-dashboards
说明
步骤 1:确定目标仪表板
使用直接提供的 ID 或仪表板资源上下文中的 ID。名称不是
ID:对于所有仅提供名称的请求,都使用 signoz_list_dashboards 查找;通过
filter 参数缩小范围(参见 signoz://dashboard/list-filter-guide),并按
offset 翻页,直到覆盖 total。根据 spec.display.name 匹配。如果有多个
仪表板匹配,请列出它们并询问要修改哪一个;如果只有一个匹配项,则使用其 ID。
步骤 2:获取当前仪表板状态
调用 signoz_get_dashboard 并传入仪表板 ID,以获取其完整
配置。这是必需步骤:signoz_update_dashboard 需要完整的更新后状态,而补丁也需要实际的面板 ID 和网格项索引。切勿跳过此步骤。
检查响应,了解以下内容:
- 当前面板及其 ID(
spec.panels是以面板 ID 为键的映射) - 当前网格项的位置(在 12 列网格中的 x、y、宽度和高度)
- 当前变量
- 每个包含查询的面板上的当前查询(且恰好有一个);
signoz/TextPanel的queries: []则为非空值 spec.layouts结构:每个分区对应一个 Grid,且各自拥有自己的 items
获取到的 source 为 user、system 或 integration。只有 source=user
的仪表板可以修改。如果是 system 或 integration,请说明该仪表板不可修改,然后停止。v2 列表不包含 system 行,但仍可通过已知的 system ID 获取仪表板。请勿查找特殊的 system 发现工具,也不要尝试更改 source。
第 3 步:规划修改
根据用户的请求,规划所需更改。
以下情况应用更改前须与用户确认:
- 修改具有破坏性:移除面板、删除变量、将整个查询替换为另一个查询、更改查询的
signal(例如,将 traces 改为 logs),或从根本上改变所显示的数据(将聚合方式从 p99 改为 avg,移除 groupBy 维度) - 请求含糊不清:可能有多个面板符合“延迟面板”
- 更改规模较大:重构各个部分,或一次添加多个面板
破坏性意味着数据丢失或行为悄然改变。 即使用户说“赶紧做”,简单确认一下(“我会永久移除‘Memory Fragmentation’。可以吗?”)也只需几秒,却能避免不可逆的错误。用户的紧迫要求不能凌驾于这项防护措施之上。
非破坏性更改无需破坏性确认: 重命名、添加面板或变量、更改单位或面板类型、调整布局,以及添加阈值。添加变量仍须遵循下方的面板适用性提示。
复合修改: 如果请求涉及多项更改(例如,移除面板 + 添加面板 + 重命名),请根据获取的状态规划所有更改,并一次性应用:一个补丁数组可以包含多个操作。不要在每项更改之间应用修改并重新获取状态。
第 4 步:应用修改
先选择写入工具。 默认使用 signoz_patch_dashboard(RFC 6902):
它只发送发生更改的操作,因此不会丢弃无关面板。读取 signoz://dashboard/patch-instructions,了解 JSON Pointer 路径。只有在仪表板的大部分内容都需要更改时,才使用 signoz_update_dashboard(将完整替换内容合并到第 2 步获取的状态中)。以下规则适用于这两种工具;每条规则都会说明其补丁路径。
操作按顺序执行,并基于前一操作完成后的文档进行。 当一个补丁要移除同一数组中的多个条目(网格项、布局、变量、标签或复合查询的成员查询)时,请按索引降序排列这些移除操作。否则,每次移除都会重新编排其后条目的索引,过时的索引会悄然删除错误条目,或导致操作无效果(移除不存在的路径不会报错)。根据第 2 步状态规划的索引,仅对每个数组的第一次移除有效。
修改规则:
-
时间范围和刷新频率属于查看器控件。 仪表板负载不会持久化默认时间范围或刷新间隔。如果用户要求更改其中一项,请说明面板遵循查看器选择的全局范围;不要自行添加
timeRange、defaultTimeRange或refresh字段。 -
保留受支持的可变状态。 复制获取到的仪表板,仅更改用户提出的内容,并在 MCP 标准化之后比较语义。不要丢弃无关面板、变量、网格项或部分内容。
-
保留面板/网格项的标识。
spec.panels中的每个面板 ID 都必须且只能对应一个网格项,该网格项的content.$ref需指向此面板;添加或移除面板时,必须同时处理对应网格项。原样复用现有面板 ID:重命名是显示内容的更改,不是新建 ID。 -
每次写入前读取架构。 读取写入工具指定的所有必需资源和适用的条件资源。对于 Query Builder,还需根据对应的信号读取
signoz://metrics-aggregation-guide、signoz://traces/query-builder-guide或signoz://logs/query-builder-guide。MCP 是事实来源。 -
添加面板:
- 使用简短且稳定的 id 构建面板,并在
/spec/panels/<id>处执行add。如果仪表板中已有目标类型的面板,请直接使用 Step 2 响应中的该面板 JSON,而不要自行组合(遵循更新路径中的相同差异比较与合并原则,且服务端自身的结构已知有效)。重新指定每个用于标识数据的字段(aggregation、groupBy、filter.expression、order、legend、alias、signal);克隆面板时即使有一个字段过期,结构仍然有效且会被接受,因此必须执行下方的试运行来检查。仅当不存在该类型的面板时,才从signoz://dashboard/widgets-examples组合。 - 选择用户所指的 Grid:各个区段是
spec.layouts中彼此独立的条目,每个条目都有自己的spec.display.title和项目坐标,因此添加到较早的区段只会影响该 Grid。 - 在
/spec/layouts/<n>/spec/items/-处add一个网格项目,其content.$ref为#/spec/panels/<id>,并遵守下方的边界条件。除非明确要求并排放置,否则将其设为x: 0、y: max(y + height),位置在该 Grid 内。没有网格项目的面板会被接受,但永远不会渲染。
- 使用简短且稳定的 id 构建面板,并在
-
移除面板: 同时移除网格项目(其在对应 Grid 中的从零开始的索引)和
/spec/panels/<id>条目;若项目仍指向已移除的面板,则会被拒绝。 不要尝试自动紧凑布局或调整剩余面板的y位置;SigNoz 前端网格引擎会自动填补空隙。只需移除这两个引用(面板条目、网格项目),并保持其他所有位置不变。 -
编辑面板查询: 替换
/spec/panels/<id>/spec/queries/0处的查询,并保持其他面板字段不变;绝不要追加第二个查询,因为带查询的面板恰好只包含一个查询。TextPanel 不包含查询。 -
添加或编辑文本: 使用
signoz/TextPanel,模式为markdown,并设置非 null 的空queries: [],同时采用当前资源的显示结构。需同时添加面板和对应的 Grid 项目。TextPanel 跳过查询发现和试运行。不要自行创建行面板。 -
更改面板类型: 同时更新插件
kind和查询封装的kind(signoz/TimeSeriesPanel+time_series→signoz/TablePanel+scalar):遵循widgets-examples中目标类型的完整结构。保留现有查询和 signal;只更改特定于可视化的字段。signoz/TimeSeriesPanel和signoz/AreaChartPanel都使用time_series查询,因此在两者之间切换时只需更改插件。不要在面积图中叠加延迟、百分位数或比率。 -
添加/编辑变量:
- 对于含义不明确或受版本影响的属性,调用
signoz_get_field_keys并可选择使用相关 signal 和fieldContext=resource调用signoz_get_field_values。以发现的键为准(例如,deployment.environment而非deployment.environment.name)。 - 显示面板列表,并询问变量适用于所有面板还是所选子集。
- 对于基于属性的下拉菜单,使用带有
signoz/DynamicVariable插件的ListVariable,并在/spec/variables/-处追加。其spec.name是$handle;plugin.spec.name是属性键。 - 仅将
$<name>添加到所选面板的filter.expression,保留未选中的面板,并对变量更改影响的每个查询执行试运行。
- 对于含义不明确或受版本影响的属性,调用
-
重新排列布局/并排放置: 修改
/spec/layouts/<n>/spec/items/<i>处的网格项;不改动面板映射。- SigNoz 使用 12 列网格,绝不是 24 列:每个条目都必须满足
0 <= x < 12、1 <= width <= 12和x + width <= 12。 - 两个面板并排:每个面板的
width: 6,第一个的x: 0,第二个的x: 6,且y和height相同。 - 一行放置三个面板:每个面板的
width: 4,x分别为0、4、8。 - 调整现有面板大小以腾出空间时,先更新其
width和x,再将新面板放入腾出的空间,并保持相同的y。 - 常见高度:图表/表格使用
height: 6,数值面板使用height: 2–3。
- SigNoz 使用 12 列网格,绝不是 24 列:每个条目都必须满足
对修改后的面板进行试运行(必须)。 对于每个新增或更改的、带查询的面板,都要遵循
signoz://dashboard/widgets-instructions 中的“试运行面板查询”。
面板已存储执行规范,因此要将其提取到外层封装中,并使用该负载调用 signoz_execute_builder_query。试运行时使用较短的绝对 Unix 毫秒时间窗口,通常为最近 30–60 分钟;切勿不加判断地使用面板的显示范围;扩大范围或重试之前,先遵循该部分关于空结果和超时的规则。试运行副本中使用有代表性的变量值,并在保存状态中保留 $var。
对每个更改过的 Builder 查询/公式,都要保留或添加明确的结果上限:保存的规范中必须包含正数 limit 和非空的 order,且试运行时原样发送这些值。列表面板和跟踪请求面板默认返回 100 行,并按时间戳降序排列(原始日志还按 ID 降序排列),但要保留有意设置的更小正数列表上限。
独立聚合查询和公式输出默认返回 100 个分组。公式引用的每个基础查询都使用 10000,因为公式计算前会应用基础查询上限;除非较小的现有上限是有意设置的公式计算前 Top-N 选择,否则应提高该上限。检查每个公式表达式(包括 disabled: true 的公式),并沿公式引用追踪到所有 builder_query 叶节点,以找出完整的基础查询集合。这种依赖遍历仅用于确定上限;它不能确定公式之间的确定性计算顺序,因此要试运行完整的复合负载。保存的面板和试运行都应让基础查询按其主要聚合排序,让公式按 __result 排序。对于时间序列,Top-N 是根据整个时间窗口选取的,因此短暂出现的局部峰值可能会被省略。如果公式输入的基数可能超过 10000,应缩小筛选范围或分组范围。
如果执行器无法表示保存的字段,应将面板报告为未经验证,并且只有在获得明确接受后才能继续。服务器错误、验证错误和意外的空结果都会阻止继续,除非明确接受。
调用 signoz_patch_dashboard,并传入 ID 和操作数组;操作应用后会验证结果,锁定的仪表板会被拒绝:
signoz_patch_dashboard({
"id": "<dashboard-id>",
"patch": [{"op": "replace", "path": "/spec/display/name", "value": "New title"}]
})
如果写入失败,绝不要重新发送相同的负载。 客户端的 InputValidationError 从未到达 SigNoz,因此完全相同的重试不可能成功;弄清楚失败原因也不意味着可以再次尝试。正是这种推理会让两次失败变成二十次。每种方案最多尝试两次,然后更换方案:采用克隆并重新指向,而不是创作新内容;或者将一个补丁拆分成多个。如果两种方案都失败,就停止并向用户报告确切的操作和错误文本,而不是尝试第三种方案。这仅限制客户端验证失败;试运行超时属于服务器端情况,此时缩小时间窗口后重试是正确的做法。
对于完整替换,signoz_update_dashboard 要求将合并后的状态与 id 平铺放置,而不是嵌套在 dashboard 键下。合并到第 2 步响应的 data 对象中;传入 {status, data} 封装本身会被拒绝。将获取到的 name(不可变的机器标签)原样传回,并删除 GET 返回的只读字段(createdAt、updatedBy、orgId、webUrl 等):
signoz_update_dashboard({
"id": "<dashboard-id>",
"schemaVersion": "v6",
"name": "<the fetched name, unchanged>",
"tags": [...],
"spec": <complete merged spec from signoz_get_dashboard>
})
同时,从更新请求体中省略只读的 source、生成的链接、锁定/公共元数据以及其他由服务端填充的字段。通过拒绝非用户写入来保留其含义,而不是将这些字段一并发回。
步骤 5:报告结果
简要告知用户所做的更改。视情况提供进一步修改。
防护措施
- 优先使用补丁;更新时提交完整状态:对于定向编辑,优先使用
signoz_patch_dashboard。确实需要完整替换时,signoz_update_dashboard要求在id旁以扁平结构提交完整仪表板(schemaVersion、name、tags、spec),不得嵌套在dashboard键下。务必先调用signoz_get_dashboard,将更改合并到响应的data对象中,原样传回name,绝不要从头构造请求负载。 - 保留未更改的内容:保留请求范围之外的面板、变量和网格项所支持的可变语义。执行差异比对并合并;不要重建数据,也不要承诺 MCP 规范化后能逐字节保持相同。
- 确认破坏性更改:移除面板、替换查询或删除变量前,务必向用户确认,即使用户说“直接做”或表达了紧迫性。添加、重命名、更改类型和添加变量无需确认。
- 验证更改的查询:写入前,必须先执行上述强制性试运行步骤。
- 仅限有效 JSON:遵循
signoz://dashboard/*MCP 资源(instructions、widgets-instructions、widgets-examples、query-builder-example)中记录的架构。绝不要生成格式错误的查询或布局。 - OTel 属性名称:使用
service.name,而不是service;使用host.name,而不是host。但对于deployment.environment与deployment.environment.name等随版本变化的键,应先查明,再决定使用哪种形式,不要强行指定。 - 不得猜测指标:如果要添加或更改查询,但不确定有哪些指标可用,请询问用户或调用
signoz_list_metrics查找可用指标。错误的指标名称会导致面板为空。 - 对仪表板列表分页:按名称搜索仪表板时,务必遍历完整的
signoz_list_dashboards结果,再判断仪表板是否不存在。 - 标识符:为新面板指定简短、稳定的 ID,并在网格项的
content.$ref中引用;每个变量的spec.name必须与其查询使用的$handle完全一致;A、B和F1等查询名称必须保持稳定。 - 仅使用 Perses 和 source:使用规范的 v6 Perses 路径和字段。TextPanel 使用
queries: [];每个查询面板仅包含一个查询。绝不持久化旧版widgets、panelMap、panelTypes、queryData、selectedLogFields或selectedTracesFields。绝不写入非用户仪表板。 - 仅使用真实仪表板 ID:绝不要将
"unused"之类的哨兵值用作仪表板 ID。先通过signoz_list_dashboards和signoz_get_dashboard查明真实 ID。 - 范围边界:此技能用于修改现有仪表板。新建仪表板的请求应交由
signoz-creating-dashboards处理。
示例
用户:“在我的 Redis 仪表板中添加一个错误率面板”
Agent:
- 调用
signoz_list_dashboards并设置filter="redis";找到名为“Redis Overview”的 仪表板,其 ID 为abc-123。 - 调用
signoz_get_dashboard并传入 IDabc-123;获取完整配置,其中包含两个 Grid 分区中的 8 个现有面板。 - 调用
signoz_list_metrics,查找可用的 Redis 错误指标。 - 创建一个新的时序面板(一个包含两个已禁用基础查询和错误率公式的
signoz/CompositeQuery),并在 Overview Grid 中最后一个项目下方为其添加一个网格项。 - 使用
signoz_execute_builder_query对新面板进行试运行;修复任何错误或意外的空结果。 - 调用
signoz_patch_dashboard,传入两个操作(add /spec/panels/error-rate和add /spec/layouts/0/spec/items/-),而不是重新发送全部 9 个面板。 - 回复:“已在 Redis Overview 仪表板的 Overview 分区中添加‘Error Rate’时序面板。需要我调整什么吗?”
用户:“将我的 API 仪表板中的延迟面板从图表改为表格”
Agent:
- 通过带筛选条件的
signoz_list_dashboards查找“API Monitoring”,然后调用signoz_get_dashboard并传入其 ID。 - 找到标题为“Request Latency”的面板;如果有多个面板可能匹配,则向用户确认:“我找到了‘Request Latency’。要将它转换为表格吗?”
- 将插件
kind改为signoz/TablePanel,将查询kind改为scalar,匹配widgets-examples中的表格结构,并保持查询不变。 - 由于面板类型会影响请求结构,因此对表格执行结构进行试运行。
- 调用
signoz_patch_dashboard,对该面板的插件和查询 kind 执行 replace 操作。 - 回复:“已将‘Request Latency’从图表改为表格。需要我调整列宽或添加列单位吗?”
用户:“移除 CPU 面板,并将仪表板重命名为‘Service Health’”
Agent:
- 通过
signoz_get_dashboard获取仪表板。 - 找到“CPU Usage”面板。确认:“我将移除‘CPU Usage’面板,并将仪表板重命名为‘Service Health’。继续吗?”(移除操作具有破坏性;务必先确认。)
- 用户确认。
- 移除面板条目及其网格项。保持所有其他面板的位置不变(前端网格会自动填补空隙)。通过
/spec/display/name重命名,绝不修改不可变的顶层name。 - 调用
signoz_patch_dashboard,在一个数组中传入全部三个操作。 - 回复:“已移除‘CPU Usage’面板,并将仪表板重命名为‘Service Health’。还需要调整其他内容吗?”