关于 signoz-generating-queries
该技能指导 Agent 使用 SigNoz MCP 工具查询指标、日志和链路数据,适合进行可观测性检索与分析。它强调先发现可用数据和字段,再选择匹配的查询工具。
主要功能
- 01查询指标、日志与链路
- 02按意图选择信号类型
- 03查询前发现指标和字段
- 04支持聚合与趋势分析
适用场景
- 01计算延迟、错误率或吞吐量
- 02查找日志、链路或指标
- 03分析数据随时间的变化
MCP 相关
依赖 SigNoz MCP 服务提供的工具执行数据发现、查询、搜索和聚合;若工具不可用,需先初始化或修复 MCP 连接。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ signoz/ agent-skills --skill signoz-generating-queries安装后在 Claude Code 中输入/signoz-generating-queries确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/files/capped-logs-failed-count.jsonservice-absence-traces.json详细介绍
查询生成
先决条件
此技能会频繁调用 SigNoz MCP 服务工具(signoz_execute_builder_query、
signoz_query_metrics、signoz_search_logs、signoz_search_traces、
signoz_aggregate_logs、signoz_aggregate_traces、signoz_get_field_keys、
signoz_get_field_values、signoz_list_metrics、signoz_list_services、
signoz_get_service_top_operations、signoz_get_trace_details)。运行工作流前,请确认
signoz_* 工具可用。如果不可用,请先运行 signoz-mcp-setup,以初始化或修复 MCP 连接。
不要改用原始 HTTP 调用,也不要在没有 MCP 工具的情况下捏造查询结果。
适用场景
当用户要求以下操作时,请使用此技能:
- 查询、搜索或查找可观测性数据(追踪、日志、指标)
- 计算聚合值(错误率、p99 延迟、请求数、吞吐量)
- 查找特定日志条目、追踪或指标值
- 调查模式(随时间变化的峰值、下降或趋势)
请勿在以下情况下使用:
- 用户需要用于仪表盘面板的原始 ClickHouse SQL(自定义联接、窗口函数、对日志正文使用正则表达式);这是单独的仪表盘面板 SQL 工作流,不属于此技能。
- 用户需要将 Exceptions Explorer 作为异常专用信号:当前 MCP 契约没有异常查询工具。请说明此限制;只有在能回答用户根本问题时,才提供等效的错误追踪或错误日志查询。
说明
第 1 步:确定信号类型
将用户意图映射到合适的信号:
| 用户意图 | 信号 | 原因 |
|---|---|---|
| 错误率、延迟、吞吐量、请求数 | 指标(首选)或 追踪 | 指标已预先聚合,查询速度最快。如果用户需要单个请求的详细信息,或没有匹配的指标,则使用追踪。 |
| p50/p75/p90/p95/p99 延迟 | 指标(直方图)或 追踪(对 duration_nano 聚合) | 如果存在直方图指标(例如 signoz_latency_bucket),优先使用指标;否则回退到追踪聚合。 |
| 查找特定日志条目、错误消息、堆栈追踪 | 日志 | 文本搜索、模式匹配、严重性筛选。 |
| 查找特定追踪、慢请求、错误 Span | 追踪 | 单个请求的详细信息、Span 属性、时长筛选。 |
| 基础设施指标(CPU、内存、磁盘、网络) | 指标 | 资源利用率一律使用指标。 |
| 采集量(字节数或数量)、成本或计费使用量 | 使用 source=meter(Cost Meter)的 指标 | signoz.meter.* 采集指标(日志/Span/数据点的数量和字节数)只存在于 Meter 存储中;原始信号不提供字节数。金额不是指标;应根据数量 × 单价计算(见第 2 步)。groupBy/筛选的用法与普通指标相同,但只能针对 Meter 保留的有限属性集(不能使用任意日志/追踪字段)。如果要按 Meter 不包含的属性细分数量,请直接聚合日志/追踪。 |
| “每个 Y 有多少个 X”(按维度分组的数量/速率) | 追踪或日志(聚合) | 使用 signoz_aggregate_traces 或 signoz_aggregate_logs 获取分组计数。 |
追踪不支持无条件的全文搜索;请对已发现的结构化追踪字段使用 CONTAINS。便捷搜索 searchText 仅适用于日志。
如果信号类型确实不明确,请先询问用户,再继续操作。问题的呈现方式由宿主应用决定(例如结构化澄清工具或内嵌的 <assistant_question> 标签);请遵循宿主应用的 UI 渲染规则。
第 2 步:发现可用数据
查询前务必先发现。 只能使用工具返回的名称,切勿根据训练知识猜测。
尽可能并行执行发现调用:
-
对于指标:调用
signoz_list_metrics,并使用与用户意图匹配的子字符串作为searchText(例如,searchText: "http"、searchText: "latency")。 响应包含指标类型、暂时性和isMonotonic;将这些信息传递给signoz_query_metrics,避免额外查询。过滤或分组前,调用signoz_get_field_keys(signal: "metrics", metricName: <discovered-name>)发现标签;指标标签不是追踪/日志属性(例如,db.system是 span 属性,除非发现结果也将其列为指标标签)。根据发现的指标元数据选择
timeAggregation:指标类型 有效的 timeAggregationgauge latest、sum、avg、min、max、count、count_distinct单调 counter/sum rate、increase非单调 sum avg、sum、min、max、count、count_distinct;切勿使用latest或ratehistogram / exponential histogram 省略;聚合会自动进行 -
对于 Cost Meter(摄取量、成本、账单):向
signoz_list_metrics传递source=meter,以发现指标(signoz.meter.*);这些指标在默认存储中不可见,而且集合会不断变化,因此不要硬编码。groupBy/过滤器/聚合的用法与其他指标相同,但有三个注意事项: 只有这里才有字节数(也可通过直接调用signoz_aggregate_logs/_traces获取数量);meter 只保留有限的 属性集合,因此请通过signoz_get_field_keys(signal: "metrics", source: "meter")发现可分组的键;如果所需属性不在其中,就回退到直接计数(不含字节数);而且美元成本不是 meter 指标: 存储中只有用量,因此不要使用searchText: "cost"并期待得到结果。 若用户询问成本,请查询用量指标(日志/追踪使用字节数,指标数据点使用数量),再乘以 Settings → Billing 中的单价;如果不知道单价,请向用户询问。 -
对于追踪:调用
signoz_list_services确认服务名称存在; 如果pagination.hasMore为 true,则继续根据pagination.nextOffset翻页,再判断服务是否缺失。 可以选择调用signoz_get_service_top_operations,查找该服务的操作名称。使用任何属性进行过滤或分组前,调用signoz_get_field_keys(signal: "traces")。 -
对于日志:使用任何属性进行过滤或分组前,调用
signoz_get_field_keys(signal: "logs");发现后才使用signoz_get_field_values验证值。
字段键因信号而异:日志中可能没有 service.name,而 body 仅适用于日志。切勿跨信号沿用键。只有当本次对话中的实时输出已为同一信号返回该键时,才可跳过键发现;用户文本或记忆中的信息不算。原样使用返回的点分隔表示法,不要猜测诸如 traceID 或 hostname 这样的 camelCase 名称。切勿假设租户键(org.id、orgId、organization_id 等);请按信号发现实际键。调用 signoz_get_field_values 前,必须先调用 signoz_get_field_keys;两者都需要 signal,且值查询还需要一个非空、已发现的 name。
第 3 步:选择合适的工具
使用能回答问题的最简单工具:
| 问题类型 | 工具 | 适用场景 |
|---|---|---|
| 指标时间序列、标量、比率或公式 | signoz_query_metrics | 常规指标查询、Cost Meter 趋势/速率,以及通过 formula + formulaQueries 查询指标比率。 |
| Cost Meter 总量或分组归因总量 | signoz_execute_builder_query | 使用发现的 meter 指标,并设置原始 timeAggregation: "sum";对完整的小时桶求和。不要使用 signoz_query_metrics 查询总量。 |
| 日志搜索(查找匹配条目) | signoz_search_logs | 查找特定日志行。使用 searchText 查找字面文本(searchScope 选择匹配范围;默认是日志正文),使用 filter 筛选字段,使用 severity 按级别筛选。 |
| Trace 搜索(查找匹配 span) | signoz_search_traces | 查找特定 Trace/span。使用 service、operation、error、minDuration/maxDuration 快捷参数,并使用 filter 筛选字段。 |
| 日志聚合(计数、平均值、百分位数) | signoz_aggregate_logs | 简单总量、分组计数,以及按单项聚合计算的 Top-N。 |
| Trace 聚合(计数、平均值、百分位数) | signoz_aggregate_traces | 简单总量、分组计数,以及按单项聚合计算的 Top-N。 |
| 复杂的日志/Trace 公式或整形 | signoz_execute_builder_query | 比率、整形、排序或基数控制超出便捷工具能力时使用;不要手动构建简单的分组计数。 |
日志搜索规范:
signoz_search_logs接受filter;之前的query别名 已被拒绝。searchText是要查找的字面文本,会自动转义。searchScope选择匹配范围;默认是日志正文。它与filter以 AND 组合。 如果没有searchText,则使用searchScope会触发验证错误。searchScope的取值:body(默认值)表示消息文本;attribute或resource表示相应的键和值;all表示所有字段。body以外的范围 速度较慢,SigNoz 可能会在较宽的时间范围内拒绝这些查询。 只有在不知道文本位于哪个键时才使用这些范围;已知键时,应在filter中使用attribute.<key> CONTAINS 'text'这样的谓词。- 如需显式跨字段搜索,请使用
filter: "search('timeout')".signoz://logs/query-builder-guide文档中介绍的search()范围 支持 body、attribute、resource、log,或其允许的组合。 不指定范围的search()表示搜索所有受支持的日志字段;用户只请求 搜索部分字段时,应明确列出范围。 - 已知字段时,优先使用
service.name = 'payments'这样的直接字段谓词, 或使用service快捷参数;服务端会将该快捷参数组合为相同的 AND 条件service.name谓词。先发现不熟悉的字段。 - 构造搜索字面量时,先转义反斜杠,再转义撇号。调用方编写的原始
filter应保持不变;不要再次转义。
对于 signoz_aggregate_logs / signoz_aggregate_traces,aggregation 必须是一个
不带修饰的标记:count、count_distinct、avg、sum、min、max、p50、p75、
p90、p95、p99 或 rate。不要包含括号或列名;将列名放在
aggregateOn 中(count 和 rate 不需要列名)。省略 orderBy 时,默认按
聚合表达式降序排序;显式排序应使用 groupBy 键或聚合表达式。自定义别名或公式
需要使用 signoz_execute_builder_query。
对于每个 signoz_execute_builder_query 负载,每个 builder_query 和
builder_formula 规格都必须包含正数 limit 和非空的 Query Builder v5
order。原始请求和 requestType: trace 的 trace 信号默认返回 100 行:
traces 按 timestamp 降序排列,而原始 logs 按 timestamp 降序、再按 id 降序排列。
标量/时间序列请求默认返回 100 个分组:metrics/公式按 __result 降序排列,
logs/traces 按主聚合降序排列。公式结果仍为 100,但公式引用的每个
builder_query 都使用 10000,因为每个组件的 limit 都会在公式求值前应用;
各自独立的前 100 个输入可能会漏掉比率较高的分组。计算这些输入边界时,
检查每个公式表达式,包括 disabled: true 的公式,并沿公式引用追溯,直到找到
所有 builder_query 叶节点。这种依赖关系遍历只用于设置边界;它不能证明公式之间
具有确定的求值顺序,因此请验证完整的复合负载。如果输入基数可能超过 10000,
请收窄过滤条件/分组。此线缆字段是 order,不是仪表板编辑器的 orderBy。
时间序列的 top-N 会按整个时间窗口对分组排名,因此短暂出现的局部峰值可能不会出现在返回结果中。
聚合的 requestType 选择:
scalar(默认):“有多少个?”、“p99 是多少?”、“哪个服务最多?”time_series:“错误何时激增?”、“延迟如何变化?”、“显示趋势”- 如果问题包含任何时间维度(峰值、趋势、变化),请使用
time_series
聚合工具仅接受 scalar 或 time_series。对于传递给
signoz_execute_builder_query 的 builder-query 封装,只能使用:
| 信号 | 有效的 requestType |
|---|---|
| metrics | time_series、scalar |
| traces | raw、trace、scalar、time_series |
| logs | raw、scalar、time_series |
切勿编造 aggregate、table、timeseries 或 series。此矩阵不适用于 PromQL 或 ClickHouse SQL 封装。
步骤 4:执行查询
- 始终将用户的原始问题作为
searchContext传入,以提高结果相关性。 - 遵循用户指定的时间范围;否则使用 1h。搜索和聚合日志、追踪数据的工具接受相对
timeRange字符串(例如"1h"、"24h";默认值为1h),请优先使用。有效的 Unix 毫秒start/end会覆盖timeRange;显式时间戳格式错误时,会返回指向timeRange的验证提示。signoz_execute_builder_query不支持相对时间选项:其外层query必须包含绝对的start和end,格式为 JSON 整数 Unix 毫秒,否则会报错missing start or end timestamp。 - 当用户的筛选条件与快捷参数(
service、severity、operation、error)匹配时,请使用这些参数;相比构建filter表达式,它们更简单,也更不容易出错。 - 将快捷参数与
filter结合使用以添加其他约束;两者按 AND 关系组合。 - 对于
signoz_query_metrics,请传入signoz_list_metrics响应中的metricType、temporality和isMonotonic,以避免额外的自动获取往返。 - 对于 Cost Meter 总量或分组总量归因,请使用
signoz_execute_builder_query,不要使用signoz_query_metrics。传入完整的工具参数,其中包含外层query对象、Unix 毫秒start/end、requestType: "time_series"、formatOptions和variables。构建器规范需保留signal: "metrics"、source: "meter"、发现的metricName和temporality、stepInterval: 3600,以及原始的timeAggregation: "sum"和spaceAggregation: "sum"。对于分组总量,请使用signoz_get_field_keys查找 meter 字段,并将其name、fieldDataType、fieldContext和signal原样复制到groupBy,不要删减或翻译字段。排除标记为partial: true的数据点,然后对每个返回分组的完整小时桶求和。 - 对于不属于总量归因的 Cost Meter 趋势或速率,仍应使用
signoz_query_metrics。保留source=meter,使用stepInterval: 3600;对于总量趋势,使用timeAggregation: increase,只有在计算每秒速率时才使用rate。
第 5 步:处理结果
每项结论都必须限定在读取结果所覆盖的范围内。 报告之前,先对每项结果进行分类:
- 读取失败:工具返回错误或超时。这不能作为数据不存在的证据。说明读取失败,引用错误信息,并且绝不报告零、“无”或总数。
- 部分结果:原始搜索的备注报告
hasMore=true;任何包含nextCursor的响应,或备注说明还有更多结果或可能还有更多结果的响应;或者返回的分组数恰好等于limit的groupBy聚合(聚合工具不会标记这一点,因此应视为结果被截断)。结论只能涵盖返回的行(“最近的 100 条匹配日志都来自 pod-a”)。绝不能把返回行数报告为总数,也不能根据部分结果声称完整范围或时间窗口内“没有”或“全部”符合条件。 - 完整结果:在完整请求范围和时间窗口内成功执行的聚合,或备注报告
hasMore=false的原始搜索(结果少于limit,包括零条)。只有这类结果才能支持对完整范围使用“没有”“全部”或总数等说法。若总数超过一页,请使用signoz_aggregate_logs或signoz_aggregate_traces,并设置aggregation: count。
返回的数据:
- 将发现作为客观观察呈现,并附上时间戳和值。
- 在回复中注明时间范围。
- 对于包含
groupBy的聚合,突出显示排名靠前的条目。若返回的分组数恰好等于limit,请说明可能还有更多分组;不会报告分组总数。 - 对于搜索结果,总结其规律,而不是逐条列出所有结果。
未返回数据。 说明哪些内容在什么范围内为空,不要做超出该范围的结论:
-
在请求范围内为零:成功且完整的查询未返回匹配项。请说明筛选条件和时间窗口:“过去一小时内,没有符合
service.name = 'checkout-service'的错误跨度。”没有错误或跟踪记录并不能证明该服务运行正常、从未运行,或数据缺失的原因。只有明确标注为可能性时,才能提出这类解释。 -
范围内没有数据:在发现阶段见过该字段或指标,但请求的时间窗口内没有数据点。请说明该空时间窗口,并建议扩大时间范围。在更大范围内看到的较早数据不属于请求时间窗口内的近期活动。
-
发现结果中未找到:指标、字段或服务不在发现结果中。发现范围有限且结果可能有上限;若列表被截断,未找到并不说明任何问题:
signoz_list_services仅列出有跟踪记录的服务(默认时间范围为 6h)。请持续获取pagination.nextOffset,直到hasMore=false。这里未列出的服务仍可能发送日志或指标。signoz_list_metrics列出该时间窗口内活跃的指标(默认时间范围为 1h),且不支持分页。如果其备注报告hasMore=true,请使用searchText缩小范围。- 如果
signoz_get_field_keys和signoz_get_field_values的结果被截断,则会设置data.complete=false。请使用searchText缩小范围。
如果列表完整,请报告“在 中, 时间范围内未见”,而不要说“不存在”或“未埋点”。缺少埋点只是需要核查的可能原因之一,也可以考虑扩大时间范围或尝试其他名称。
深入调查:
- 如果聚合结果揭示了值得关注的规律(如峰值、异常服务),请提出针对该范围深入调查具体跟踪记录或日志。
- 如果跟踪记录搜索返回了值得关注的跨度,请提出通过
signoz_get_trace_details获取完整跟踪详情。
使用规范
- 先发现:切勿猜测指标、字段或服务名称。只有当本次对话中针对同一信号的实时输出确认了某个字段,该字段才算已确认。
- 提供必需参数:切勿调用工具并寄希望于它们自动发现。
signoz_aggregate_*需要aggregation;signoz_query_metrics需要一个来自signoz_list_metrics的metricName;signoz_get_trace_details需要traceId;signoz_get_service_top_operations需要一个来自signoz_list_services的service。先发现,再调用。 - 切勿声称根本原因:呈现数据模式和相关性。应写“checkout 的错误率在 14:05 从 0.2% 上升至 4.1%”,而不是“此次部署导致了错误。”
- 切勿在证据之外声称不存在:读取失败、超时或不完整,无法证明某项内容不存在。“无”“全部”和总数必须基于请求范围内的完整结果(步骤 5)。
- 每个问题只执行一个聚焦查询:一个精确查询就能回答问题时,不要发起多个零散查询。发现阶段可并行调用,但执行时务必精准。
- 遵守 MCP 服务规则:MCP 服务会对资源属性筛选器、筛选器运算符和冗余查询执行规则。请遵守这些规则,尤其是在筛选器中优先使用资源属性,以加快查询。
- 禁止使用原始 ClickHouse SQL:始终使用 Query Builder 工具。切勿构造原始 SQL。
- 范围边界:此技能用于查询数据。如果用户希望将查询封装为定期触发的告警,请引导至
signoz-creating-alerts。 - 在最终消息中输出
apply_filter。 当用户要求编写、构建、生成或展示查询时,需在最终助手消息中包含一个apply_filter操作,其中带有本轮成功调用signoz_execute_builder_query时传入的完整 v5query对象。该操作会携带完整的查询范围封装(schemaVersion: "v1"、start、end、requestType、compositeQuery),而不仅仅是内部的compositeQuery;必须逐字复制,不得重新构造。如果你通过简化工具(signoz_search_logs、signoz_search_traces、signoz_aggregate_*、signoz_query_metrics)回答,则使用较小的limit运行一次验证用的signoz_execute_builder_query,并复制其完整query对象,或者不输出该操作。使用适当的signal字段(metrics、logs或traces)。这会向 SigNoz UI 表明用户希望将查询应用到浏览器页面。只有当用户的主要意图是获取可运行的查询时,才输出apply_filter;如果用户询问的是一次性数据问题,且分析文本已作答,则不要输出。对于 Cost Meter 查询,保留signal: metrics,并确保复制的查询规范包含source: meter。
示例
用户:“显示过去一小时结账服务的错误率”
Agent:
-
调用
signoz_list_metrics(searchText: "calls", timeRange: "1h"),并 选择返回结果中精确匹配的请求计数指标。在此示例中,发现结果为signoz_calls_total,其metricType: "sum"、temporality: "cumulative",且isMonotonic: true。 -
调用
signoz_get_field_keys(signal: "metrics", metricName: "signoz_calls_total")以发现服务和错误标签,然后针对每个返回的name/fieldContext,使用相同的指标调用signoz_get_field_values, 确认checkout-service和STATUS_CODE_ERROR。此示例返回的名称是service.name和status_code;请使用实时发现返回的名称。 -
使用以下完整参数调用
signoz_query_metrics。主要参数定义查询 A;formulaQueries明确将查询 B 定义为使用不同的筛选条件,从而让分母包含所有 checkout 请求。两个筛选条件均原样使用步骤 2 返回的标签名称:{ "searchContext": "Show me the error rate for the checkout service in the last hour", "metricName": "signoz_calls_total", "metricType": "sum", "isMonotonic": true, "temporality": "cumulative", "timeAggregation": "increase", "spaceAggregation": "sum", "filter": "service.name = 'checkout-service' AND status_code = 'STATUS_CODE_ERROR'", "timeRange": "1h", "requestType": "scalar", "formula": "A / B * 100", "formulaQueries": [{ "name": "B", "metricName": "signoz_calls_total", "metricType": "sum", "isMonotonic": true, "temporality": "cumulative", "timeAggregation": "increase", "spaceAggregation": "sum", "filter": "service.name = 'checkout-service'" }] }将上述所有具体指标、元数据值、字段和字段值替换为租户发现结果;切勿假设此示例存在。
-
呈现:“checkout-service 的错误率:过去一小时为 2.3%(14:00– 15:00 UTC)。2,041 个请求中有 47 个错误。”
-
提供深入分析选项:“要我检查哪些操作的错误率最高吗?”
用户:“查找日志中的超时错误”
Agent:
- 调用
signoz_search_logs(searchText: "timeout", severity: "ERROR", timeRange: "1h")。 - 呈现:“过去一小时发现 23 个超时错误。其中大多数来自 payment-service(18 个)和 gateway(5 个)。常见模式:对下游 api 的 gRPC 调用中出现 ‘context deadline exceeded’。”
- 提供选项:“要我检查这些服务的跟踪数据,看看超时发生在哪里吗?”
用户:“购物车服务的 p99 延迟是多少?”
Agent:
- 调用
signoz_aggregate_traces(aggregation: "p99", aggregateOn: "duration_nano", service: "cart-service", requestType: "scalar", timeRange: "1h")。 - 呈现:“过去一小时 cart-service 的 p99 延迟为 1.2s。”
- 提供选项:“要我按操作细分,还是显示一段时间内的趋势?”
用户:“前端的错误是什么时候激增的?”
Agent:
- 调用
signoz_aggregate_traces(aggregation: "count", error: "true", service: "frontend", requestType: "time_series", timeRange: "6h")。 - 呈现:“过去 6 小时 frontend 的错误计数。11:30 UTC 出现峰值: 错误计数从约 5/min 跃升至约 45/min,并于 12:15 恢复至基线。”
- 提供选项:“要我检查峰值期间出现了哪些错误类型吗?”
用户:“每个服务摄取了多少日志数据?”
Agent:
- 按服务统计字节数 → 成本计量器。调用
signoz_list_metrics(searchText: "log", source: "meter"),并根据实时名称和单位选择返回的日志量指标。 - 使用外层
query包装器、schemaVersion: "v1"、整数 Unix 毫秒范围、requestType: "time_series"、formatOptions、variables,以及构建器规范调用signoz_execute_builder_query。规范使用signal: "metrics"、source: "meter"、发现的指标名称和时间聚合类型、stepInterval: 3600、原始的timeAggregation: "sum"、spaceAggregation: "sum",并使用signoz_get_field_keys返回的service.name字段,将其name、fieldDataType、fieldContext和signal复制到groupBy中。 - 排除
partial: true数据点,按服务汇总完整的每小时数据桶,并以发现的单位呈现 每个服务的摄取量。(如果计量器缺少所需属性,则回退为直接计数,并注明字节数只能通过计量器获取。)