← 文章 / 编程开发
signoz 11天前 · 2026-10-25 02:32:31 · 9 阅读

在 Node.js OpenTelemetry 中过滤噪声 HTTP 端点

默认情况下,OpenTelemetry 会自动对所有进出的 HTTP 请求进行插桩。但像健康检查(/health)、就绪探针或指标(/metrics)这类端点会在链路追踪中产生大量噪音。对这些端点的一次请求会生成一整串 span:除了 HTTP span,还有每个 Express 中间件和请求处理器的若干 span。排除这些请求,能减少的 span 数量远比请求次数要多。

本指南将介绍如何通过配置 HttpInstrumentation 钩子过滤掉这些请求,让它们不再产生 span,以及如何削减另外两个常见的 span 来源:Express 中间件 span 和 net/dns 连接 span。

前提条件

配置 HttpInstrumentation

HttpInstrumentation 类允许你定义一个 ignoreIncomingRequestHook。这个钩子是一个接收请求对象(req)的函数,如果返回 true,该请求就会被忽略,不会创建 span。

使用自动插桩 SDK手动插桩警告

如果你使用的是零代码插桩方式,HTTP 端点无法通过环境变量来配置。你需要改为编程式插桩:按下文所示创建一个 instrumentation.js 文件,并用 node -r ./instrumentation.js app.js 加载。完整的配置步骤请参阅 Node.js OpenTelemetry Instrumentation。

如果你在使用 getNodeAutoInstrumentations,请把配置传给 @opentelemetry/instrumentation-http 这个键。getNodeAutoInstrumentations 辅助函数支持按名称配置具体的插桩项。

instrumentation.js ```pre>const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { NodeSDK } = require('@opentelemetry/sdk-node'); // ... 其他导入 const sdk = new NodeSDK({ // ... 其他配置 instrumentations: [ getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-http': { ignoreIncomingRequestHook(req) { // 排除常见的健康检查路径 const excludedPaths = [ /^\/health/, /^\/ready/, /^\/metrics/ ]; return excludedPaths.some(pattern => pattern.test(req.url)); }, }, }), ], }); sdk.start(); 如果你需要手动添加 instrumentation,请直接实例化并配置 HttpInstrumentation 类: instrumentation.js ```pre>const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http'); const { NodeSDK } = require('@opentelemetry/sdk-node'); const httpInstrumentation = new HttpInstrumentation({ ignoreIncomingRequestHook(req) { return req.url.startsWith('/health') || req.url.startsWith('/api/static'); }, }); const sdk = new NodeSDK({ instrumentations: [ httpInstrumentation, // ... 其他 instrumentation ], }); sdk.start();

过滤 Express 中间件 span

Express instrumentation 会为请求链中的每个中间件(cors、jsonParser、helmet、logger、compression 等)各创建一个 span。设置 ignoreLayersType 可以跳过中间件层,同时保留路由和请求处理器的 span。

使用自动 instrumentation SDK 手动 instrumentation

如果使用 getNodeAutoInstrumentations,请将该选项传入 @opentelemetry/instrumentation-express 键。在 Express 5 中,还需禁用 @opentelemetry/instrumentation-router。因为 Express 5 通过 router 包处理请求,而该包的 instrumentation 会创建属于它自己的中间件和请求处理 span。

instrumentation.js
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { NodeSDK } = require('@opentelemetry/sdk-node');
 
const sdk = new NodeSDK({
  // ... other config
  instrumentations: [
    getNodeAutoInstrumentations({
      '@opentelemetry/instrumentation-express': {
        ignoreLayersType: ['middleware'],
      },
      // Express 5 only
      '@opentelemetry/instrumentation-router': { enabled: false },
    }),
  ],
});
 
sdk.start();

若手动添加 instrumentation,请在 ExpressInstrumentation 中传入该选项:

instrumentation.js
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
const { NodeSDK } = require('@opentelemetry/sdk-node');
 
const sdk = new NodeSDK({
  // ... other config
  instrumentations: [
    new HttpInstrumentation(),
    new ExpressInstrumentation({ ignoreLayersType: ['middleware'] }),
  ],
});
 
sdk.start();

禁用 net 和 dns span

net instrumentation 会为每个新建的出站连接添加 tcp.connect span,HTTPS 场景下还会增加 tls.connect span。dns instrumentation 则在每次执行 dns.lookup 或 dns/promises.lookup 时创建 dns.lookup span。它仅在应用或库加载 dns 模块之后才修补这些函数,因此单纯的出站 HTTP 请求可能不会生成这些 span。若不需要连接级别的详细数据,请同时禁用两者:

Copy
export OTEL_NODE_DISABLED_INSTRUMENTATIONS="net,dns"

若采用代码方式配置,请为 @opentelemetry/instrumentation-net 和 @opentelemetry/instrumentation-dns 传入 { enabled: false }。参见 Node.js Selective Auto-Instrumentation。

验证

  1. 使用新配置运行应用: Copy
    node -r ./instrumentation.js app.js
  2. 对已排除的端点发起流量(例如 curl http://localhost:3000/health)。
  3. 对包含的端点发起流量(例如 curl http://localhost:3000/api/users)。
  4. 在 SigNoz 中打开 Traces 标签页。
  5. 确认你只能看到被包含端点的 trace。
  6. 如果你过滤了 Express middleware 或禁用了 net 和 dns,打开一个被包含端点的 trace,确认其中没有 per-middleware span,也没有 tcp.connect、tls.connect 或 dns.lookup span。
排除健康检查后的 trace 输出示例
排除健康检查后的 trace 示例

故障排查

在 SigNoz 中仍然看不到数据?请参阅调试缺失的 trace、日志和指标,其中涵盖了 SDK 诊断、Collector 连接问题,以及三类信号常见的接入错误。

被排除的端点仍然产生 trace?

  • 检查正则/条件:req.url 包含路径和查询字符串(如 /health?id=1)。做部分匹配时不要用严格相等(===),应改用 .startsWith() 或正则。可以打印 req.url 来调试。
  • 插桩顺序:如果使用手动插桩,确保 HttpInstrumentation 已初始化并传给了 SDK。
  • 多重插桩:同时使用自动插桩和手动实例可能产生冲突,建议只用其中一种方式。

开启调试日志

设置 OTEL_LOG_LEVEL=debug,可以查看插桩是否已初始化、span 是否被创建或丢弃。

下一步

获取帮助

如需本教程相关操作帮助,请加入 SigNoz 社区 Slack。若你是 SigNoz Cloud 用户,可使用 SigNoz 实例右下角的产品内聊天客服,或发送邮件至 cloud-support@signoz.io 联系我们。

原始来源: signoz

评论 (0)