diff --git a/src/modules/metrics/metrics.controller.ts b/src/modules/metrics/metrics.controller.ts new file mode 100644 index 000000000..37facce63 --- /dev/null +++ b/src/modules/metrics/metrics.controller.ts @@ -0,0 +1,23 @@ +import { Controller, Get, Post } from '@nestjs/common'; +import { Scopes } from '../auth/scope.decorator'; +import { ProcessMetricData } from './metrics.interface'; +import { MetricsService } from './metrics.service'; + +@Controller('metrics') +export class MetricsController { + constructor(private metricsService: MetricsService) {} + + /** Get process metrics */ + @Get('process') + @Scopes('metric:read-process') + process(): Promise { + return this.metricsService.getProcessMetrics(); + } + + /** Update metrics */ + @Post('update') + @Scopes('metric:write-process') + update(): Promise { + return this.metricsService.updateProcessMetrics(); + } +} diff --git a/src/modules/metrics/metrics.interface.ts b/src/modules/metrics/metrics.interface.ts new file mode 100644 index 000000000..f19754fbe --- /dev/null +++ b/src/modules/metrics/metrics.interface.ts @@ -0,0 +1,5 @@ +export interface ProcessMetricData { + date: Date; + cpu: number; + memory: number; +} diff --git a/src/modules/metrics/metrics.module.ts b/src/modules/metrics/metrics.module.ts new file mode 100644 index 000000000..a75becdd5 --- /dev/null +++ b/src/modules/metrics/metrics.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { PrismaModule } from '../../providers/prisma/prisma.module'; +import { MetricsController } from './metrics.controller'; +import { MetricsService } from './metrics.service'; + +@Module({ + imports: [PrismaModule], + controllers: [MetricsController], + providers: [MetricsService], + exports: [MetricsService], +}) +export class MetricsModule {} diff --git a/src/modules/metrics/metrics.service.ts b/src/modules/metrics/metrics.service.ts new file mode 100644 index 000000000..d9986a3bc --- /dev/null +++ b/src/modules/metrics/metrics.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import CircularBuffer from 'circularbuffer'; +import pidusage from 'pidusage'; +import { PrismaService } from '../../providers/prisma/prisma.service'; +import type { ProcessMetricData } from './metrics.interface'; + +@Injectable() +export class MetricsService { + private queue = new CircularBuffer(60); + + constructor(private prisma: PrismaService) {} + + async updateProcessMetrics(): Promise { + const stats = await pidusage(process.pid); + this.queue.enq({ + date: new Date(), + cpu: Math.round(stats.cpu * 100) / 100, + memory: Math.round(stats.memory * 100) / 100, + }); + return this.getProcessMetrics(); + } + + async getProcessMetrics(): Promise { + return this.queue.toArray(); + } +}