在 Node.js OpenTelemetry 中过滤噪声 HTTP 端点
默认情况下,OpenTelemetry 会自动对所有进出的 HTTP 请求进行插桩。但像健康检查(/health)、就绪探针或指标(/metrics)这类端点会在链路追踪中产生大量噪音。对这些端点的一次请求会生成一整串 span:除了 HTTP span,还有每个 Express 中间件和请求处理器的若干 span。排除这些请求,能减少的 span 数量远比请求次数要多。
本指南将介绍如何通过配置 HttpInstrumentation 钩子过滤掉这些请求,让它们不再产生 span,以及如何削减另外两个常见的 span 来源:Express 中间件 span 和 net/dns 连接 span。
前提条件
- Node.js 18.0 或更高版本(参见官方的支持版本列表)
- 已安装并配置 OpenTelemetry SDK 的Node.js 应用
配置 HttpInstrumentation
HttpInstrumentation 类允许你定义一个 ignoreIncomingRequestHook。这个钩子是一个接收请求对象(req)的函数,如果返回 true,该请求就会被忽略,不会创建 span。
如果你使用的是零代码插桩方式,HTTP 端点无法通过环境变量来配置。你需要改为编程式插桩:按下文所示创建一个 instrumentation.js 文件,并用 node -r ./instrumentation.js app.js 加载。完整的配置步骤请参阅 Node.js OpenTelemetry Instrumentation。
如果你在使用 getNodeAutoInstrumentations,请把配置传给 @opentelemetry/instrumentation-http 这个键。getNodeAutoInstrumentations 辅助函数支持按名称配置具体的插桩项。
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。
如果使用 getNodeAutoInstrumentations,请将该选项传入 @opentelemetry/instrumentation-express 键。在 Express 5 中,还需禁用 @opentelemetry/instrumentation-router。因为 Express 5 通过 router 包处理请求,而该包的 instrumentation 会创建属于它自己的中间件和请求处理 span。
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 中传入该选项:
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。若不需要连接级别的详细数据,请同时禁用两者:
export OTEL_NODE_DISABLED_INSTRUMENTATIONS="net,dns"
若采用代码方式配置,请为 @opentelemetry/instrumentation-net 和 @opentelemetry/instrumentation-dns 传入 { enabled: false }。参见 Node.js Selective Auto-Instrumentation。
验证
- 使用新配置运行应用:
Copy
node -r ./instrumentation.js app.js - 对已排除的端点发起流量(例如
curl http://localhost:3000/health)。 - 对包含的端点发起流量(例如
curl http://localhost:3000/api/users)。 - 在 SigNoz 中打开 Traces 标签页。
- 确认你只能看到被包含端点的 trace。
- 如果你过滤了 Express middleware 或禁用了
net和dns,打开一个被包含端点的 trace,确认其中没有 per-middleware span,也没有tcp.connect、tls.connect或dns.lookupspan。

故障排查
在 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 联系我们。