Discover the top benefits of observability
See the research

At New Relic, we’re always adapting to developers’ needs, integrating with innovative tools, frameworks, and libraries. NestJS is one of the many new Node.js frameworks that are helping teams build efficient, reliable, and scalable server-side applications. Until now, it hasn’t been easy to integrate into New Relic One due to NestJS’s use of TypeScript, which is then transpiled to ES5 using a predefined build process. 

However, the New Relic One observability platform now offers a Node.js agent that you can use to integrate NestJS quickly with our agent and code sample. 

The New Relic Node.js APM agent

When talking about scalability, microservices immediately spring to mind. NestJS offers modularity, extensibility, and versatility, but with this comes the complexity of observing your application’s performance. Here is where this NestJS integration comes into play. 

This Node.js agent not only allows you to view the health of, measure performance of, and pinpoint errors in your Node applications, but it also visualizes microservices relationships with service maps or trace requests between your services with distributed tracing.

NEW RELIC NODE.JS INTEGRATION
Node.js logo
Start monitoring your Node.js data today.
Install the Node.js quickstart Install the Node.js quickstart

Create microservices observability with the Node.js agent and NestJS

To demonstrate the integration of NestJS with the New Relic Node.js agent, we’ll be using this example app. It’s a Dockerized service containing two Node.js applications written using NestJS. Both apps have an instance of the New Relic Node.js agent integrated using the concept of NestJS interceptors

When the parent app calls the child interceptors, both apps start a new web transaction. Upon completion of the request between the apps, you’ll find the full path of the request between the microservices in the distributed tracing available within New Relic One. This image illustrates an example path that you might see:

Integrate NestJS using the New Relic Node.js agent

Because it uses the latest JavaScript patterns and is transpiled from TypeScript to ES5 using a pre-defined build process, there are a few key things to know when integrating NestJS with New Relic One.

.ts file extensions

Because NestJS uses TypeScript, it’s important to remember to save the newrelic.ts (js) config file used by the Agent with the .ts extension instead of standard .js extension.

/src directory

It is usually recommended to place the newrelic.ts config file in the root directory of the project. In NestJS, the /src directory is treated as the root directory of the application, because it contains the entry point, the main.ts file. So don’t forget to place the newrelic.ts file in /src .

NestJS Interceptor

In this image, you can see an example implementation of the NestJS interceptor that starts and ends the New Relic agent’s transaction whenever the service is called: 

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelic = require('newrelic');
​
@Injectable()
export class NewrelicInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return newrelic.startWebTransaction(context.getHandler().name, function () {
      const transaction = newrelic.getTransaction();
​
      return next.handle().pipe(
          tap(() => transaction.end())
      );
    });
  }
}

Interceptors intercept HTTP requests, and with this implementation, they send data to New Relic One.

Let’s analyze this example:

  1. On line 9, we required the newrelicmodule.
  2.  Whenever an HTTP request is sent to the application, the interceptor fires.
  3. At line 14, the newrelic module then starts a web transaction. You’ll also see an anonymous function passed as the second argument to startWebTransaction.
  4. This anonymous function is a handler function and defines the function you want to instrument.
  5. On line 15,  we get the current New Relic/NestJS transaction.
  6. On line 17, we use next, which is a NestJS call handler.
  7. We call next.handle() when the captured HTTP request is returned back to the caller.
  8. This is when we know that the HTTP request (the transaction) has finished. To tell the New Relic Agent to end the transaction we use transaction.end() at line 18.

Sample application

If you want to play around with NestJS and New Relic, visit the nestjs-test-app GitHub repository where you can find further details and instructions. In the repository, you'll find everything you need to integrate your NestJS applications with New Relic One so you can benefit from the latest technologies in both the JavaScript and observability worlds. Feel free to reach out to the repository maintainers if you have any questions.