OPENTELEMETRY

Setup NodeJs OpenTelemetry with Signoz on Kubernetes

Ayush P Gupta
4 min readJan 21, 2024

Monitoring NestJs apps with OpenTelemetry and Signoz

Tracing becomes important for any production-grade app. A developer should be able to monitor which functions are causing delays in overall execution.

OpenTelemetry and Signoz are the most popular choices for Open Source tracing solutions.

In this article, we shall quickly see how to setup both in a Kubernetes cluster via helm charts and setup monitoring on our NestJs app

What is OpenTelemetry?

OpenTelemetry is a collection of APIs, SDKs, and tools. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior.

We shall be using a Nodejs client for the OpenTelemtry setup.

What is Signoz?

SigNoz is an open-source observability tool to help you find issues in your deployed applications & solve them quickly.

Signoz provides its own OTEL collector collecting open telemetry logs

Getting Started

We shall now see how to deploy Signoz on Kubernetes.

Note: We assume you have a Kubernetes cluster running. Also, we shall use NestJs app to implement OpenTelemetry in it

We shall use the helm chart to deploy our Signoz suite:

Using namespace signoz and helm release name signoz

helm repo add signoz https://charts.signoz.io
helm upgrade --install signoz signoz/signoz -n signoz --create-namespace --values ./values.yml

We need to wait for a few seconds till our services are fully up.
The output of the above commands shall look like this:

1. You have just deployed SigNoz cluster:

- frontend version: '0.37.0'
- query-service version: '0.37.0'
- alertmanager version: '0.23.4'
- otel-collector version: '0.88.8'
- otel-collector-metrics version: '0.88.8'

2. Get the application URL by running these commands:

export POD_NAME=$(kubectl get pods --namespace signoz -l "app.kubernetes.io/name=signoz,app.kubernetes.io/instance=signoz,app.kubernetes.io/component=frontend" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:3301 to use your application"
kubectl --namespace signoz port-forward $POD_NAME 3301:3301


If you have any ideas, questions, or any feedback, please share on our Github Discussions:
https://github.com/SigNoz/signoz/discussions/713

We can see following pods are up:

We are interested in the following Pods:

  • signoz-frontend-5bfc85dd64-fpn2c
    A pod that provides access to the frontend of Signoz

We are interested in the following Services:

These shall become endpoints for the OpenTelemetry logs collector

Setting up OpenTelemetry in NestJs app

Now in our NestJs app, we need to include the following dependencies:

npm install --save @opentelemetry/auto-instrumentations-node
npm install --save @opentelemetry/exporter-trace-otlp-http
npm install --save @opentelemetry/resources
npm install --save @opentelemetry/sdk-node
npm install --save @opentelemetry/semantic-conventions

After installing, include the following tracer.ts file in your code:

import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { NodeSDK } from "@opentelemetry/sdk-node";

const exporterOptions = {
// url: "http://localhost:4318/v1/traces",
};

const traceExporter = new OTLPTraceExporter(exporterOptions);
const sdk = new NodeSDK({
traceExporter,
instrumentations: [getNodeAutoInstrumentations({ "@opentelemetry/instrumentation-nestjs-core": { enabled: true } })],
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: "<your app name>",
}),
});

// gracefully shut down the SDK on process exit
process.on("SIGTERM", () => {
sdk
.shutdown()
.then(() => console.log("Tracing terminated"))
.catch((error) => console.log("Error terminating tracing", error))
.finally(() => process.exit(0));
});

// gracefully shut down the SDK on process exit
process.on("SIGINT", () => {
sdk
.shutdown()
.then(() => console.log("Tracing terminated"))
.catch((error) => console.log("Error terminating tracing", error))
.finally(() => process.exit(0));
});

export default sdk;

Note- You need to replace Service name by your app name

Now in your main.ts include the following line to start the tracer

import tracer from "./tracer";

async function bootstrap() {
const app = await NestFactory.create(AppModule, {});

// this line
tracer.start();

void app.listen(port);
}

We need to set two env variables to make the OpenTelemetry point to the correct collector. In our case signoz-otel-collector service.

# OpenTelemetry
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://signoz-otel-collector.signoz.svc.cluster.local:4318/v1/traces

This env variable is important. Note:

  • http: We shall use HTTP protocol
  • signoz-otel-collector.signoz.svc.cluster.local:4318:
    Point to the correct service name and port.
    Service endpoint shall be of the following pattern:
    <service-name>.<namespace>.svc.cluster.local:port
  • v1/traces: Default endpoint

Read more here: https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/

Deploy your new NestJs app on Kubernetes.

Now let us check back our Signoz frontend by port forwarding the signoz-frontend-5bfc85dd64-fpn2c pod.

Note: I have used the 3010 port for port-forward. Default is 3301.

If you see your application name above, Congratulations we have deployed OpenTelemetry successfully. It's time to explore this dashboard.

Conclusion

In this article, we saw how to set up Signoz and OpenTelemetry for monitoring our NestJs application.
We can use Grafana Tracing, and Tempo as an alternative to Signoz.

Whola! Both you and I learned something new today. Congrats
👏 👏 👏

Further Reading

--

--

Ayush P Gupta

NodeJs | VueJs | Kubernetes | Flutter | Linux | DIY person