martomi / chiadog

A watch dog providing a peace in mind that your Chia farm is running smoothly 24/7.
MIT License
458 stars 120 forks source link

Chiadog cannot handle log files with ANSI colors (i.e., when `log_stdout: true`) #288

Open flotti455 opened 3 years ago

flotti455 commented 3 years ago

Describe the bug

Chia's config.yaml provides the option logging.log_stdout.

By default, log_stdout is set to false.

When setting log_stdout to true, logging happens to stdout, allowing advanced control for stuff such as log rotation with logrotate on the operating system level.

Also, setting log_stdout to true causes Chia's output to contain ANSI color escape sequences (e.g., coloring INFO in green). This coloring cannot be turned off via Chia.

Including the recent version 0.7.0, Chiadog cannot handle logfiles with ANSI color escape sequences. Letting Chiadog handle such a "colored" log file causes Chiadog to miss all Chia events, making Chiadog incorrectly report [ WARNING] --- Your harvester appears to be offline! No events for the past 901 seconds. (keep_alive_monitor.py:83).

Therefore it'd be great if Chiadog could handle colored log files as well, e.g. by stripping away any ANSI escape sequences before parsing Chia log output.

Environment:

flotti455 commented 3 years ago

Here is a proof of concept bug fix (FileLogConsumer only) which removes any ANSI escape sequences from log lines (credit: https://stackoverflow.com/a/14693789 ):

$ git diff
diff --git a/src/chia_log/log_consumer.py b/src/chia_log/log_consumer.py
index 6eeb7b1..af08a86 100644
--- a/src/chia_log/log_consumer.py
+++ b/src/chia_log/log_consumer.py
@@ -7,6 +7,7 @@ The latter has not been implemented yet. Feel free to add it.
 """

 # std
+import re
 import logging
 from abc import ABC, abstractmethod
 from pathlib import Path, PurePosixPath, PureWindowsPath, PurePath
@@ -57,6 +58,7 @@ class FileLogConsumer(LogConsumer):
     def __init__(self, log_path: Path):
         super().__init__()
         logging.info("Enabled local file log consumer.")
+        self._ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
         self._expanded_log_path = str(log_path.expanduser())
         self._offset_path = Config.get_log_offset_path()
         self._is_running = True
@@ -73,7 +75,8 @@ class FileLogConsumer(LogConsumer):
         while self._is_running:
             sleep(1)  # throttle polling for new logs
             for log_line in Pygtail(self._expanded_log_path, read_from_end=True, offset_file=self._offset_path):
-                self._notify_subscribers(log_line)
+                ansiless_log_line = self._ansi_escape.sub('', log_line)
+                self._notify_subscribers(ansiless_log_line)