Nodejs tops the checklist of most generally used frameworks for server-side programming by developers. Powered by Google’s V8 engine, its efficiency is unbelievable. In consequence, Nodejs has now turn into a vital a part of the know-how stack of large-scale enterprises and startups. And as nodejs is predicated on Javascript, it’s also simpler to be taught and start with.

Nodejs is a dynamically typed single-threaded programming language. There may be a whole lot of freedom for the interpreter and runtime to make selections that may simply result in reminiscence leaks and excessive CPU masses. As such, monitoring your nodejs utility for efficiency points is vital.

Nevertheless it’s not sufficient to watch your nodejs web servers solely. You have to monitor your whole utility stack for strong utility efficiency. On this tutorial, the pattern utility that we’ll monitor is constructed utilizing the MEVN stack.

Discover ways to construct a CRUD utility utilizing Vue 3, Node, Categorical, and MongoDB.

Complete MEVN stack tutorial

Nodejs efficiency monitoring is crucial to take care of and enhance the applying’s efficiency to satisfy rising customers’ expectations. When a person clicks on an utility’s interface, the request travels from the frontend to the web servers initiating any database calls if required.

On this tutorial, we are going to use OpenTelemetry and SigNoz to watch a full-stack utility. The pattern app is constructed utilizing these 4 elements:

  • Vue 3
  • Categorical
  • Nodejs
  • MongoDB

Utilizing OpenTelemetry and SigNoz, you may hint a person request end-to-end from the frontend to the web servers, together with the database calls. Earlier than we show how to do that with OpenTelemetry and SigNoz, let’s be taught a bit about them.



OpenTelemetry and SigNoz

OpenTelemetry is a vendor-agnostic set of instruments, APIs, and SDKs used to instrument purposes to create and handle telemetry information(logs, metrics, and traces). It goals to make telemetry information a built-in function of cloud-native software program purposes.

OpenTelemetry gives the instrumentation layer to generate and export your telemetry information to a backend. Then, you should select a backend device that may present the information storage and visualization in your telemetry information. That’s the place SigNoz comes into the image.

SigNoz is a full-stack open-source APM device that gives metrics monitoring and distributed tracing.

OpenTelemetry is the way in which ahead for cloud-native utility house owners who need to arrange a sturdy observability framework. It additionally gives you the liberty to decide on any backend evaluation device. SigNoz is constructed to assist OpenTelemetry natively, thus making a terrific combo.



Nodejs Efficiency monitoring with OpenTelemetry and SigNoz

To watch the nodejs utility for efficiency points, we’d like good telemetry information. Telemetry information could be something that tells us how the applying is performing whereas processing person requests. As soon as we’ve that telemetry information, it must be visualized for actionable insights.

OpenTelemetry lets you generate telemetry information, as talked about earlier than. And SigNoz helps to retailer, visualize and run queries on the information. Collectively, OpenTelemetry and SigNoz make a terrific combo to watch nodejs purposes for efficiency points.

Step one is to instrument your utility with OpenTelemetry shopper libraries. Instrumentation is the method of enabling your utility code to generate telemetry information.

We are going to divide the tutorial into two components:

  • Instrumenting the pattern nodejs app
    • Instrumenting the frontend utility made with Vuejs
    • Instrumenting node/specific server
    • Instrumenting MongoDB database calls
  • Monitor nodejs efficiency with SigNoz dashboards



Putting in SigNoz

Initially, you should set up SigNoz. OpenTelemetry doesn’t present any storage capabilities, so you should export the information to SigNoz backend as soon as it’s collected by means of OpenTelemetry.

SigNoz could be put in on macOS or Linux computer systems in simply three steps through the use of a easy set up script.

The set up script routinely installs Docker Engine on Linux. Nonetheless, on macOS, it’s essential to manually set up Docker Engine earlier than working the set up script.

git clone -b principal https://github.com/SigNoz/signoz.git
cd signoz/deploy/
./set up.sh
Enter fullscreen modeExit fullscreen mode

You possibly can go to our documentation for directions on how you can set up SigNoz utilizing Docker Swarm and Helm Charts.

Deployment Docs

If you end up carried out putting in SigNoz, you may entry the UI at http://localhost:3301

SigNoz dashboard
SigNoz dashboard – It exhibits providers from a pattern app that comes bundled with the applying



Instrumenting the full-stack utility with OpenTelemetry

On this part, we shall be monitoring the API calls made out of the frontend Vuejs utility by means of the specific and nodejs server and eventually to Mongodb with OpenTelemetry.

You’ll find the applying code instrumented with OpenTelemetry and able to be monitored with SigNoz here. Get it to your native by cloning the GitHub repo:

git clone https://github.com/SigNoz/mevn-opentelemetry-example.git
Enter fullscreen modeExit fullscreen mode

Within the pattern app repo, the SigNoz folder can be included. You possibly can hold your SigNoz folder anyplace you need. The part beneath explains how you can go about establishing the MEVN utility for monitoring.

Word: The GitHub pattern app is already instrumented with OpenTelemetry.



Frontend monitoring arrange

Get into /shopper utility and set up the OpenTelemetry dependencies by working the next command:

npm i @opentelemetry/api @opentelemetry/sdk-trace-web @opentelemetry/assets @opentelemetry/sdk-trace-base @opentelemetry/exporter-collector @opentelemetry/context-zone @opentelemetry/instrumentation-fetch @opentelemetry/instrumentation
Enter fullscreen modeExit fullscreen mode

Now create a file referred to as tracing.js within the /src folder, and in that file, we shall be including the required setup to allow frontend tracing.

Paste the next code in src/tracing.js file:

import { context, hint, SpanStatusCode } from "@opentelemetry/api";
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
import { Useful resource } from "@opentelemetry/assets";
import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { CollectorTraceExporter } from "@opentelemetry/exporter-collector";
import { ZoneContextManager } from "@opentelemetry/context-zone";
import { FetchInstrumentation } from "@opentelemetry/instrumentation-fetch";
import { registerInstrumentations } from "@opentelemetry/instrumentation";

const serviceName = "link-frontend"; //bear in mind this service identify

const useful resource = new Useful resource({ "service.identify": serviceName });
const supplier = new WebTracerProvider({ useful resource });

const collector = new CollectorTraceExporter({
    url: "http://localhost:4318/v1/traces",
});

supplier.addSpanProcessor(new SimpleSpanProcessor(collector));
supplier.register({ contextManager: new ZoneContextManager() });

const webTracerWithZone = supplier.getTracer(serviceName);

var bindingSpan;

window.startBindingSpan = (
    traceId,
    spanId,
    traceFlags,
) => {
    bindingSpan = webTracerWithZone.startSpan("");
    bindingSpan.spanContext().traceId = traceId;
    bindingSpan.spanContext().spanId = spanId;
    bindingSpan.spanContext().traceFlags = traceFlags;
};

registerInstrumentations({
    instrumentations: [
        new FetchInstrumentation({
            propagateTraceHeaderCorsUrls: ["/.*/g"],
            clearTimingResources: true,
            applyCustomAttributesOnSpan: (
                span,
                request,
                consequence,
            ) => {
                const attributes = span.attributes;
                if (attributes.part === "fetch") {
                    span.updateName(
                        `${attributes["http.method"]} ${attributes["http.url"]}`
                    );
                }
                if (consequence instanceof Error) {
                    span.setStatus({
                        code: SpanStatusCode.ERROR,
                        message: consequence.message,
                    });
                    span.recordException(consequence.stack || consequence.identify);
                }
            },
        }),
    ],
});

// That is the perform that we'll be utilizing to hint perform calls
export perform traceSpan(
    identify,
    func
) {
    var singleSpan;
    if (bindingSpan) {
        const ctx = hint.setSpan(context.energetic(), bindingSpan);
        singleSpan = webTracerWithZone.startSpan(identify, undefined, ctx);
        bindingSpan = undefined;
    } else {
        singleSpan = webTracerWithZone.startSpan(identify);
    }
    return context.with(hint.setSpan(context.energetic(), singleSpan), () => {
        attempt {
            const consequence = func();
            singleSpan.finish();
            return consequence;
        } catch (error) {
            singleSpan.setStatus({ code: SpanStatusCode.ERROR });
            singleSpan.finish();
            throw error;
        }
    });
}
Enter fullscreen modeExit fullscreen mode

Now import the traceSpan perform from the src/tracing.js file and use it with the features that you simply’re utilizing to make API calls.

Contained in the <script> part in App.vue

import { traceSpan } from "./tracing";
.
.
.
strategies: {
    async addTodo() {
      const response = await axios.publish("api/todoList/", {
        title: this.title,
        description: this.description
      });
      this.todos.push(response.information);
      this.title = "";
      this.description = "";
    },
    async removeTodo(merchandise, i) {
      await axios.delete("api/todoList/" + merchandise._id);
      this.todos.splice(i, 1);
    },

    // these are the features that we'll use so as to add and take away todo
    async handleAddTodo(e){
        e.preventDefault();
        await traceSpan("addTodo", this.addTodo);
   },
    async handleRemoveTodo(todo, i){
      await traceSpan("removeTodo", this.removeTodo(todo, i));
    }
  }
Enter fullscreen modeExit fullscreen mode

Contained in the <template> part in App.vue, take away addTodo() & removeTodo and use handleAddTodo() & handleRemoveTodo():

<template>
 <div class="principal">
  <h3>Todo Checklist</h3>

  <kind class="kind" >
    <enter class="enter" v-model="title" kind="textual content" identify="identify" placeholder="Enter Todo" />
    <br />
    <enter class="enter" v-model="description" kind="textual content" identify="description"  placeholder="Enter Description" />
    <br />
    <button class="submit-button" @click on="handleAddTodo">Add Todo</button>
  </kind>
  <div class="todo-container">
    <ul>
      <li v-for="(todo, i) in todos" :key="todo._id">
        <div class="todo">
        <span class="todo-name">{{ todo.title }}</span>
        <span class="todo-description">{{ todo.description }}</span>
      </div>
        <button class="delete-btn" @click on="handleRemoveTodo(todo, i)">DELETE TODO</button>
      </li>
    </ul>
  </div>
  </div>
</template>
Enter fullscreen modeExit fullscreen mode

Now, allow CORS within the OpenTelemetry Receiver.Below SigNoz folder, open the otel-collector-config.yaml file. The file is positioned at deploy/docker/clickhouse-setup/otel-collector-config.yaml

You possibly can view the file at SigNoz GitHub repo. Contained in the file add the next CORS config:

http:
  cors:
    allowed_origins:
      - https://netflix.com  # URL of your Frontend utility
Enter fullscreen modeExit fullscreen mode

Replace the URL within the config file to match your frontend utility URL. For this tutorial, we shall be working our frontend utility on http://localhost:8080.

http:
  cors:
    allowed_origins:
      - http://localhost:8080
Enter fullscreen modeExit fullscreen mode

Right here’s a snapshot from the GitHub repo. You’ll find the file here.

Enabling CORS
Enabling CORS

After including the adjustments, you should restart the SigNoz Docker containers.

To cease the working SigNoz cluster:

  • x86 – sudo docker-compose -f docker/clickhouse-setup/docker-compose.yaml cease
  • Apple M1 – sudo docker-compose -f docker/clickhouse-setup/docker-compose.arm.yaml cease

To begin/resume the working SigNoz cluster:

  • x86 – sudo docker-compose -f docker/clickhouse-setup/docker-compose.yaml begin
  • Apple M1 – sudo docker-compose -f docker/clickhouse-setup/docker-compose.arm.yaml begin

*Word: The stopped SigNoz cluster ought to resume and mount to the prevailing docker volumes.

And congratulations, your frontend utility made with Vuejs is now instrumented with OpenTelemetry.



Backend monitoring setup

Now, get into /server and observe the beneath steps

Step1: Set up OpenTelemetry packages:

npm set up --save @opentelemetry/api
npm set up --save @opentelemetry/sdk-node
npm set up --save @opentelemetry/auto-instrumentations-node
npm set up --save @opentelemetry/exporter-otlp-grpc
Enter fullscreen modeExit fullscreen mode

Step 2: Create tracing.js file

Instantiate tracing by making a tracing.js file and utilizing the beneath code:

// tracing.js
'use strict'
const course of = require('course of');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-otlp-grpc');
// configure the SDK to export telemetry information to the console
// allow all auto-instrumentations from the meta package deal
const traceExporter = new OTLPTraceExporter();
const sdk = new opentelemetry.NodeSDK({
  traceExporter,
  instrumentations: [getNodeAutoInstrumentations()]
  });

  // initialize the SDK and register with the OpenTelemetry API
  // this permits the API to report telemetry
  sdk.begin()
  .then(() => console.log('Tracing initialized'))
  .catch((error) => console.log('Error initializing tracing', error));

  // gracefully shut down the SDK on course of exit
  course of.on('SIGTERM', () => {
    sdk.shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch((error) => console.log('Error terminating tracing', error))
    .lastly(() => course of.exit(0));
    });
Enter fullscreen modeExit fullscreen mode

Go the mandatory surroundings variable

As soon as the file is created, you solely must run one final command at your terminal, which passes the mandatory surroundings variables. Right here, you additionally set SigNoz as your backend evaluation device.

export OTEL_EXPORTER_OTLP_ENDPOINT="<IP of SigNoz>:4317"
export OTEL_RESOURCE_ATTRIBUTES=service.identify=<service_name> 
Enter fullscreen modeExit fullscreen mode

Changing the placeholders within the above command for localhost:

IP of SigNoz Backend: localhost (since we’re working SigNoz on our localhost).

service_name: mevn-signoz (you may give no matter identify that fits you)

So the ultimate command is:

export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_RESOURCE_ATTRIBUTES=service.identify=mevn-signoz
Enter fullscreen modeExit fullscreen mode

Change the scripts of package deal.json on server to provoke tracing of the API calls:

//server/package deal.json
"scripts": {
    "begin:server": "node -r ./tracing.js index.js",
    "begin:shopper": "npm run serve --prefix '../shopper/'",
    "dev": "concurrently "npm run begin:server" "npm run begin:shopper""
  },
Enter fullscreen modeExit fullscreen mode

Now run each shopper & server:

npm run dev
Enter fullscreen modeExit fullscreen mode

Now, the shopper needs to be working on http://localhost:8080 whereas the server
runs on http://localhost:3000

Work together with the applying a bit to generate some dummy information, and look forward to the applying to be seen on the SigNoz dashboard.

Under we are able to discover the mevn-signoz within the checklist of purposes being monitored.

MEVN Example Application on Signoz
MEVN Instance Software on SigNoz



Monitor full-stack Nodejs utility efficiency with SigNoz

You possibly can monitor calls out of your frontend utility below the Traces tab of SigNoz.

Frontned monitoring on SigNoz
Perform calls from frontend being monitored on SigNoz

SigNoz comes with out-of-box charts for monitoring utility metrics. You possibly can monitor key utility metrics like utility latency, requests per second, error fee, and so on. You too can see the checklist of prime endpoints out of your utility.

Application metrics on SigNoz
Monitor utility metrics like latency, requests per second, error share, and so on. with out-of-box charts

The Traces tab of SigNoz helps you analyze the tracing information collected out of your nodejs utility. SigNoz additionally allows you to correlate your metrics with traces. If you wish to examine metrics of a selected endpoint, you may click on on it to see the traces captured for it.

Traces tab on SigNoz
Traces of the /GET endpoint for one of many requests

SigNoz gives Flamegraphs and Gantt charts to visualise the entire journey of person requests or transactions.

Flamegraphs and Gantt Charts on SigNoz
Flamegraphs and Gantt charts on SigNoz dashboard assist you visualize the entire journey of a person request

SigNoz helps you hint database calls too. Within the flamegraphs, you may see the calls made to the MongoDB database within the pattern app.

Trace database calls on SigNoz
Hint Mongodb database calls with SigNoz



Conclusion

Nodejs efficiency monitoring can allow engineering groups to take the best motion whereas troubleshooting efficiency points. With SigNoz and OpenTelemetry, you may arrange efficiency monitoring for a full-stack utility utilizing nodejs because the server-side language.

SigNoz gives distributed tracing, utilizing which you’ll be able to hint transactions from the frontend utility to web servers together with database calls. Such a visibility is required to debug efficiency points in fashionable purposes that use distributed architectures like microservices-based structure or serverless.

OpenTelemetry makes it very handy to instrument a full-stack utility. Furthermore, openTelemetry helps a variety of web frameworks and programming languages. It’s backed by Cloud Native Computing Foundation, the identical basis that incubated Kubernetes.

Should you check out SigNoz to instrument your nodejs utility and face any points, be happy to ping us within the #assist channel.

SigNoz Slack community




Additional Studying

Implementing OpenTelemerty in an Angular application

Tracing MongoDB calls with OpenTelemetry



Abu Sayed is the Best Web, Game, XR, Blockchain Developer, Producer and Singer in Bangladesh. Don't forget to Checkout his Latest Songs.


Read More