For the complete documentation index, see llms.txt. Markdown versions are available by appending .md to documentation URLs.

Filter Noisy HTTP Endpoints in Node.js OpenTelemetry

SigNoz Cloud - This page applies to SigNoz Cloud editions.
Self-Host - This page applies to self-hosted SigNoz editions.

By default, OpenTelemetry automatically instruments all incoming and outgoing HTTP requests. However, endpoints like health checks (/health), readiness probes, or metrics (/metrics) can generate a lot of noise in your traces. A single request to one of these endpoints produces a chain of spans: the HTTP span plus one or more spans for each Express middleware and request handler. Excluding those requests removes far more spans than the request count suggests.

This guide shows you how to filter out these requests by configuring the HttpInstrumentation hook so they don't produce spans, and how to drop two other common sources of span volume: Express middleware spans and net/dns connection spans.

Prerequisites

  • Node.js version 18.0 or higher (see official list of supported versions)
  • Instrumented Node.js app with OpenTelemetry SDK installed and configured

Configure HttpInstrumentation

The HttpInstrumentation class allows you to define an ignoreIncomingRequestHook. This hook is a function that receives the request object (req). If it returns true, the request is ignored and no span is created.

If you are using getNodeAutoInstrumentations, pass the configuration to the @opentelemetry/instrumentation-http key. The getNodeAutoInstrumentations helper allows you to configure specific instrumentations by name.

instrumentation.js
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { NodeSDK } = require('@opentelemetry/sdk-node');
// ... other imports
 
const sdk = new NodeSDK({
  // ... other config
  instrumentations: [
    getNodeAutoInstrumentations({
      '@opentelemetry/instrumentation-http': {
        ignoreIncomingRequestHook(req) {
            // Exclude common health check paths
            const excludedPaths = [
                /^\/health/, 
                /^\/ready/, 
                /^\/metrics/
            ];
            return excludedPaths.some(pattern => pattern.test(req.url));
        },
      },
    }),
  ],
});
 
sdk.start();

Filter Express middleware spans

The Express instrumentation creates one span per middleware in the chain (cors, jsonParser, helmet, logger, compression, and so on) on every request. Set ignoreLayersType to skip the middleware layer while keeping router and request handler spans.

If you use getNodeAutoInstrumentations, pass the option to the @opentelemetry/instrumentation-express key. On Express 5, also disable @opentelemetry/instrumentation-router. Express 5 routes requests through the router package, and that instrumentation creates its own middleware and request handler spans.

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();

Disable net and dns spans

The net instrumentation adds a tcp.connect span, plus a tls.connect span for HTTPS, to each new outbound connection. The dns instrumentation creates a dns.lookup span each time dns.lookup or dns/promises.lookup runs. It patches these functions only after your application or a library loads the dns module, so outbound HTTP calls alone may not produce these spans. Disable both when you don't need connection-level detail:

export OTEL_NODE_DISABLED_INSTRUMENTATIONS="net,dns"

For a code-based setup, pass { enabled: false } for @opentelemetry/instrumentation-net and @opentelemetry/instrumentation-dns. See Node.js Selective Auto-Instrumentation.

Validate

  1. Run your application with the new configuration:
    node -r ./instrumentation.js app.js
  2. Generate traffic to the excluded endpoints (e.g., curl http://localhost:3000/health).
  3. Generate traffic to included endpoints (e.g., curl http://localhost:3000/api/users).
  4. Go to the Traces tab in SigNoz.
  5. Verify that you only see traces for the included endpoints.
  6. If you filtered Express middleware or disabled net and dns, open a trace for an included endpoint. Make sure that it has no per-middleware spans and no tcp.connect, tls.connect, or dns.lookup spans.
Sample trace output showing HTTP endpoints except health checks
Sample traces after excluding health checks

Troubleshooting

Still not seeing data in SigNoz? Work through Debug missing traces, logs, and metrics, which covers SDK diagnostics, Collector connectivity, and the common ingestion errors for all three signals.

Still seeing traces for excluded endpoints?

  • Check Regex/Conditions: req.url includes the path and query string (e.g., /health?id=1). Avoid using strict equality (===) for partial matches; use .startsWith() or regex instead. Log req.url to debug.
  • Instrumentation Order: If using manual instrumentation, ensure HttpInstrumentation is initialized and passed to the SDK.
  • Multiple Instrumentations: If you use both auto-instrumentations and manual instances, they might conflict. Prefer one method.

Enable debug logging

Set OTEL_LOG_LEVEL=debug to see if the instrumentation is initialized and if spans are being created/dropped.

Next Steps

Get Help

If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack. If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.

Is this page helpful

Last updated—October 19, 2026

Edit on GitHub