251206:1710 specs: frontend plan P1,P3 wait Verification
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled

This commit is contained in:
admin
2025-12-06 17:10:56 +07:00
parent be3b71007a
commit 5c49bac772
40 changed files with 977 additions and 244 deletions
@@ -8,7 +8,6 @@ import {
MemoryHealthIndicator,
DiskHealthIndicator,
} from '@nestjs/terminus';
import { MetricsService } from '../services/metrics.service';
@Controller()
export class HealthController {
@@ -17,8 +16,7 @@ export class HealthController {
private http: HttpHealthIndicator,
private db: TypeOrmHealthIndicator,
private memory: MemoryHealthIndicator,
private disk: DiskHealthIndicator,
private metricsService: MetricsService,
private disk: DiskHealthIndicator
) {}
@Get('health')
@@ -37,9 +35,4 @@ export class HealthController {
this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.9 }),
]);
}
@Get('metrics')
async getMetrics() {
return await this.metricsService.getMetrics();
}
}
@@ -4,6 +4,11 @@ import { Global, Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { APP_INTERCEPTOR } from '@nestjs/core';
import {
PrometheusModule,
makeCounterProvider,
makeHistogramProvider,
} from '@willsoto/nestjs-prometheus';
// Existing Components
import { HealthController } from './controllers/health.controller';
@@ -14,21 +19,39 @@ import { PerformanceInterceptor } from '../../common/interceptors/performance.in
import { MonitoringController } from './monitoring.controller';
import { MonitoringService } from './monitoring.service';
@Global() // Module นี้เป็น Global (ดีแล้วครับ)
@Global()
@Module({
imports: [TerminusModule, HttpModule],
controllers: [
HealthController, // ✅ ของเดิม: /health
MonitoringController, // ✅ ของใหม่: /monitoring/maintenance
imports: [
TerminusModule,
HttpModule,
PrometheusModule.register({
path: '/metrics',
defaultMetrics: {
enabled: true,
},
}),
],
controllers: [HealthController, MonitoringController],
providers: [
MetricsService, // ✅ ของเดิม
MonitoringService, // ✅ ของใหม่ (Logic เปิด/ปิด Maintenance)
MetricsService,
MonitoringService,
{
provide: APP_INTERCEPTOR,
useClass: PerformanceInterceptor, // ✅ ของเดิม (จับเวลา Response Time)
useClass: PerformanceInterceptor,
},
// Metrics Providers
makeCounterProvider({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
}),
makeHistogramProvider({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.1, 0.2, 0.5, 1.0, 1.5, 2.0, 5.0],
}),
],
exports: [MetricsService, MonitoringService],
exports: [MetricsService, MonitoringService, PrometheusModule],
})
export class MonitoringModule {}
@@ -1,54 +1,16 @@
// File: src/modules/monitoring/services/metrics.service.ts
import { Injectable } from '@nestjs/common';
import { Registry, Counter, Histogram, Gauge } from 'prom-client';
import { Counter, Histogram } from 'prom-client';
import { InjectMetric } from '@willsoto/nestjs-prometheus';
@Injectable()
export class MetricsService {
private readonly registry: Registry;
public readonly httpRequestsTotal: Counter<string>;
public readonly httpRequestDuration: Histogram<string>;
public readonly systemMemoryUsage: Gauge<string>;
constructor(
@InjectMetric('http_requests_total')
public readonly httpRequestsTotal: Counter<string>,
@InjectMetric('http_request_duration_seconds')
public readonly httpRequestDuration: Histogram<string>
) {}
constructor() {
this.registry = new Registry();
this.registry.setDefaultLabels({ app: 'lcbp3-backend' });
// นับจำนวน HTTP Request ทั้งหมด แยกตาม method, route, status_code
this.httpRequestsTotal = new Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
registers: [this.registry],
});
// วัดระยะเวลา Response Time (Histogram)
this.httpRequestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.1, 0.2, 0.5, 1.0, 1.5, 2.0, 5.0], // Buckets สำหรับวัด Latency
registers: [this.registry],
});
// วัดการใช้ Memory (Gauge)
this.systemMemoryUsage = new Gauge({
name: 'system_memory_usage_bytes',
help: 'Heap memory usage in bytes',
registers: [this.registry],
});
// เริ่มเก็บ Metrics พื้นฐานของ Node.js (Optional)
// client.collectDefaultMetrics({ register: this.registry });
}
/**
* ดึงข้อมูล Metrics ทั้งหมดในรูปแบบ Text สำหรับ Prometheus Scrape
*/
async getMetrics(): Promise<string> {
// อัปเดต Memory Usage ก่อน Return
const memoryUsage = process.memoryUsage();
this.systemMemoryUsage.set(memoryUsage.heapUsed);
return this.registry.metrics();
}
// Removed manual getMetrics() as PrometheusModule handles /metrics
}