251124:1700 Ready to Phase 7
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
// File: src/modules/monitoring/controllers/health.controller.ts
|
||||
import { Controller, Get } from '@nestjs/common';
|
||||
import {
|
||||
HealthCheckService,
|
||||
HttpHealthIndicator,
|
||||
HealthCheck,
|
||||
TypeOrmHealthIndicator,
|
||||
MemoryHealthIndicator,
|
||||
DiskHealthIndicator,
|
||||
} from '@nestjs/terminus';
|
||||
import { MetricsService } from '../services/metrics.service';
|
||||
|
||||
@Controller()
|
||||
export class HealthController {
|
||||
constructor(
|
||||
private health: HealthCheckService,
|
||||
private http: HttpHealthIndicator,
|
||||
private db: TypeOrmHealthIndicator,
|
||||
private memory: MemoryHealthIndicator,
|
||||
private disk: DiskHealthIndicator,
|
||||
private metricsService: MetricsService,
|
||||
) {}
|
||||
|
||||
@Get('health')
|
||||
@HealthCheck()
|
||||
check() {
|
||||
return this.health.check([
|
||||
// 1. ตรวจสอบการเชื่อมต่อ Database (MariaDB)
|
||||
() => this.db.pingCheck('database'),
|
||||
|
||||
// 2. ตรวจสอบ Memory Heap (ไม่ควรเกิน 1GB สำหรับ Container นี้ - ปรับค่าตามจริง)
|
||||
() => this.memory.checkHeap('memory_heap', 1024 * 1024 * 1024),
|
||||
|
||||
// 3. ตรวจสอบพื้นที่ Disk สำหรับ DMS Data (Threshold 90%)
|
||||
// path '/' อาจต้องเปลี่ยนเป็น '/share/dms-data' ตาม Environment จริง
|
||||
() =>
|
||||
this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.9 }),
|
||||
]);
|
||||
}
|
||||
|
||||
@Get('metrics')
|
||||
async getMetrics() {
|
||||
return await this.metricsService.getMetrics();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// File: src/modules/monitoring/logger/winston.config.ts
|
||||
import {
|
||||
utilities as nestWinstonUtilities,
|
||||
WinstonModuleOptions,
|
||||
} from 'nest-winston';
|
||||
import * as winston from 'winston';
|
||||
|
||||
/**
|
||||
* ฟังก์ชันสร้าง Configuration สำหรับ Winston Logger
|
||||
* - Development: แสดงผลแบบ Console อ่านง่าย
|
||||
* - Production: แสดงผลแบบ JSON พร้อม Timestamp เพื่อการทำ Log Aggregation
|
||||
*/
|
||||
export const winstonConfig: WinstonModuleOptions = {
|
||||
transports: [
|
||||
new winston.transports.Console({
|
||||
format: winston.format.combine(
|
||||
winston.format.timestamp(),
|
||||
winston.format.ms(),
|
||||
// เลือก Format ตาม Environment
|
||||
process.env.NODE_ENV === 'production'
|
||||
? winston.format.json() // Production ใช้ JSON
|
||||
: nestWinstonUtilities.format.nestLike('LCBP3-DMS', {
|
||||
prettyPrint: true,
|
||||
colors: true,
|
||||
}),
|
||||
),
|
||||
}),
|
||||
// สามารถเพิ่ม File Transport หรือ HTTP Transport ไปยัง Log Server ได้ที่นี่
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
// File: src/modules/monitoring/monitoring.module.ts
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { TerminusModule } from '@nestjs/terminus';
|
||||
import { HttpModule } from '@nestjs/axios';
|
||||
import { APP_INTERCEPTOR } from '@nestjs/core';
|
||||
import { HealthController } from './controllers/health.controller';
|
||||
import { MetricsService } from './services/metrics.service';
|
||||
import { PerformanceInterceptor } from '../../common/interceptors/performance.interceptor';
|
||||
|
||||
@Global() // ทำให้ Module นี้ใช้งานได้ทั่วทั้ง App โดยไม่ต้อง Import ซ้ำ
|
||||
@Module({
|
||||
imports: [TerminusModule, HttpModule],
|
||||
controllers: [HealthController],
|
||||
providers: [
|
||||
MetricsService,
|
||||
{
|
||||
provide: APP_INTERCEPTOR, // Register Global Interceptor
|
||||
useClass: PerformanceInterceptor,
|
||||
},
|
||||
],
|
||||
exports: [MetricsService],
|
||||
})
|
||||
export class MonitoringModule {}
|
||||
@@ -0,0 +1,54 @@
|
||||
// File: src/modules/monitoring/services/metrics.service.ts
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Registry, Counter, Histogram, Gauge } from 'prom-client';
|
||||
|
||||
@Injectable()
|
||||
export class MetricsService {
|
||||
private readonly registry: Registry;
|
||||
public readonly httpRequestsTotal: Counter<string>;
|
||||
public readonly httpRequestDuration: Histogram<string>;
|
||||
public readonly systemMemoryUsage: Gauge<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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user