[object Object]

← back to Cncp Failure Collector

fix(collector): skip phantom pm2 restarts

411ed67da01340d475625b36f6f197c999af6393 · 2026-05-11 21:04:43 -0700 · SteveStudio2

Files touched

Diff

commit 411ed67da01340d475625b36f6f197c999af6393
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Mon May 11 21:04:43 2026 -0700

    fix(collector): skip phantom pm2 restarts
---
 index.js | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/index.js b/index.js
index d467daa..8fa7355 100644
--- a/index.js
+++ b/index.js
@@ -161,6 +161,16 @@ async function scanPm2(state) {
     if (restartedSinceLast || flippedDown) {
       const errLog = p.pm2_env?.pm_err_log_path || path.join(PM2_LOG_DIR, `${name}-error.log`);
       const lastLines = fs.existsSync(errLog) ? tailFile(errLog, 30) : '';
+      // Skip "phantom" restarts — process bumped restart_time but is online again
+      // with no error log content. Usually a `pm2 restart` from deploy or a
+      // one-shot scraper finishing under autorestart=true. flippedDown posts
+      // always go through even with empty logs (those are real downtime signals).
+      const restartCountDelta = restartTime - (prior.restart_time || 0);
+      if (restartedSinceLast && !flippedDown && status === 'online' &&
+          lastLines.trim().length === 0 && restartCountDelta <= 1) {
+        state.pm2[name] = { restart_time: restartTime, status, exitedAt };
+        continue;
+      }
       const posted = await postTask({
         source: 'pm2',
         processName: name,

← b3aa723 feat(collector): also filter nginx TLS handshake bot noise  ·  back to Cncp Failure Collector  ·  chore: add dist/build/.next to .gitignore 81d499d →