DEV Community

DIVESH YADAV
DIVESH YADAV

Posted on

How I Hooked Up My First Node.js App to SigNoz Cloud in 5 Minutes (Without Docker)

I’ve been hearing a lot about OpenTelemetry lately, but honestly, every tutorial starts with the same exhausting step: "First, install Docker Desktop (which is a massive 600MB+ download), clone this massive repo, and run a bash script."

As a Windows developer running on a mid-range machine, I didn't want to slow down my system just to try out an observability tool. So today, with the hackathon deadline staring at me, I decided to take a shortcut: SigNoz Cloud.

If you are confused about how to instrument a basic application using OpenTelemetry without going through local self-hosting hell, this quick guide is for you. Here is exactly what I did, the errors I hit, and how it finally clicked.


The Goal

We are going to take a dead-simple Node.js Express server, add OpenTelemetry packages, and stream the traces directly to SigNoz Cloud so we can see exactly where our application slows down.


Step 1: Getting the SigNoz Cloud Credentials

Instead of downloading anything, I just went straight to their website and hit the Get Started - Free button.

After a quick Google login, it gives you a clean cloud dashboard. The most important thing you need from here is your Ingestion Key and your Otel Endpoint. SigNoz explicitly tells you where to find these in your settings or onboarding screen. Keep them handy in a notepad; we will need them to point our code to the cloud.


Step 2: Setting up the Dummy Code

I initialized a clean project in my terminal because I wanted to test how OpenTelemetry behaves with real delay loops.

mkdir signoz-cloud-test
cd signoz-cloud-test
npm init -y
npm install express
Enter fullscreen mode Exit fullscreen mode

Then, I created a standard index.js file. To make the dashboard graphs actually look interesting, I added a regular route and a fake "slow" route that mimics a laggy database call using a standard setTimeout promise:

const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Cloud Monitoring is Active!');
});

// Simulating a heavy database query delay
app.get('/api/data', async (req, res) => {
  await new Promise(resolve => setTimeout(resolve, 1200)); 
  res.json({ status: "success", data: "Here is your laggy data" });
});

app.listen(PORT, () => {
  console.log(`Test server running on port ${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

Step 3: The OpenTelemetry Part (Where I Got Confused)

This is where the official docs can get a bit overwhelming because there are a million packages. After checking the opentelemetry.io specs, I realized you don't need to manually initialize tracers for basic Express apps if you use the auto-instrumentation package.

Run this in your terminal to get the required SDK:

npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http
Enter fullscreen mode Exit fullscreen mode

Now, instead of messing up my clean index.js logic, I created a separate file named tracer.js right next to it. This file initializes the OpenTelemetry SDK before our application even loads:

const opentelemetry = require("@opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");

// Connects directly to SigNoz Cloud endpoints
const sdk = new opentelemetry.NodeSDK({
  traceExporter: new OTLPTraceExporter(),
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();
Enter fullscreen mode Exit fullscreen mode

Step 4: Running it with Cloud Environment Variables

Here is the trick. OpenTelemetry looks for specific system variables to know where to send the data. Since we are using SigNoz Cloud, we pass our credentials directly in the terminal command.

Replace YOUR_SIGNOZ_INGESTION_KEY with the actual token from your cloud dashboard:

\$env:OTEL_EXPORTER_OTLP_HEADERS="signoz-access-token=YOUR_SIGNOZ_INGESTION_KEY"
\$env:OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.us.signoz.io:443"
\$env:OTEL_SERVICE_NAME="my-windows-node-app"
node --require ./tracer.js index.js
Enter fullscreen mode Exit fullscreen mode

(Note: If you are on standard Linux/Mac, use export instead of $env:).

Once the server started, I opened Chrome and hit http://localhost:3000/api/data a few times to force that 1.2-second delay into the system.


Step 5: Checking the Traces

I went back to my SigNoz Cloud tab, clicked on Services on the left menu, and there it was—my-windows-node-app was successfully sending live telemetry signals.

When I jumped into the Traces tab, I could clearly see the exact spike caused by my /api/data route. It shows you a beautiful breakdown tree showing that the request spent the majority of its life cycle waiting inside that execution function.


What I Learned & Final Takeaway

If you're just getting started with APM (Application Performance Monitoring) tools, don't waste time trying to configure complex local setups on night one. The open-source standard of OpenTelemetry means that whether you send data to a local Docker container or a managed cloud platform, the underlying code remains exactly the same.

SigNoz makes this incredibly simple because their cloud ingestion endpoints just work right out of the box without requiring custom wrappers.

If you are building an AI agent or a regular web app for this hackathon, use the Cloud route to save your development time for your core project features rather than debugging infra setups.

Let me know in the comments if you face any endpoint connection issues while setting up your header tokens!

Top comments (3)

Collapse
 
topstar_ai profile image
Luis Cruz

I really like how you've streamlined the process of setting up OpenTelemetry with SigNoz Cloud, especially by leveraging the auto-instrumentation package to simplify the tracer initialization. The use of a separate tracer.js file to initialize the OpenTelemetry SDK is a clever approach, as it keeps the main application logic clean and focused on the business functionality. I've had similar experiences with setting up observability tools, and I can appreciate the frustration of dealing with cumbersome installation processes. One thing that might be worth exploring further is how to handle errors and exceptions within the OpenTelemetry context, to get a more comprehensive view of the application's behavior. Have you considered adding any custom error handling or logging mechanisms to your setup?

Collapse
 
divesh_yadav_981d3bfe8adc profile image
DIVESH YADAV

Thanks for the awesome feedback! I really appreciate you taking the time to read the post.Keeping tracer.js separate was a conscious choice because I hate messy main files, so glad to hear you liked that approach!Regarding your question about custom error handling—yes, absolutely! Since I was rushing against the hackathon timeline to get the cloud ingestion working, I kept this initial setup pretty barebones. But my next step is definitely to hook up the OpenTelemetry @opentelemetry/api tracer explicitly inside the Express error-handling middleware. That way, whenever an exception or 500 error hits, we can record the exception directly into the active span using span.recordException(error) and set the span status to error.I'm also planning to explore SigNoz's log management by connecting a standard Winston or Pino logger logger to the OpenTelemetry log exporter so that traces and logs are correlated automatically in the dashboard.Thanks again for the great suggestion, it definitely gives me a solid roadmap for my next update!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.