What is @willsoto/nestjs-prometheus?
@willsoto/nestjs-prometheus is a NestJS module that integrates Prometheus metrics into your NestJS application. It allows you to easily create and manage Prometheus metrics, providing a way to monitor the performance and health of your application.
What are @willsoto/nestjs-prometheus's main functionalities?
Basic Setup
This code demonstrates how to set up the Prometheus module in a NestJS application. By importing and registering the PrometheusModule, you can start collecting metrics.
const { Module } = require('@nestjs/common');
const { PrometheusModule } = require('@willsoto/nestjs-prometheus');
@Module({
imports: [PrometheusModule.register()],
})
class AppModule {}
Custom Metrics
This code demonstrates how to create and use custom metrics in your NestJS application. In this example, a custom counter metric named 'my_counter' is created and incremented within a service.
const { Injectable } = require('@nestjs/common');
const { InjectMetric, makeCounterProvider } = require('@willsoto/nestjs-prometheus');
const { Counter } = require('prom-client');
@Injectable()
class MyService {
constructor(@InjectMetric('my_counter') private counter: Counter<string>) {}
incrementCounter() {
this.counter.inc();
}
}
const { Module } = require('@nestjs/common');
@Module({
providers: [
MyService,
makeCounterProvider({
name: 'my_counter',
help: 'Example of a custom counter',
}),
],
})
class AppModule {}
HTTP Metrics
This code demonstrates how to set up HTTP metrics to track the total number of HTTP requests. The counter metric 'http_requests_total' is created with labels for method and status.
const { Module } = require('@nestjs/common');
const { PrometheusModule, makeCounterProvider } = require('@willsoto/nestjs-prometheus');
@Module({
imports: [PrometheusModule.register()],
providers: [
makeCounterProvider({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'status'],
}),
],
})
class AppModule {}
Other packages similar to @willsoto/nestjs-prometheus
prom-client
prom-client is a Prometheus client for Node.js that allows you to create and manage custom metrics. It is a lower-level library compared to @willsoto/nestjs-prometheus and requires more manual setup, but it offers greater flexibility and control.
express-prometheus-middleware
express-prometheus-middleware is a middleware for Express.js applications that automatically collects and exposes Prometheus metrics. It is similar to @willsoto/nestjs-prometheus but is designed specifically for Express.js rather than NestJS.
prometheus-api-metrics
prometheus-api-metrics is a middleware for collecting Prometheus metrics in API applications. It is framework-agnostic and can be used with various Node.js frameworks, providing a flexible alternative to @willsoto/nestjs-prometheus.
NestJS Prometheus
Installation
yarn add @willsoto/nestjs-prometheus prom-client
npm install @willsoto/nestjs-prometheus prom-client
Usage
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
@Module({
imports: [PrometheusModule.register()],
})
export class AppModule {}
By default, this will register a /metrics
endpoint that will return the default metrics.
Changing the metrics http endpoint
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
@Module({
imports: [
PrometheusModule.register({
path: "/mymetrics",
}),
],
})
export class AppModule {}
Disabling default metrics collection
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
@Module({
imports: [
PrometheusModule.register({
defaultMetrics: {
enabled: false,
},
}),
],
})
export class AppModule {}
Configuring the default metrics
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
@Module({
imports: [
PrometheusModule.register({
defaultMetrics: {
config: {},
},
}),
],
})
export class AppModule {}
Injecting individual metrics
import { Module } from "@nestjs/common";
import {
PrometheusModule,
makeCounterProvider,
} from "@willsoto/nestjs-prometheus";
import { Service } from "./service";
@Module({
imports: [PrometheusModule.register()],
providers: [
Service,
makeCounterProvider({
name: "metric_name",
help: "metric_help",
}),
],
})
export class AppModule {}
import { Injectable } from "@nestjs/common";
import { InjectMetric } from "@willsoto/nestjs-prometheus";
import { Counter } from "prom-client";
@Injectable()
export class Service {
constructor(@InjectMetric("metric_name") public counter: Counter<string>) {}
}
Setting default labels
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
@Module({
imports: [
PrometheusModule.register({
defaultLabels: {
app: "My app",
},
}),
],
})
export class AppModule {}
See the docs for more information.
Prefixing custom metrics
You can add a custom prefix to all custom metrics by providing the customMetricPrefix
option to the module configuration.
Some caveats:
In order to have the custom metrics registered in different modules from where the PrometheusModule
was registered, you must do one of a few things:
Option 1 (recommended)
- Add the
PrometheusModule
to the exports
of the registering Module
. It may be useful to create a CommonModule
that registers and exports the PrometheusModule
. - Import that module into whatever module you are creating the custom metrics.
Option 2 (not recommended)
- Mark the
PrometheusModule
as global
Available metrics
import { makeCounterProvider } from "@willsoto/nestjs-prometheus";
import { makeGaugeProvider } from "@willsoto/nestjs-prometheus";
import { makeHistogramProvider } from "@willsoto/nestjs-prometheus";
import { makeSummaryProvider } from "@willsoto/nestjs-prometheus";
Providing a custom controller
If you need to implement any special logic or have access to the controller (e.g., to customize Swagger),
you can provide your own controller (or subclass) of the default controller.
Here is a basic example which should be enough to extend or customize in any way you might need.
import { Controller, Get, Res } from "@nestjs/common";
import { PrometheusController } from "@willsoto/nestjs-prometheus";
import { Response } from "express";
@Controller()
class MyCustomController extends PrometheusController {
@Get()
async index(@Res({ passthrough: true }) response: Response) {
return super.index(response);
}
}
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
import { MyCustomController } from "./my-custom-controller";
@Module({
imports: [
PrometheusModule.register({
controller: MyCustomController,
}),
],
})
export class AppModule {}
Pushgateway
In order to enable Pushgateway for injection, provide the configuration under the pushgateway
key.
import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
@Module({
imports: [
PrometheusModule.register({
pushgateway: {
url: "http://127.0.0.1:9091",
},
}),
],
})
export class AppModule {}
import { Injectable } from "@nestjs/common";
import * as client from "prom-client";
@Injectable()
export class Service {
constructor(private readonly pushgateway: client.Pushgateway) {}
}