Prechádzať zdrojové kódy

updated surveillance

Dr-Swopt 1 týždeň pred
rodič
commit
3a0fedcf08
1 zmenil súbory, kde vykonal 44 pridanie a 14 odobranie
  1. 44 14
      src/surveillance/surveillance.service.ts

+ 44 - 14
src/surveillance/surveillance.service.ts

@@ -1,10 +1,12 @@
 import { Injectable, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common';
 import * as si from 'systeminformation';
 
+export type ServiceStatusType = 'ACTIVE' | 'IDLE' | 'OFFLINE';
+
 export interface ServiceStatus {
   service: string; // 'nestjs' | 'n8n' | 'ollama'
   pid: number | null;
-  online: boolean;
+  status: ServiceStatusType;
   cpu: number;    // % usage
   memory: number; // bytes
 }
@@ -21,7 +23,12 @@ export interface SystemMetrics {
 // Keep legacy alias so the Gateway compiles without changes
 export type MonitorPayload = SystemMetrics;
 
-const TRACKED_NAMES = ['node', 'n8n', 'ollama'];
+// Command-based signatures — checked against p.command to avoid node.exe collisions
+const SERVICE_SIGNATURES: Record<string, string> = {
+  nestjs: 'main.js',
+  n8n:    'n8n',
+  ollama: 'ollama',
+};
 
 @Injectable()
 export class SurveillanceService implements OnModuleInit, OnModuleDestroy {
@@ -94,27 +101,50 @@ export class SurveillanceService implements OnModuleInit, OnModuleDestroy {
   private buildServiceStatuses(
     processList: si.Systeminformation.ProcessesProcessData[],
   ): ServiceStatus[] {
-    return TRACKED_NAMES.map((name) => {
+    const ACTIVE_CPU_THRESHOLD = 1.0;
+
+    const statuses = Object.entries(SERVICE_SIGNATURES).map(([serviceName, signature]) => {
       if (processList.length === 0) {
-        return { service: name, pid: null, online: false, cpu: 0, memory: 0 };
+        return { service: serviceName, pid: null, status: 'OFFLINE' as ServiceStatusType, cpu: 0, memory: 0 };
       }
 
-      const match = processList.find((p) =>
-        (p.name ?? '').toLowerCase().includes(name) ||
-        (p.command ?? '').toLowerCase().includes(name),
+      // Single-pass filter by command — avoids node.exe collisions from name-only matching
+      const matches = processList.filter((p) =>
+        (p.command ?? '').toLowerCase().includes(signature.toLowerCase()),
       );
 
-      if (!match) {
-        return { service: name, pid: null, online: false, cpu: 0, memory: 0 };
+      if (matches.length === 0) {
+        return { service: serviceName, pid: null, status: 'OFFLINE' as ServiceStatusType, cpu: 0, memory: 0 };
       }
 
+      // Aggregate CPU and RSS memory across all matching processes
+      const { totalCpu, totalMem, firstPid } = matches.reduce(
+        (acc, p) => ({
+          totalCpu:  acc.totalCpu + (p.cpu ?? 0),
+          totalMem:  acc.totalMem + (p.memRss ?? 0),
+          firstPid:  acc.firstPid ?? p.pid,
+        }),
+        { totalCpu: 0, totalMem: 0, firstPid: null as number | null },
+      );
+
+      const status: ServiceStatusType = totalCpu > ACTIVE_CPU_THRESHOLD ? 'ACTIVE' : 'IDLE';
+
       return {
-        service: name,
-        pid: match.pid,
-        online: true,
-        cpu: parseFloat((match.cpu ?? 0).toFixed(2)),
-        memory: match.memRss ?? 0,
+        service: serviceName,
+        pid:     firstPid,
+        status,
+        cpu:     parseFloat(totalCpu.toFixed(2)),
+        memory:  totalMem,
       };
     });
+
+    // Verification debug log — one line per service per tick
+    for (const s of statuses) {
+      this.logger.debug(
+        `[aggregator] ${s.service.padEnd(8)} | status=${s.status.padEnd(7)} | cpu=${s.cpu.toFixed(2).padStart(6)}% | mem=${s.memory} bytes | pid=${s.pid ?? 'none'}`,
+      );
+    }
+
+    return statuses;
   }
 }