1+ """
2+ ================================================================================
3+ Logger Utility Module
4+ ================================================================================
5+ Author : Breno Farias da Silva
6+ Created : 2025-12-11
7+ Description :
8+ This module implements a dual-channel logging system designed to cleanly
9+ capture all console output produced by Python scripts.
10+
11+ Its purpose is to provide consistent, color-safe logging across interactive
12+ terminals, background executions, CI pipelines, Makefile pipelines, and
13+ nohup/systemd environments.
14+
15+ Key features include:
16+ - Automatic ANSI color detection and stripping for log files
17+ - Full compatibility with interactive and non-interactive terminals
18+ - Mirrored output: terminal + clean log file
19+ - Seamless integration with print() and exceptions
20+ - Drop-in replacement for sys.stdout and sys.stderr
21+
22+ Usage:
23+ 1. Import the module in any script requiring safe logging.
24+
25+ from logger import DualLogger
26+ sys.stdout = DualLogger("./Logs/output.log")
27+ sys.stderr = sys.stdout
28+
29+ 2. Run your script normally or via Makefile.
30+ $ make dataset_converter or $ python script.py
31+
32+ 3. All printed output appears colored in the terminal (when interactive)
33+ and clean (color-free) in the log file.
34+
35+ Outputs:
36+ - <path>.log file containing fully sanitized log output
37+ - Real-time console output with correct ANSI handling
38+
39+ TODOs:
40+ - Add timestamp prefixing to all log lines
41+ - Add optional file rotation or max-size log splitting
42+ - Add a CLI flag to force-enable or disable color output
43+ - Add support for JSON-structured logs
44+
45+ Dependencies:
46+ - Python >= 3.8
47+ - colorama (optional but recommended)
48+
49+ Assumptions & Notes:
50+ - ANSI escape sequences follow the regex pattern \x1B \[[0-9;]*[a-zA-Z]
51+ - Log file is always written without ANSI sequences
52+ - If the output is redirected (not a TTY), color output is disabled
53+ """
54+
55+ import os # For interacting with the filesystem
56+ import re # For stripping ANSI escape sequences
57+ import sys # For replacing stdout/stderr
58+
59+ # Regex Constants:
60+ ANSI_ESCAPE_REGEX = re .compile (r"\x1B\[[0-9;]*[a-zA-Z]" ) # Pattern to remove ANSI colors
61+
62+ # Classes Definitions:
63+
64+ class DualLogger :
65+ """
66+ A logging class that mirrors all console output to both the terminal and
67+ a log file, while stripping ANSI escape codes from the log file.
68+
69+ This ensures that the log file remains clean for archival, debugging,
70+ or machine parsing, while the console retains colored output when
71+ running interactively.
72+
73+ :param logfile_path: Path to the output log file.
74+ :return: None
75+ """
76+
77+ def __init__ (self , logfile_path ):
78+ """
79+ Initializes the DualLogger instance.
80+
81+ :param logfile_path: The path where logs will be written.
82+ :return: None
83+ """
84+
85+ self .logfile_path = logfile_path # Store the log file path
86+ self .logfile = open (logfile_path , "w" , encoding = "utf-8" ) # Open the log file
87+
88+ self .is_tty = sys .stdout .isatty () # Verify if running in a real terminal
89+
90+
0 commit comments