OPENTELEMETRY
Setup NodeJs OpenTelemetry with Signoz on Kubernetes
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.
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
👏 👏 👏