π Production Integration β Connecting Your Apps to SigNoz
This guide explains how to instrument your Node.js apps (HealthTune and TrackX) so they automatically send traces and logs to SigNoz via PM2.
π Replace all sample paths, ports, and service names with your environment values before running commands.
π Architecture in This Projectβ
HealthTune API (PM2) TrackX API (PM2)
β β
tracing.js (OTEL SDK) tracing.js (OTEL SDK)
β β
OTEL Collector (port 4317)
β
SigNoz (port 3301)
Step 1 β Install OpenTelemetry Packagesβ
You need to add three OTEL packages to each Node.js project.
For HealthTune:
cd /home/youruser/healthtune_api
yarn add @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-grpc
For TrackX:
cd /home/youruser/trackx_api/backend
yarn add @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-grpc
If using npm instead of yarn:
npm install @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-grpc
What Each Package Doesβ
| Package | Purpose |
|---|---|
sdk-node | Core OTEL SDK for Node.js β initializes tracing |
auto-instrumentations-node | Automatically instruments Express, Prisma, DB clients, HTTP β no manual code changes needed |
exporter-trace-otlp-grpc | Sends trace data to the OTEL Collector via gRPC (port 4317) |
Step 2 β Create tracing.jsβ
Create this file in both projects (same content, same filename):
HealthTune: /home/youruser/healthtune_api/tracing.js
TrackX: /home/youruser/trackx_api/backend/tracing.js
'use strict';
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
// This sends your traces to the OTEL Collector running on the same server
const traceExporter = new OTLPTraceExporter({
url: 'http://localhost:4317', // Change 'localhost' if OTEL Collector is on a different server
});
const sdk = new NodeSDK({
// Service name comes from PM2 environment variable (set when starting with PM2)
serviceName: process.env.OTEL_SERVICE_NAME,
traceExporter,
// Auto-instruments: Express routes, DB queries, HTTP calls, etc.
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
β οΈ Important: This file must be loaded before your app code starts. That's why we use
-r(require) in the PM2 command below.
Step 3 β Start Apps with PM2 + Tracingβ
Stop the old PM2 processes first:
pm2 delete healthtune_dev_api
pm2 delete trackx_dev_api
Start HealthTune with tracing enabled:
OTEL_SERVICE_NAME=healthtune_api \
pm2 start "node -r /home/youruser/healthtune_api/tracing.js dist/main.js" \
--name healthtune_dev_api \
--cwd /home/youruser/healthtune_api
Start TrackX with tracing enabled:
NODE_ENV=development \
OTEL_SERVICE_NAME=trackx_dev_api \
pm2 start "node -r /home/youruser/trackx_api/backend/tracing.js server.js" \
--name trackx_dev_api \
--cwd /home/youruser/trackx_api/backend
Placeholder Mapping (Use Your Own Values)β
/home/youruser/...: replace with your real app pathhealthtune_dev_api/trackx_dev_api: replace with your PM2 process namesOTEL_SERVICE_NAME: use stable service names used by your team in dashboards
What These Flags Doβ
| Flag | Meaning |
|---|---|
OTEL_SERVICE_NAME=... | Sets the service name visible in SigNoz dashboard |
node -r tracing.js | Loads tracing.js before anything else in the app |
--name | PM2 process name (used for logs and management) |
--cwd | Working directory for the process |
Step 4 β Save PM2 Process Listβ
After starting both apps, save the PM2 process list so they survive reboots:
pm2 save
pm2 startup
pm2 startup will print a command you need to run as sudo β copy and run it.
Step 5 β Set Up PM2 Log Rotationβ
Without log rotation, PM2 log files grow forever and fill your disk.
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M # rotate when file exceeds 50MB
pm2 set pm2-logrotate:retain 7 # keep 7 rotated files, delete older
Step 6 β Verify Everything Is Runningβ
# Check all PM2 processes are online
pm2 list
# Check collector is running
sudo systemctl status otelcol-contrib
# Make test API calls to generate trace data
curl http://localhost:3000/ # HealthTune
curl http://localhost:7000/ # TrackX (adjust port to your app's port)
After making a few API calls, open SigNoz at http://YOUR_SERVER_IP:3301 and go to Services β you should see healthtune_api and trackx_dev_api listed.
π Environment Variable Referenceβ
These variables control OTEL behavior and can be set per-service:
| Variable | Example Value | Purpose |
|---|---|---|
OTEL_SERVICE_NAME | healthtune_api | Name shown in SigNoz |
OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 | Where to send traces |
OTEL_LOG_LEVEL | debug | Show verbose SDK logs (for debugging) |
NODE_ENV | development | Standard Node env flag |
You can also set these in a .env file and load with your app framework, as long as they are available when tracing.js runs.
π Connecting Other Languagesβ
Python (FastAPI / Flask)β
pip install opentelemetry-sdk opentelemetry-exporter-otlp
# tracing.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor
provider = TracerProvider()
exporter = OTLPSpanExporter(endpoint="http://localhost:4317", insecure=True)
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
Docker-Based Appsβ
If your app runs inside Docker, the OTEL Collector is not at localhost from inside the container. Use the host IP or Docker network name:
const traceExporter = new OTLPTraceExporter({
url: 'http://host.docker.internal:4317', // Windows/Mac Docker Desktop
// OR
url: 'http://172.17.0.1:4317', // Linux Docker host IP
});
β Integration Checklistβ
# Packages installed?
ls healthtune_api/node_modules/@opentelemetry
# tracing.js exists?
cat /home/youruser/healthtune_api/tracing.js
# Apps running?
pm2 list
# Traces showing in SigNoz?
# β Open http://YOUR_IP:3301 β Services
Expected result:
- Both PM2 processes are
online otelcol-contribisactive (running)- Services appear in SigNoz within ~1 minute after test traffic
Next: Troubleshooting β
Official Documentation Linksβ
- SigNoz instrumentation docs
- SigNoz Node.js instrumentation
- SigNoz Python instrumentation
- OpenTelemetry Node.js docs
- OpenTelemetry Python docs
- OpenTelemetry resource attributes
Read in Sequenceβ
- Previous: 5-otel-collector.md
- Next: 7-troubleshooting.md