Files
goodgo-platform/apps/api/src/modules/metrics/metrics.module.ts
Ho Ngoc Hai 2a392525a2 feat(cache): implement Redis caching layer for hot-read endpoints
Add cache-aside pattern for listing detail, search results, market
analytics (4 endpoints), and user profile queries. Cache invalidation
on all write mutations. Prometheus cache_hit_total/cache_miss_total
metrics with resource labels.

- CacheService: getOrSet, invalidate, invalidateByPrefix (SCAN-based)
- TTLs: listing 5m, search 1m, market 30m, profile 10m
- All 230 tests passing (13 new cache tests + 6 updated handler tests)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 04:14:06 +07:00

82 lines
2.3 KiB
TypeScript

import { Module } from '@nestjs/common';
import {
PrometheusModule,
makeCounterProvider,
makeHistogramProvider,
makeGaugeProvider,
} from '@willsoto/nestjs-prometheus';
@Module({
imports: [
PrometheusModule.register({
path: '/metrics',
defaultMetrics: { enabled: true },
}),
],
providers: [
// ── HTTP Metrics ──
makeHistogramProvider({
name: 'http_request_duration_seconds',
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',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
}),
// ── Database Metrics ──
makeHistogramProvider({
name: 'db_query_duration_seconds',
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',
help: 'Number of active database connections',
}),
// ── Search Metrics ──
makeHistogramProvider({
name: 'search_query_duration_seconds',
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 ──
makeCounterProvider({
name: 'cache_hit_total',
help: 'Total number of cache hits',
labelNames: ['resource'],
}),
makeCounterProvider({
name: 'cache_miss_total',
help: 'Total number of cache misses',
labelNames: ['resource'],
}),
// ── Business Metrics ──
makeCounterProvider({
name: 'listings_created_total',
help: 'Total number of listings created',
labelNames: ['category'],
}),
makeCounterProvider({
name: 'payments_processed_total',
help: 'Total number of payments processed',
labelNames: ['status', 'method'],
}),
makeGaugeProvider({
name: 'active_subscriptions',
help: 'Number of active subscriptions',
labelNames: ['plan'],
}),
],
exports: [PrometheusModule],
})
export class MetricsModule {}