debugger-help 4.2.0__tar.gz → 4.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: debugger-help
3
- Version: 4.2.0
3
+ Version: 4.2.2
4
4
  Summary: debugger.help VPS Agent — Deep system monitoring for logs, GPU, PM2, Docker, and more
5
5
  Author: debugger.help
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """debugger.help VPS Agent — Deep system monitoring + ComfyUI workflow management."""
2
- __version__ = "4.1.1"
2
+ __version__ = "4.2.2"
@@ -713,11 +713,20 @@ def get_firewall_rules():
713
713
  # =============================================================================
714
714
 
715
715
  class LogFileWatcher(threading.Thread):
716
+ # Normalize timestamps/numbers for smarter dedup
717
+ _NORMALIZE_RE = re.compile(r'\d{2,4}[:\-/\.]\d{2}[:\-/\.]\d{2,4}[\sT]?\d{0,2}:?\d{0,2}:?\d{0,2}\.?\d*|\b\d{4,}\b')
718
+
716
719
  def __init__(self, files):
717
720
  super().__init__(daemon=True)
718
721
  self.files = files
719
722
  self.positions = {}
720
723
  self._recent_hashes = deque(maxlen=500)
724
+ self._file_rate = {} # filepath -> (last_send_time, skip_count)
725
+ self._MIN_INTERVAL = 10 # min seconds between sends per file for similar content
726
+
727
+ def _normalize(self, text):
728
+ """Strip timestamps and long numbers so similar lines produce the same hash."""
729
+ return self._NORMALIZE_RE.sub("_", text.strip()[:300])
721
730
 
722
731
  def run(self):
723
732
  for f in self.files:
@@ -737,12 +746,20 @@ class LogFileWatcher(threading.Thread):
737
746
  self.positions[filepath] = fh.tell()
738
747
 
739
748
  if new_lines.strip():
740
- # Deduplicate
741
- msg_hash = hash(new_lines.strip()[:300])
749
+ # Deduplicate with normalized content (ignores timestamps)
750
+ normalized = self._normalize(new_lines)
751
+ msg_hash = hash(normalized)
742
752
  if msg_hash in self._recent_hashes:
743
753
  continue
744
754
  self._recent_hashes.append(msg_hash)
745
755
 
756
+ # Per-file rate limiting — max 1 log per file per 10s
757
+ now = time.time()
758
+ last_send, skip_count = self._file_rate.get(filepath, (0, 0))
759
+ if now - last_send < self._MIN_INTERVAL:
760
+ self._file_rate[filepath] = (last_send, skip_count + 1)
761
+ continue
762
+
746
763
  level = "info"
747
764
  lower = new_lines.lower()
748
765
  if any(kw in lower for kw in ["error", "exception", "traceback", "failed", "critical"]):
@@ -750,13 +767,19 @@ class LogFileWatcher(threading.Thread):
750
767
  elif "warn" in lower:
751
768
  level = "warn"
752
769
 
770
+ msg = new_lines.strip()[:2000]
771
+ if skip_count > 0:
772
+ msg = "[+{} similar skipped] {}".format(skip_count, msg)
773
+
774
+ self._file_rate[filepath] = (now, 0)
775
+
753
776
  send({
754
777
  "type": "log",
755
778
  "source": SOURCE_NAME,
756
779
  "platform": PLATFORM,
757
780
  "version": VERSION,
758
781
  "level": level,
759
- "message": "[file:{}] {}".format(os.path.basename(filepath), new_lines.strip()[:2000]),
782
+ "message": "[file:{}] {}".format(os.path.basename(filepath), msg),
760
783
  "context": {"capturedFrom": "file_watcher", "file": filepath},
761
784
  })
762
785
  elif size < self.positions.get(filepath, 0):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: debugger-help
3
- Version: 4.2.0
3
+ Version: 4.2.2
4
4
  Summary: debugger.help VPS Agent — Deep system monitoring for logs, GPU, PM2, Docker, and more
5
5
  Author: debugger.help
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "debugger-help"
7
- version = "4.2.0"
7
+ version = "4.2.2"
8
8
  description = "debugger.help VPS Agent — Deep system monitoring for logs, GPU, PM2, Docker, and more"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes