Back to Blog
When Your Distributed System Needs a Single Pane of Glass: Embracing OpenTelemetry with SigNoz
7 min readSep 9, 20263 views

When Your Distributed System Needs a Single Pane of Glass: Embracing OpenTelemetry with SigNoz

Building distributed systems is hard enough. Knowing what's actually going on when things break can feel impossible, especially when you're juggling multiple tools for logs, metrics, and traces. OpenTelemetry offers a standardized way to instrument everything, but you still need a backend. SigNoz pr

ObservabilityDistributed SystemsToolingFull-StackBackend
Share

by Sunil Band

The Observability Headache in Distributed Systems

We've all been there: a user reports an issue, and your logs are scattered across half a dozen services, each with its own format. Metrics are in a different dashboard, and if you even have distributed tracing, it's often a proprietary vendor lock-in that makes you cringe. Pinpointing the root cause in a modern microservices architecture becomes a detective novel where all the clues are written in different languages.

This isn't just an inconvenience; it's a fundamental blocker to rapid incident response and proactive system health management. You need to see the full picture, from the user's browser to your database, without context-switching between five different tabs and trying to mentally stitch together requestId across disparate systems. That's where observability comes in, and specifically, why OpenTelemetry (OTel) has become so critical.

OTel isn't just another library; it's a vendor-agnostic set of APIs, SDKs, and tools designed to standardize the generation and collection of telemetry data (metrics, logs, and traces). It means you instrument your code once, and you can send that data to any OTel-compatible backend. This is a game-changer for avoiding vendor lock-in and future-proofing your observability strategy.

But OTel only solves the instrumentation problem. You still need somewhere to send, store, analyze, and visualize that data. That's where open-source platforms like SigNoz shine. SigNoz positions itself as an OpenTelemetry-native solution, giving you a full-stack observability platform that understands OTel data out of the box, offering APM, distributed tracing, metrics, and log management all in one place.

Why OpenTelemetry Native Matters

Many existing observability platforms have retrofitted OTel support. They treat OTel data as just another input. SigNoz, however, is OpenTelemetry native. This isn't just marketing fluff; it means its internal data model, storage, and querying capabilities are optimized for the structured, correlated data that OTel produces. When you send a trace, SigNoz understands its spans, attributes, and relationships inherently, making it easier to visualize and query complex distributed transactions.

This native integration simplifies your life significantly. You don't need to worry about complex data transformations or ensuring your OTel collector is configured just right to translate to a proprietary format. You instrument with OTel, point your collector at SigNoz, and it just works. This reduces configuration overhead, potential errors, and the cognitive load on your engineering team.

Getting Started with SigNoz

Setting up SigNoz is surprisingly straightforward, especially if you're comfortable with Docker or Kubernetes. They provide a simple docker-compose setup for local development or smaller deployments. Let's walk through a quick example to see how you might instrument a simple Node.js application and send data to SigNoz.

First, you need to get SigNoz running. The easiest way is with their install script:

bash
curl -sSL https://signoz.io/install.sh | sh

This will set up SigNoz using Docker Compose. Once it's up, you can access the UI typically at http://localhost:3301.

Now, let's instrument a basic Express application. We'll add OTel tracing to see how requests flow through our service. You'll need to install a few OpenTelemetry packages:

bash
npm install @opentelemetry/sdk-node @opentelemetry/api @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-otlp-proto-http @opentelemetry/sdk-trace-base @opentelemetry/sdk-metrics

Next, create an instrumentation.js file to configure OpenTelemetry. This file will initialize the OTel SDK and set up our OTLP exporter to send data to SigNoz.

javascript
// instrumentation.js
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-otlp-proto-http');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-otlp-proto-http');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

// Configure the OTLP exporter to send traces and metrics to SigNoz's OTLP endpoint
// By default, SigNoz OTLP HTTP receiver is at /v1/traces and /v1/metrics
const exporterOptions = {
  url: 'http://localhost:4318/v1/traces', // SigNoz OTLP trace receiver URL
  metricsUrl: 'http://localhost:4318/v1/metrics', // SigNoz OTLP metric receiver URL
};

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter(exporterOptions),
  metricReader: new PeriodicExportingMetricReader({
    exporter: new OTLPMetricExporter(exporterOptions),
    interval: 5000, // Export metrics every 5 seconds
  }),
  instrumentations: [getNodeAutoInstrumentations()], // Auto-instrument popular Node.js libraries
  serviceName: 'my-node-app', // Set a service name for better identification in SigNoz
});

sdk.start();
console.log('OpenTelemetry SDK initialized');

// It's good practice to gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
  sdk.shutdown()
    .then(() => console.log('OpenTelemetry SDK shut down successfully'))
    .catch((error) => console.log('Error shutting down OpenTelemetry SDK', error))
    .finally(() => process.exit(0));
});

To ensure our application loads this instrumentation file before anything else, we'll use the NODE_OPTIONS environment variable. Modify your package.json scripts or run your app like this:

json
// package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "start": "NODE_OPTIONS='-r ./instrumentation.js' node app.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

Finally, a simple app.js using Express:

javascript
// app.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  console.log('Request received for /');
  res.send('Hello from OpenTelemetry Instrumented Node.js App!');
});

app.get('/slow', (req, res) => {
  console.log('Request received for /slow');
  // Simulate some work
  setTimeout(() => {
    res.send('This was a slow response!');
  }, Math.random() * 500 + 500); // 500ms to 1s delay
});

app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});

Run your application with npm start and hit http://localhost:3000 and http://localhost:3000/slow a few times. Then, head over to your SigNoz UI. You should start seeing traces and metrics appear for your Node.js application.

In the SigNoz UI, navigate to the 'Traces' tab. You'll see a list of requests, and clicking on one will reveal a flame graph or Gantt chart visualization of the entire request lifecycle. You'll see spans for the Express request, any middleware, and the setTimeout simulation in the /slow endpoint, all correlated. This is the power of distributed tracing: understanding the latency contribution of each service and component.

Beyond Traces: Metrics and Logs

While this example focuses on traces, OpenTelemetry also provides robust APIs for metrics and logs. With getNodeAutoInstrumentations, you'll already be getting some basic system metrics. For custom business metrics, you can use the OTel Metrics API:

javascript
// In your app.js or a separate module
const api = require('@opentelemetry/api');
const meter = api.metrics.getMeter('my-custom-meter');

// Create a counter metric
const requestCounter = meter.createCounter('http_requests_total', {
  description: 'Total number of HTTP requests',
});

app.get('/metrics-example', (req, res) => {
  requestCounter.add(1, { route: '/metrics-example', method: 'GET' });
  res.send('Metric incremented!');
});

Similarly, OpenTelemetry offers a standardized way to emit logs. While many still use traditional log files, OTel's logging API aims to correlate logs with traces, adding traceId and spanId to log records, making them much more useful in a distributed context. SigNoz provides a comprehensive log management interface to view, filter, and analyze these correlated logs.

The Trade-offs: Resource Usage and Learning Curve

While powerful, adopting OpenTelemetry and a platform like SigNoz isn't entirely free. The primary trade-offs are:

  1. Resource Usage: Instrumenting your applications and collecting telemetry data adds some overhead in terms of CPU, memory, and network I/O. For most applications, this overhead is negligible, but it's something to monitor, especially at high throughput. SigNoz itself also requires resources to store and process all that data, so plan your infrastructure accordingly.
  2. Learning Curve: While OTel aims for standardization, there's still a learning curve for understanding its concepts (spans, traces, metrics, attributes, resource attributes, exemplars, etc.) and how to effectively instrument your code. The auto-instrumentations help a lot, but for deep insights, custom instrumentation is often necessary.
  3. Configuration Complexity: Even with a native platform, configuring OTel collectors, exporters, and sampling strategies can get complex as your system grows. It requires a solid understanding of your system's data flow and performance characteristics.

Despite these, the benefits of standardized, correlated observability data, especially for distributed systems, far outweigh the costs. The ability to quickly diagnose issues, understand performance bottlenecks, and gain deep insights into your system's behavior is invaluable.

Wrapping up

You're building complex distributed systems, and relying on fragmented logs and basic metrics is a recipe for disaster. OpenTelemetry provides the unified instrumentation layer you need, and SigNoz offers a powerful, OpenTelemetry-native backend to make sense of all that data. It's a complete, open-source observability platform that can significantly improve your ability to monitor and troubleshoot your applications.

Your next step should be to clone the SigNoz repository and follow their Quick Start guide to get it running locally. Then, try instrumenting one of your own Node.js or Python microservices using the OpenTelemetry auto-instrumentation packages for your language. See how quickly you can get traces and metrics flowing into SigNoz and start exploring the UI. It's a much more effective way to understand your system than tailing log files in SSH sessions.

More from the blog
Available for projectsReady to make something fun 🎈

Ready to build the next system?Wanna build something awesome together?

Currently accepting high-impact opportunities in frontend engineering and scalable web applications.Got a cool idea rattling around? Let's grab a virtual coffee and turn it into something people love. ☕