Monitoring Your NestJS Application with AppSignal

Connor James

Connor James on

Monitoring Your NestJS Application with AppSignal

NestJS is a popular framework for Node.js that allows you to build efficient and scalable backend applications. With AppSignal, you can monitor your NestJS app with ease and rely on OpenTelemetry to handle third-party instrumentations. AppSignal even provides helper functions to help you build comprehensive custom instrumentations.

This article aims to help you get the most out of your AppSignal integration. We'll walk you through all you need to know to get your NestJS application up and running with AppSignal, discuss request profiling and error tracking, and demonstrate our custom instrumentation helper functions.

Getting Started with NestJS and AppSignal

If you've yet to install our Node.js integration, we've made doing so easy with our installer. To get started, use the below command to run our automated installer tool.

Firstly, make sure you've installed our Node.js integration on your application. For a smoother setup, we advise using our installation tool, which can be initiated by using the following command:

npx @appsignal/cli install

Once installed, our documentation will walk you through any additional installation steps.

If you're already using our Node.js integration, check to ensure you're using the latest version. This blog post is based on our recently released 3.x OpenTelemetry-based integration. You'll need to upgrade if you still use our 2.x integration. Our migration guide details the steps necessary to upgrade your application's integration.

Once you've installed our 3.x integration, that's it - no other installations are needed! Thanks to our adoption of OpenTelemetry, we now automatically instrument popular instrumentations, including NestJS.

Be sure to load AppSignal's instrumentation before any other library. To do so, you will need to require the appsignal.cjs before initializing your application, such as with the following command:

node --require ./dist/appsignal.js dist/main

Or by altering your application's package.json file, like in the example below:

"scripts": { "prebuild": "rimraf dist", "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node --require ./dist/appsignal.js dist/main" }


Now that you've successfully set up your AppSignal integration, you can utilize AppSignal and get the insights you need to keep your application running smoothly. In this section, we'll show you how to use AppSignal for profiling and error tracking, and how to configure custom instrumentations.

Request Profiling in AppSignal

AppSignal allows you to profile your requests, giving detailed insights into the functions being called and their duration. Profiling enables you to gain a broader understanding of how performant your application is and assists you in improving performance by giving you the insights you need. Let's take a look at this in action:

import { Controller, Get } from "@nestjs/common" import { AppService } from "./app.service" import { Pool } from "pg" @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() getStroopWafel(): string { const pgPool = new Pool() pgPool.query("SELECT 1 + 1 AS solution", (err, _result) => { if (err) { throw err } }) return this.appService.getStroopWafel() } }

In the above code sample, we have a NestJS controller with a get function called getStroopWafel, which will query our PostgreSQL database to retrieve matching records. Inefficient database queries can often cause performance issues. When AppSignal made a request to this endpoint, it automatically caught a performance issue and created an incident. When examining the incident, we can clearly see in the Event Timeline that our PostgreSQL request is non-performant and must be improved:


Error Tracking in AppSignal

Of course, AppSignal doesn't just monitor your application's performance. One of its most notable features is that it can catch errors. In the following code block, we've modified the getHello(); method to throw a new error:

import { Controller, Get } from "@nestjs/common" import { AppService } from "./app.service" import { Pool } from "pg" @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() getStroopWaffel(): string { const pgPool = new Pool() pgPool.query("SELECT 1 + 1 AS solution", (err, _result) => { if (err) { throw new Error("QUERY ERROR") } }) return this.appService.getStroopWaffel() } }

Once thrown, AppSignal catches the error as a new incident. From within the AppSignal application, you'll see critical information, such as the error message, sample tags, and a detailed backtrace. If you've configured your application to report deployments to AppSignal, you'll also see samples of the same error within your application's deployment history. This information can be critical in determining the root cause of a vital issue or spotting a recurring problem.

Error message text in AppSignal

Custom Instrument Your NestJS App in AppSignal

AppSignal also supports custom instrumentation. Ten helper methods are available to help you expand your application monitoring to cover behavior not automatically reported by our Node.js integration, for example, setting request header information or session data.

  • Namespace - adds the namespace from where the code is being executed
  • Tag - adds filterable tags to a sample
  • requestParameters - adds request parameters to a sample
  • setSessionData - adds session data to a sample
  • requestHeaders - adds request headers to a sample
  • rootName - adds a root name to a sample
  • customData - allows for custom data to be added to a sample
  • Child Span Helpers:
    • Category - adds a category to a child span
    • Name - adds a name to a child span
    • Body - adds body data to a child span

To use helpers, you first need to import the relevant helper function. In the example below, we use custom instrumentation helper methods to set a requested namespace data and add tags. The category, name, and body helpers are only available from within a child span. You can create a child span and access these helpers like below, where we add a category to our request data:

import { Controller, Get } from "@nestjs/common" import { AppService } from "./app.service" import { setNamespace, setTag, setCategory } from "@appsignal/nodejs"; import { trace } from "@opentelemetry/api" @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() getStroopWaffel(): string { setNamespace("waffle-factory") setTag("sugar", "syrup") const tracer = trace.getTracer("stroopwaffel-factory") tracer.startActiveSpan("getting stroopwaffles", (span) => { setCategory("waffle") span.end() }) return this.appService.getHello() } }

When reviewing the incident triggered by this custom instrumentation, we can see the namespace and tag information and use this information to filter similar requests.

Attributes set with helper functions in NestJS

Wrap Up

Of course, this is just a sample of what is possible with our AppSignal integration for your Node.js app. Our AppSignal for Node.js documentation walks you through the installation and upgrade process with detailed explanations and code examples. If you'd like to learn more about AppSignal's commitment to OpenTelemetry, you can read more in our OpenTelemetry blog post.

We also integrate with several popular third-party development applications, like Slack, Discord, Jira, and GitHub, to help you streamline and automate your workflows.

Stroopwafels and Support

If you have any questions about this article or AppSignal, or need assistance integrating AppSignal into your application, please don't hesitate to get in touch! Remember, if you're new to AppSignal, we'd love to welcome you onboard with a delicious shipment of stroopwafels 🍪 😋

Connor James

Connor James

Official technical writer at AppSignal. Podcast addict who loves cannoli so much that he's considering changing his name to Connoli. He thinks there's a `u` in color. You might find him on the mic, on the stage, or lying on the sofa when he's off Documentation Duty.

All articles by Connor James

Become our next author!

Find out more

AppSignal monitors your apps

AppSignal provides insights for Ruby, Rails, Elixir, Phoenix, Node.js, Express and many other frameworks and libraries. We are located in beautiful Amsterdam. We love stroopwafels. If you do too, let us know. We might send you some!

Discover AppSignal
AppSignal monitors your apps