From af9c455ee0e075e2b860ebb2ddea512b5c63a96c Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Fri, 11 Jul 2025 12:15:08 +0800 Subject: [PATCH] feat(server): add process memory usage metrics (#13148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close CLOUD-235 image #### PR Dependency Tree * **PR #13148** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **New Features** * Introduced a new monitoring service that automatically collects and logs process memory usage statistics every minute. * Enhanced system monitoring capabilities by integrating a global monitoring module. * Added support for a new "process" scope in metric tracking. * **Chores** * Improved internal module organization by including the monitoring module in the core functionality set. --- packages/backend/server/src/app.module.ts | 2 ++ .../server/src/base/metrics/metrics.ts | 3 +- .../backend/server/src/core/monitor/index.ts | 9 ++++++ .../server/src/core/monitor/service.ts | 28 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 packages/backend/server/src/core/monitor/index.ts create mode 100644 packages/backend/server/src/core/monitor/service.ts diff --git a/packages/backend/server/src/app.module.ts b/packages/backend/server/src/app.module.ts index e2675a8c3f..ebe1ec6804 100644 --- a/packages/backend/server/src/app.module.ts +++ b/packages/backend/server/src/app.module.ts @@ -36,6 +36,7 @@ import { DocRendererModule } from './core/doc-renderer'; import { DocServiceModule } from './core/doc-service'; import { FeatureModule } from './core/features'; import { MailModule } from './core/mail'; +import { MonitorModule } from './core/monitor'; import { NotificationModule } from './core/notification'; import { PermissionModule } from './core/permission'; import { QuotaModule } from './core/quota'; @@ -112,6 +113,7 @@ export const FunctionalityModules = [ WebSocketModule, JobModule.forRoot(), ModelsModule, + MonitorModule, ]; export class AppModuleBuilder { diff --git a/packages/backend/server/src/base/metrics/metrics.ts b/packages/backend/server/src/base/metrics/metrics.ts index 9154a605fd..c4626b6705 100644 --- a/packages/backend/server/src/base/metrics/metrics.ts +++ b/packages/backend/server/src/base/metrics/metrics.ts @@ -60,7 +60,8 @@ export type KnownMetricScopes = | 'ai' | 'event' | 'queue' - | 'storage'; + | 'storage' + | 'process'; const metricCreators: MetricCreators = { counter(meter: Meter, name: string, opts?: MetricOptions) { diff --git a/packages/backend/server/src/core/monitor/index.ts b/packages/backend/server/src/core/monitor/index.ts new file mode 100644 index 0000000000..6385712b04 --- /dev/null +++ b/packages/backend/server/src/core/monitor/index.ts @@ -0,0 +1,9 @@ +import { Global, Module } from '@nestjs/common'; + +import { MonitorService } from './service'; + +@Global() +@Module({ + providers: [MonitorService], +}) +export class MonitorModule {} diff --git a/packages/backend/server/src/core/monitor/service.ts b/packages/backend/server/src/core/monitor/service.ts new file mode 100644 index 0000000000..ba1c25c9b6 --- /dev/null +++ b/packages/backend/server/src/core/monitor/service.ts @@ -0,0 +1,28 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { Cron, CronExpression } from '@nestjs/schedule'; + +import { metrics } from '../../base'; + +@Injectable() +export class MonitorService { + protected logger = new Logger(MonitorService.name); + + @Cron(CronExpression.EVERY_MINUTE) + async monitor() { + const memoryUsage = process.memoryUsage(); + this.logger.log( + `memory usage: rss: ${memoryUsage.rss}, heapTotal: ${memoryUsage.heapTotal}, heapUsed: ${memoryUsage.heapUsed}, external: ${memoryUsage.external}, arrayBuffers: ${memoryUsage.arrayBuffers}` + ); + metrics.process.gauge('node_process_rss').record(memoryUsage.rss); + metrics.process + .gauge('node_process_heap_total') + .record(memoryUsage.heapTotal); + metrics.process + .gauge('node_process_heap_used') + .record(memoryUsage.heapUsed); + metrics.process.gauge('node_process_external').record(memoryUsage.external); + metrics.process + .gauge('node_process_array_buffers') + .record(memoryUsage.arrayBuffers); + } +}