关于 signoz-reducing-telemetry-cost
此 SigNoz 技能面向希望降低遥测成本的工程团队,指导使用 SigNoz MCP 工具分析指标、日志和追踪数据。流程包含成本归因、使用情况与基数检查,并要求保护基础设施和 APM 页面依赖的数据。
主要功能
- 01按信号分析遥测成本
- 02归因指标与日志用量
- 03检查指标使用情况和基数
- 04评估日志级别与过滤方案
- 05保护基础设施及 APM 依赖指标
适用场景
- 01调查指标、日志或追踪的成本来源
- 02识别可合并的高基数指标标签
- 03评估降低日志量的候选方案
- 04避免删除支撑基础设施页面的指标
MCP 相关
该技能依赖 SigNoz MCP 服务提供的工具来查询成本、指标、日志、追踪和告警信息。运行前需确认相关工具可用;未配置时应先运行 signoz-mcp-setup。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ signoz/ agent-skills --skill signoz-reducing-telemetry-cost安装后在 Claude Code 中输入/signoz-reducing-telemetry-cost确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonreferences/cost-meter-queries.mdinfra-do-not-drop.mdotel-attribute-cardinality.md详细介绍
前置条件
此技能会大量调用 SigNoz MCP 服务工具(signoz_list_metrics、
signoz_get_field_keys、signoz_execute_builder_query、
signoz_get_top_metrics、signoz_check_metric_usage、signoz_check_metric_cardinality、
signoz_aggregate_logs、signoz_aggregate_traces、signoz_search_logs、
signoz_list_alert_rules、signoz_get_alert、signoz_get_service_top_operations)。运行工作流前,请确认 signoz_* 工具可用。如果不可用,则表示 SigNoz
MCP 服务尚未安装或配置;请先运行 signoz-mcp-setup。整个调查都以这些查询为依据;没有该服务,就无从分析。
得出结论前,请先阅读这两个参考文件:
references/otel-attribute-cardinality.md:对遇到的任何指标标签进行分类。references/infra-do-not-drop.md:为内置 Infrastructure 页面以及 APM/Services 页面提供支持的指标(基于 Span 的signoz_*RED 指标);即使使用情况显示这些指标未被使用,也绝不可将它们列为“可安全删除”。
工作流
始终从 Cost Meter 快照开始(步骤 1)。进行完整成本调查时,对每种有数据的信号都执行指标、日志和追踪步骤,并按当前成本贡献从高到低排序(主要、次要、第三)。最后完成报告(步骤 5)。
步骤 1:Cost Meter 快照
首先了解跨信号的成本情况。始终以 source: "meter" 调用 signoz_list_metrics;将其返回的指标名称、类型、时间属性和单位视为实时事实来源,因为 Meter 集合会不断变化。然后,对发现的每个相关指标调用 signoz_execute_builder_query 查询(source: "meter"、requestType: "time_series"、
stepInterval: 3600、使用发现的 temporality,以及 timeAggregation: "sum");完整的工具参数模板请参阅 references/cost-meter-queries.md。对完整的小时区间求和,并排除所有标记为 partial: true 的数据点。不要使用
signoz_query_metrics 计算 Cost Meter 总量或分组总量归因。
只报告成功查询返回的值。如果查询失败,或 MCP 工具可用后仍未返回可用值,请展示预期查询,并说明无法计算总量;绝不可编造总量。如果工具不可用,请遵循前置条件中的指引。
对于滚动 7 天时间窗口(end = 现在,start = end − 7 天),获取每种信号的总量
(Span 大小、日志大小、指标数据点),然后计算并报告:
- 主要成本驱动因素。 美元成本权重最高的信号:追踪/日志为 $0.30/GB,指标为 $0.10/M 个样本(仅供参考;绝不可引用美元节省额)。这依据成本而非原始数据量进行判断。
- 每条记录的字节数。 span.size ÷ span.count 和 log.size ÷ log.count,用于判断问题出在信号载荷大小还是数据量。
然后按环境和服务细分主要信号。首先以 signal: "metrics" 和 source: "meter" 调用 signoz_get_field_keys;只使用其返回的键,并将每个键的 name、fieldDataType、fieldContext 和 signal 原样复制到原始查询的 groupBy 中,不要翻译或省略字段。对完整的 groupBy 运行相同的 Meter 查询,并报告每组排名前
约 10 项及其占比。如果非生产环境(staging、dev、test、qa、
sandbox、preview、uat 等)的数据量超过 40%,则在进行任何信号级变更前,建议先对该键启用 Ingestion Limits:https://signoz.io/docs/ingestion/signoz-cloud/keys/
步骤 2:指标
当 Cost Meter 显示存在指标数据时,按其成本贡献顺序运行;或者用户明确询问指标成本或基数时运行。
2a. 使用 signoz_get_top_metrics 按数据量排序。 返回摄入样本数排名前 100 的指标,包含预先计算好的百分比和样本数 totalValue(传入 start/end)。这是按数据量排序的待处理列表。直方图指标(后缀为 .bucket)通常是主要贡献者,因为每个抓取周期都会为每个桶边界生成一个独立样本。
2b. 使用 signoz_check_metric_usage 检查用量。 传入排名靠前的指标名称(每次调用最多 50 个)。此工具会为每个指标返回 { dashboards, alerts, error }。只有当 error 为空,且 dashboards 和 alerts 均为空时,该指标才是可删除候选项。如果 error 非空,则查询不完整(可能是超时,或使用的是缺少此端点的旧版 SigNoz),返回的列表不可靠,因此绝不要将该指标视为未使用;应标记为先检查一次(手动确认其用量)。如果查询正常,且两个列表均为空,则该指标是可删除候选项,但以下保护规则除外。
禁止删除保护规则(强制)。 在将任何用量为空的指标称为“可安全删除”之前,先检查
references/infra-do-not-drop.md。Infrastructure 页面(Hosts / Kubernetes)通过内置查询使用system.*以及许多k8s.*/container.*指标,而非仪表盘,因此用量检查会将这些指标报告为空,但删除它们会导致该页面无法正常工作。如果某个候选指标属于禁止删除集合,应将其标记为**“Infrastructure 页面依赖项:删除会导致 Hosts/Kubernetes 视图无法正常工作;删除前请确认你不使用该视图,”**绝不要称其为“可安全删除”。这条规则优先于用量为空的结果。此外,排除内部signoz_/signoz.指标(为 APM 页面提供支持的自动生成 RED 指标,不受客户控制)。
2c. 使用 signoz_check_metric_cardinality 检查基数。 对非可删除候选指标,以及用户选择保留的可删除候选指标运行此工具。对用户已同意删除的指标进行基数分析没有价值。此工具会按基数从高到低返回属性键,每个键包含 valueCount 和样本 values。根据 references/otel-attribute-cardinality.md 对其进行分类:
- 无界(
url.full、http.target、db.query.text、client.port、trace.id、exception.stacktrace等):会持续增长,没有上限;无论当前计数是多少,都应标记。 - 累积型(
container.id、k8s.pod.uid、k8s.pod.name、k8s.pod.start_time):valueCount反映的是历史 Pod 更替情况,而非活跃序列数;请解释这一区别。 - 高基数但有界(
valueCount≳ 100):建议聚合前,检查仪表盘/告警是否实际使用该标签进行筛选。
基础设施实体标识覆盖规则(强制)。 对于受
references/infra-do-not-drop.md保护的指标,应保留该指标的 Infra 实体/视图所使用的身份属性和页面元数据。若实体 UID/名称属性用于确定该实体,则不得聚合或移除这些属性。Pod 指标应保留k8s.pod.start_time,因为 Pods 页面会用它显示 Pod Age。此规则优先于基数参考文档中的通用累积型处理方法。
要降低基数,请使用 metricstransform 处理器的 aggregate_labels 操作来合并序列(样本才是计费成本,因此只有合并才能真正降低成本),不要使用 transform 处理器的 delete_key;它不会减少样本数,还会产生冲突的序列。如果某个标签对指标的身份至关重要,请删除整个指标,或在 SDK 中修正。对于直方图,减少桶边界可以减少样本,同时对 P99 的影响很小。文档:
https://signoz.io/docs/userguide/drop-metrics/ ·
https://signoz.io/docs/metrics-management/dropping-metric-labels/
2d. 检查采集间隔。 对于必须保留的高容量指标,建议更改前先确定其生成方式和当前间隔。延长间隔可以减少摄取的数据点,但也会降低时间分辨率,因此应保留仪表板和告警所需的分辨率。使用来源本身的控制项:对于 Collector 生成的指标,使用接收器的 collection_interval;对于 Prometheus 抓取的指标,使用抓取间隔;对于 SDK 推送的指标,如果 SDK 支持,则使用 OTEL_METRIC_EXPORT_INTERVAL。绝不要建议在 delta 和 cumulative 暂时性之间切换指标;更改同一指标的暂时性可能会破坏 SigNoz 查询。
第 3 步:日志
当 Cost Meter 显示有日志数据时,按成本贡献排序后运行;或者在用户明确询问日志成本时运行。
3a. 总量和归因决定处理路径。
- 日志总 GB 数(绝对成本数值):使用
signoz_execute_builder_query,查询已发现的计量指标;该指标的实时单位和含义必须代表日志字节数,并按第 1 步所述求和。 - 归因:运行相同的计量查询,并按
service.name分组。这会返回每个服务对应的分组,以及一个用于归因缺失日志的未设置/空service.name分组。完全基于此分组结果计算比率,以确保分子和分母依据相同;分组求和可能与未分组的总量不同,因此绝不要用已归因分组的总和除以未分组总量:- 已归因 GB 数 =
service.name非空的分组总和。 - 分组总量 = 所有分组的总和(包括空分组)。
- 归因百分比 = 已归因 ÷ 分组总量。
- 已归因 GB 数 =
- 这是一个硬性分支:
- ≥ 10% → 路径 A(服务模式)。
- < 10% → 路径 B(命名空间模式)。 日志来自基础设施转发器(Fluent Bit / Fluentd / Vector),而不是 OTel SDK,因此不会设置
service.name。路径 B 不太常见,因此要检查其数值是否合理。
3b. 分析选定的归因路径,并找出可选的修复方案。 此步骤中的修复方案仅为候选方案。在建议任何减少日志量的措施(包括更改源日志级别)之前,请先完成第 3c 步中的告警检查。
路径 A,服务模式(≥ 10%)。 使用 signoz_aggregate_logs 获取严重级别分布,设置 aggregation: count、groupBy: "service.name,severity_text"。对严重级别分类:可减少 = INFO、INFORMATION、DEBUG、TRACE、VERBOSE;高信号 = ERROR、FATAL、CRITICAL、WARN、WARNING。对于按 GB 数排名靠前的每个服务:
- 可减少级别占主导 + 自有服务代码 → 候选方案:设置
LOG_LEVEL=WARN(在源头停止生成日志)。 - 可减少级别占主导 + 第三方库 → 候选方案:使用 Collector 按
instrumentation_scope.name过滤(从signoz_search_logs样本的scope_name中读取范围名称)。 - 无法访问源代码 → 候选方案:使用 Collector 按
severity_text过滤,仅匹配可减少的级别(INFO/DEBUG/TRACE),绝不要使用也会匹配 WARN 及以上级别的范围。 - 高信号级别占主导(WARN/ERROR > 50%)→ 值得保留这些日志;较高的错误率可能是真实问题,因此应单独标记,不要建议将其过滤掉。
服务严重级别保护规则。 上述候选修复方案(
LOG_LEVEL=WARN,或仅针对 INFO/DEBUG 的 Collector 过滤器)按设计会保留 WARN 及以上级别,因此严重级别分布不会阻止这些方案;不过,第 3c 步仍会决定告警是否依赖这些记录。此保护规则仅适用于还会丢弃高信号日志的操作:无差别丢弃某个服务的所有日志,或范围包含 WARN/ERROR/FATAL/CRITICAL 的severity_text过滤器。在建议其中一种操作前,计算高信号百分比 = (所有高信号严重级别的匹配数,包括 ERROR、FATAL、CRITICAL、WARN 和 WARNING,匹配时不区分大小写)÷ 服务总数。如果结果 > 1%(或绝对数量不可忽略),不要执行无差别操作:将减少范围限制在 INFO/DEBUG,并把错误标记为真实信号。 路径 B,命名空间模式(< 10%)。
- 顶级命名空间:
signoz_aggregate_logs、count、groupBy: "k8s.namespace.name,deployment.environment",按 count 降序排序,限制约为 10。使用 24h 窗口(大型租户的 7 天命名空间扫描会超时;由于 Cost Meter 没有命名空间维度,因此以 count 作为代理指标)。 - 每个命名空间的严重程度:
signoz_aggregate_logs、count、groupBy: "k8s.namespace.name,severity_text"。 - 样本:
signoz_search_logs、filter: "k8s.namespace.name = '<ns>'"、较小的 limit;读取body、severity_text、scope_name。
命名空间严重程度保护规则。 高信号占比 =(所有高信号严重程度,包括 ERROR、FATAL、 CRITICAL、WARN、以及 WARNING,不区分大小写匹配)÷ 命名空间 总量。如果占比 > 1%(或绝对数量并非可忽略),不要考虑丢弃或 过滤整个命名空间。 将过滤范围限定为具体的噪声模式(日志 类别、
severity_text匹配项或组件)。绝不要丢弃包含活跃错误的命名空间。只有基本上全是 INFO/DEBUG 的命名空间才适合整体过滤, 且须遵循步骤 3c。
- 样本中的
severity_text为空 → 转发器发送的是未经解析的原始行;修复方法是在 OTel Collector 日志管道中添加 json/regex 解析器(没有解析器就无法按严重程度过滤)。 k8s.event.*日志通常量大、价值低 → 如果没有针对它们设置告警,则可以丢弃。
3c. 日志告警:提出任何日志缩减建议前都要检查。 signoz_list_alert_rules,
逐页检查所有页面(持续跟进 pagination.nextOffset,直到 pagination.hasMore 为
false;不要停在第一页,否则会漏掉后续页面上的告警,导致过滤看似安全,实则不然)。保留
alertType == "LOGS_BASED_ALERT"。对每条告警,调用 signoz_get_alert(id) 并读取
condition.compositeQuery.queries[].spec.filter.expression + groupBy,查看它保护的是哪个服务 /
严重程度 / 命名空间。如果某项过滤会导致告警失效,请标记为 将破坏告警覆盖范围,并注明告警名称。文档:https://signoz.io/docs/logs-management/guides/drop-logs/
第 4 步:Trace
当 Cost Meter 显示 span 数据并按成本贡献排序时运行,或用户明确询问 span 成本时运行。
4a. 全局操作名称视图,先读取此视图。 signoz_aggregate_traces,
aggregation: count,groupBy: "name",orderBy: "count() desc",限制为 20,不添加服务筛选条件。这会一次性显示所有服务中的自动埋点噪声(健康检查、SQL、缓存、sidecar)。
4b. 各服务的成本 + 各服务的操作。 按服务统计 Span GB:使用
signoz_execute_builder_query,指定已发现的 meter 指标,其实时单位和含义表示 span 字节数;按第 1 步所述求和,并按
signoz_get_field_keys 返回的 service.name 字段分组(照抄其 name、fieldDataType、fieldContext 和 signal)。
计算每个服务占比时,分母应为分组总计(此查询中所有服务分组的总和),而不是前 N 名的总和,也不是单独获取的未分组总计;分子和分母必须基于同一分组口径。对于 GB 排名前 3 的每个服务,使用 signoz_get_service_top_operations(或通过 service: "<svc>" + groupBy: "name" 调用 signoz_aggregate_traces)获取其主要操作。为简洁起见,操作明细只列出前 3 名,但错误率检查(4c)和下方的 APM 保护要求适用于你考虑降低开销的每一个服务。
4c. 各服务的错误率。 调用 signoz_aggregate_traces,使用 count、groupBy: "service.name" 获取总数;然后再次调用,并设置 error: true。错误率 = 错误数 ÷ 总数,按服务计算。
4d. Trace 告警。 signoz_list_alert_rules,翻阅所有分页(持续跟进 pagination.nextOffset,直到 pagination.hasMore 为 false)。仅保留 alertType == "TRACES_BASED_ALERT";调用 signoz_get_alert(id) 查看每条告警的保护对象。
分类主要操作。
- 常见噪声候选项:健康检查/存活探测(
/health、/ping、/ready、grpc.health.v1.Health/Check);代理/sidecar(envoy.*、istio.*、linkerd.*)。将它们视为候选项,而非自动认定可以安全移除;仍须遵守下方的 APM 保护要求。 - 下结论前先调查,不要凭假设判断:SQL 片段(具体库取决于语言:Java → JDBC,Python → SQLAlchemy,Node → pg/mysql2/sequelize,.NET → EF/Dapper);缓存命令(HMGET/GET/SET… → ioredis、redis-py、Jedis、go-redis…);不熟悉的 gRPC 方法。先搜索;若搜索后仍无法识别,请说明这一点。
修复层。 对于已确认的噪声操作,优先使用已部署 SDK 或埋点库文档中提供的禁用/排除控制项,让数据在源头停止生成。命名具体设置前,先识别语言和库;Java、Python、Node.js 和 .NET 使用的控制项各不相同。如果 SDK 没有相应控制项,则使用 Collector 按操作名称过滤。
Span → APM 保护(强制)。 切勿建议或配置头部采样、概率采样、尾部采样或任何其他 Trace 采样来降低成本。当用户询问采样时,须说明其两方面影响:内置的 APM/Services 指标只涵盖保留的 Trace,因此绝对请求数和速率会低于实际流量;延迟趋势和错误峰值可能仍有参考价值,但 APM 页面将不再代表所有请求。这种有限的参考价值并不意味着允许将采样作为降本手段,处理器的放置位置也不构成例外。
对已确认的噪声使用 SDK 排除项和 Collector 过滤器。在提供配置前,说明被移除的操作将从 APM 中消失。 文档:https://signoz.io/docs/traces-management/guides/drop-spans/
步骤 5:汇报发现
先给出 TL;DR:简洁明了,不加标题,分为两部分:
- 成本概况:指出主要驱动因素、占比,以及产生这些成本的原因 (注明服务、环境或指标)。如果多个因素共同占主导,分别列出各自占比 和合计影响。
- 按优先级排列的行动清单:按优先级列出所有可执行的发现,并在每项中注明状态: 可安全实施 / 需先检查一项内容(说明具体内容)/ 将导致仪表板失效(注明仪表板)/ 将导致告警覆盖失效(注明告警)/ 依赖基础设施页面(会影响 Hosts/K8s 视图)。对于指标量下降,注明 体量百分比,让读者了解成本影响。
TL;DR 之后,只补充此前未提及的证据或背景信息。按照步骤 2–4 中的决策顺序排列行动, 但每项发现及其防护措施只说明一次,不要重复行动清单或按信号分类的操作指南。
保持对话式表达:使用按优先级排列的分流清单,不要写成带标题和表格的格式化报告。将 Cost Meter 数据涵盖的每个信号都纳入这份清单;不要询问是否要检查工作流已分析过的信号。
防护措施
- 检查不完整时,绝不能将下降或过滤判定为“安全”。 必须完整翻页检查
signoz_list_alert_rules(直到pagination.hasMore为 false),再判断是否影响告警; 如果signoz_check_metric_usage返回非空的error,则用量状态应视为未知 (需要人工检查),而不是“未使用”。查询不完整不代表可以放行。 - 体量数据必须来自已发现的 Cost Meter 指标及其实际单位:Span/日志体量使用字节, 指标体量使用样本数。绝不能用 Span/日志记录数表示体量。
- 成本总额和分组总额归因必须使用
signoz_execute_builder_query,设置原始的timeAggregation: sum、每小时的stepInterval: 3600,并仅使用完整的数据点; 绝不能使用signoz_query_metrics。 - 通过原始查询通道发送的每个 Cost Meter
builder_query都必须包含limit: 100和 Query Builder v5 的order: [{key:{name:"__result"}, direction:"desc"}]。这是传输字段order,不是仪表板字段orderBy;分组查询中 必须保留该字段。limit会按整个时间窗口对分组排序,因此要指出短时存在的分组 可能未进入前 N 名。 - 绝不能将基础设施页面或 APM 指标描述为可安全丢弃(参见
references/infra-do-not-drop.md),即使用量检查显示没有仪表板或告警也不例外。 - 日志:绝不能建议丢弃/过滤承载活跃 ERROR/WARN 的整个服务或命名空间
(高信号日志占比 > 1%,或绝对数量不可忽略)。应将过滤范围限定为噪声模式。
修复顺序:从源头修复(
LOG_LEVEL=WARN)→ Collector 范围过滤 (instrumentation_scope.name)→severity_text过滤。 - 日志归因采用硬性阈值:≥ 10% → 路径 A;< 10% → 路径 B。请计算归因比例。
- Trace:绝不能建议或配置头部采样、概率采样、尾部采样或任何其他采样方式。 采样会使内置的 APM/Services 指标仅统计保留的 Trace,因此绝对请求数和速率将不再 代表全部流量。
- UNBOUNDED 和 IDENTIFIER 标签始终值得指出:问题在于增长趋势,而不只是当前数量。
- 绝不能建议更改保留期限。绝不能估算美元节省金额。 绝不能将仪表板或告警称为 未使用/噪声过多/冗余;只报告数量。
- 所有结论都必须以查询结果为依据。 如果某个信号没有 Cost Meter 数据,请明确说明; 不要用基于数量的替代指标。不要重复列出明细中已显示的指标;体量约为前 20 名之外的 指标,其单项影响可以忽略不计。
其他资源
references/cost-meter-queries.md:Cost Meter 的发现过程、完整的signoz_execute_builder_query模板、单位换算,以及分组与未分组的注意事项。references/infra-do-not-drop.md:内置 Infrastructure 和 APM/Services 页面背后的指标,绝不能建议丢弃这些指标。references/otel-attribute-cardinality.md:用于对指标标签进行分类的参考资料 (UNBOUNDED / ACCUMULATING / BOUNDED / IDENTIFIER)。signoz-generating-queriesskill:用于本次调查所指向的临时后续查询。