Frontend Development

Mastering Nest.js Monitoring with Grafana and Prometheus: A Comprehensive Guide

Learn how to set up a comprehensive monitoring system for your NestJS application using Grafana and Prometheus. Monitor key metrics, identify issues, and ensure optimal performance.

Bhavik Charola
6 min read

Mastering Nest.js Monitoring with Grafana and Prometheus: A Comprehensive Guide

NestJS, a powerful framework built on top of Node.js and TypeScript, offers developers a robust structure for building scalable and maintainable applications. However, as your NestJS application grows, monitoring its performance and health becomes crucial.

This blog post will guide you through setting up a comprehensive monitoring system for your NestJS application using the dynamic duo of Grafana and Prometheus. We'll cover everything from logging configuration to building insightful dashboards, allowing you to keep a watchful eye on your application's health and performance.

1. Setting up Logging in NestJS

Before we can monitor, we need data to monitor. NestJS provides a flexible logging system through its built-in Logger service. Here's how to get started:

1.1 Install Dependencies

npm install @nestjs/platform-logger pino

1.2 Configure Logging in your main.ts file:

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const logger = new Logger('Bootstrap');
  logger.log('Starting application...');
  await app.listen(3000);
  logger.log('Application started on port 3000');
}
bootstrap();

1.3 Using the Logger Service:

import { Injectable, Logger } from '@nestjs/common';

@Injectable()
export class MyService {
  private readonly logger = new Logger(MyService.name);

  doSomething() {
    this.logger.log('Doing something...');
  }
}

1.4 Using Pino for Enhanced Logging:

Pino is a high-performance Node.js logger that excels in performance and structured logging.

import { Injectable, Logger } from '@nestjs/common';
import { PinoLogger } from 'nestjs-pino';

@Injectable()
export class MyService {
  constructor(private readonly logger: PinoLogger) {
  }

  doSomething() {
    this.logger.info('Doing something...', { event: 'somethingDone' });
  }
}

By using PinoLogger you can log structured JSON data, enabling more insightful monitoring.

2. Introducing Prometheus: Your Monitoring Workhorse

Prometheus is an open-source monitoring system that gathers metrics from your application and stores them in a time series database.

2.1 Installation:

docker run -d -p 9090:9090 --name prometheus prometheus/prometheus

This command downloads and runs the Prometheus image as a Docker container.

2.2 Exposing Metrics in NestJS:

To expose metrics for Prometheus to scrape, we'll use the @nestjs/prometheus package.

2.2.1 Install dependencies:

npm install @nestjs/prometheus prom-client

2.2.2 Configure in your main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { registerMetrics } from './metrics';

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

  // Register metrics with Prometheus
  registerMetrics(app);

  await app.listen(3000);
}
bootstrap();

2.2.3 Create a metrics helper file (metrics.ts):

import { Injectable } from '@nestjs/common';
import { register } from 'prom-client';
import { Instrument } from '@nestjs/prometheus';
import { Gauge } from 'prom-client';

@Injectable()
export class MetricsService {
  constructor(@Instrument() private gauge: Gauge<string>) {
  }
  
  incrementCounter(): void {
    this.gauge.inc();
  }
}

export function registerMetrics(app) {
  const gauge = new Gauge({
    name: 'my_app_requests',
    help: 'The number of requests processed by the application',
    labelNames: ['status'],
  });
  register.registerMetric(gauge);
  app.useGlobalGuards(new MetricsGuard(gauge));
}

export class MetricsGuard {
  constructor(private readonly gauge: Gauge<string>) {
  }
  
  canActivate(): boolean {
    this.gauge.inc({ status: 'success' });
    return true;
  }
}

This example shows how to track the number of successful requests to your application.

3. Grafana: Visualizing Your Data

Grafana provides a powerful and user-friendly interface for visualizing your Prometheus metrics.

3.1 Install and Run Grafana:

docker run -d -p 3000:3000 --name grafana grafana/grafana

3.2 Add Prometheus as a Data Source:

  1. Access Grafana at http://localhost:3000.
  2. Login with default credentials: admin and admin.
  3. Go to Configuration -> Data Sources and add a new Prometheus data source.
  4. Fill in the details, including the Prometheus endpoint (http://localhost:9090).

3.3 Creating a Dashboard:

  1. Create a new dashboard in Grafana.
  2. Add panels and configure them to display your Prometheus metrics.
  3. You can use Grafana's query builder to create complex queries and visualize your data in different ways (graphs, charts, tables).

4. Alerts: Notifying You of Issues

Grafana allows you to set up alerts based on Prometheus metrics. These alerts can notify you via email, Slack, or other channels if predefined thresholds are exceeded.

4.1 Create an Alert Rule in Prometheus:

groups:
  - name: request_errors
    rules:
      - alert: RequestErrors
        expr: my_app_errors > 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High number of request errors"
          description: "The number of request errors is above 10 for the last 5 minutes."

This rule triggers an alert if the my_app_errors metric exceeds 10 for 5 minutes.

4.2 Configure Alerting in Grafana:

  1. Go to Alerting in Grafana.
  2. Configure the alerting settings for your Prometheus data source.
  3. Select the desired notification channels and configure them.

Conclusion

By implementing the steps outlined in this blog post, you can confidently monitor your NestJS application with Grafana and Prometheus. This powerful combination empowers you to track key metrics, identify potential issues, and proactively maintain your application's health and performance. From logging configuration to building insightful dashboards, this guide has equipped you with the knowledge to build a robust monitoring system, making your NestJS application even more reliable and efficient.

Don't hesitate to explore the vast possibilities of Grafana and Prometheus beyond the basic setup presented here. You can create custom dashboards, utilize advanced querying techniques, and leverage the rich alerting capabilities to gain deeper insights into your application's behavior and ensure its optimal performance.