mcpField
S
signoz-reducing-telemetry-cost

signoz-reducing-telemetry-cost

github.com/signoz云与 DevOps19168 次安装5 天前更新
代码仓库

关于 signoz-reducing-telemetry-cost

此 SigNoz 技能面向希望降低遥测成本的工程团队,指导使用 SigNoz MCP 工具分析指标、日志和追踪数据。流程包含成本归因、使用情况与基数检查,并要求保护基础设施和 APM 页面依赖的数据。

主要功能

  1. 01按信号分析遥测成本
  2. 02归因指标与日志用量
  3. 03检查指标使用情况和基数
  4. 04评估日志级别与过滤方案
  5. 05保护基础设施及 APM 依赖指标

适用场景

  1. 01调查指标、日志或追踪的成本来源
  2. 02识别可合并的高基数指标标签
  3. 03评估降低日志量的候选方案
  4. 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.json
references/
cost-meter-queries.md
infra-do-not-drop.md
otel-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 非空的分组总和。
    • 分组总量 = 所有分组的总和(包括空分组)。
    • 归因百分比 = 已归因 ÷ 分组总量。
  • 这是一个硬性分支:
    • ≥ 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:简洁明了,不加标题,分为两部分:

  1. 成本概况:指出主要驱动因素、占比,以及产生这些成本的原因 (注明服务、环境或指标)。如果多个因素共同占主导,分别列出各自占比 和合计影响。
  2. 按优先级排列的行动清单:按优先级列出所有可执行的发现,并在每项中注明状态: 可安全实施 / 需先检查一项内容(说明具体内容)/ 将导致仪表板失效(注明仪表板)/ 将导致告警覆盖失效(注明告警)/ 依赖基础设施页面(会影响 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-queries skill:用于本次调查所指向的临时后续查询。

评论

支持 Markdown