feat(api): add prometheus metrics

Currently we support metrics for the Node.js runtime and HTTP endpoints.
This commit is contained in:
Julian Tölle 2020-11-21 19:55:53 +01:00
parent 9869f0a061
commit e2056b4734
6 changed files with 118 additions and 5 deletions

View file

@ -9,6 +9,7 @@ import { DatabaseModule } from "./database/database.module";
import { HealthCheckModule } from "./health-check/health-check.module";
import { ListensModule } from "./listens/listens.module";
import { LoggerModule } from "./logger/logger.module";
import { MetricsModule } from "./metrics/metrics.module";
import { MusicLibraryModule } from "./music-library/music-library.module";
import { ReportsModule } from "./reports/reports.module";
import { SourcesModule } from "./sources/sources.module";
@ -25,6 +26,7 @@ import { UsersModule } from "./users/users.module";
exclude: ["/api*"],
}),
RavenModule,
MetricsModule.forRoot(),
AuthModule,
UsersModule,
SourcesModule,

View file

@ -42,6 +42,9 @@ import { ConfigModule as NestConfigModule } from "@nestjs/config";
is: Joi.valid(true),
then: Joi.required(),
}),
// Prometheus for Metrics (Optional)
PROMETHEUS_ENABLED: Joi.boolean().default(false),
}),
}),
],

View file

@ -0,0 +1,51 @@
import { InboundMiddleware, PromModule } from "@digikare/nestjs-prom";
import { DEFAULT_PROM_OPTIONS } from "@digikare/nestjs-prom/dist/prom.constants";
import {
DynamicModule,
MiddlewareConsumer,
Module,
NestModule,
} from "@nestjs/common";
// Dirty hack because we can not conditionally import modules based on
// injected services and upstream module does not support dynamic configuration
//
// https://github.com/digikare/nestjs-prom/issues/27
const promEnabled = process.env.PROMETHEUS_ENABLED === "true";
@Module({})
export class MetricsModule implements NestModule {
static forRoot(): DynamicModule {
const module = {
imports: [],
providers: [],
};
if (promEnabled) {
const promOptions = {
metricPath: "/api/metrics",
withDefaultsMetrics: true,
withDefaultController: true,
};
module.imports.push(PromModule.forRoot(promOptions));
module.providers.push({
provide: DEFAULT_PROM_OPTIONS,
useValue: promOptions,
});
}
return {
module: MetricsModule,
...module,
};
}
configure(consumer: MiddlewareConsumer) {
if (promEnabled) {
// We register the Middleware ourselves to avoid tracking
// latency for static files served for the frontend.
consumer.apply(InboundMiddleware).forRoutes("/api");
}
}
}