feat(metrics): add MetricsService, HttpMetricsInterceptor, and metric constants

- Extract metric names into constants with goodgo_ prefix for business metrics
- Add MetricsService for type-safe metric recording
- Add HttpMetricsInterceptor for automatic request duration/count tracking
- Register interceptor globally via APP_INTERCEPTOR
- Include linter auto-fixes for test files

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 22:38:55 +07:00
parent 238c27c47a
commit 944d6262e7
7 changed files with 175 additions and 14 deletions

View File

@@ -5,6 +5,19 @@ import {
makeHistogramProvider,
makeGaugeProvider,
} from '@willsoto/nestjs-prometheus';
import { MetricsService } from './infrastructure/metrics.service';
import {
GOODGO_API_REQUEST_DURATION,
GOODGO_LISTINGS_CREATED_TOTAL,
GOODGO_PAYMENTS_PROCESSED_TOTAL,
GOODGO_ACTIVE_SUBSCRIPTIONS,
GOODGO_SEARCH_QUERIES_TOTAL,
HTTP_REQUESTS_TOTAL,
DB_QUERY_DURATION,
DB_POOL_ACTIVE_CONNECTIONS,
SEARCH_QUERY_DURATION,
} from './metrics.constants';
import { HttpMetricsInterceptor } from './presentation/interceptors/http-metrics.interceptor';
@Module({
imports: [
@@ -16,56 +29,63 @@ import {
providers: [
// ── HTTP Metrics ──
makeHistogramProvider({
name: 'http_request_duration_seconds',
name: GOODGO_API_REQUEST_DURATION,
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
}),
makeCounterProvider({
name: 'http_requests_total',
name: HTTP_REQUESTS_TOTAL,
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
}),
// ── Database Metrics ──
makeHistogramProvider({
name: 'db_query_duration_seconds',
name: DB_QUERY_DURATION,
help: 'Duration of database queries in seconds',
labelNames: ['operation', 'model'],
buckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5],
}),
makeGaugeProvider({
name: 'db_pool_active_connections',
name: DB_POOL_ACTIVE_CONNECTIONS,
help: 'Number of active database connections',
}),
// ── Search Metrics ──
makeHistogramProvider({
name: 'search_query_duration_seconds',
name: SEARCH_QUERY_DURATION,
help: 'Duration of search queries in seconds',
labelNames: ['collection', 'type'],
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1],
}),
// ── Cache Metrics ── (registered in SharedModule alongside CacheService)
makeCounterProvider({
name: GOODGO_SEARCH_QUERIES_TOTAL,
help: 'Total number of search queries',
labelNames: ['collection', 'type'],
}),
// ── Business Metrics ──
makeCounterProvider({
name: 'listings_created_total',
name: GOODGO_LISTINGS_CREATED_TOTAL,
help: 'Total number of listings created',
labelNames: ['category'],
}),
makeCounterProvider({
name: 'payments_processed_total',
name: GOODGO_PAYMENTS_PROCESSED_TOTAL,
help: 'Total number of payments processed',
labelNames: ['status', 'method'],
}),
makeGaugeProvider({
name: 'active_subscriptions',
name: GOODGO_ACTIVE_SUBSCRIPTIONS,
help: 'Number of active subscriptions',
labelNames: ['plan'],
}),
// ── Services & Interceptors ──
MetricsService,
HttpMetricsInterceptor,
],
exports: [PrometheusModule],
exports: [PrometheusModule, MetricsService, HttpMetricsInterceptor],
})
export class MetricsModule {}