From 367a6d208ad130837e500fa8d66ed2a8dddf03c3 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Tue, 19 May 2026 06:44:00 +0200 Subject: [PATCH] refactor(logging): reformat log output, adjust stacklevel and field widths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change logging stacklevel from 3 to 4 in all log helper functions (create_module_logger, log_debug, log_info, log_warn, log_error) to correctly attribute the caller location in stack output. - Reduce level_field_width from 9 to 5 (e.g. ERROR→5 chars) and set source_field_width to 0 so source column auto-sizes to its content. - Add MESSAGE color (cyan) for log message highlighting in colored output. - Extract four helper methods from ColoredFormatter.format: _display_logger_name — strips the 'azlogs.' namespace prefix _display_level_name — normalises WARNING → WARN for compact display _format_time — builds HH:MM:SS.mmm timestamps _color_level — applies bold+color to the level token - Simplify format() to assemble [HH:MM:SS.mmm] LVL (logger:line): message with the new helpers applied inline. --- core/log_system/log_funcs.py | 10 +++---- core/log_system/logger.py | 52 +++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/core/log_system/log_funcs.py b/core/log_system/log_funcs.py index d8ea8f2..743a6a2 100644 --- a/core/log_system/log_funcs.py +++ b/core/log_system/log_funcs.py @@ -199,7 +199,7 @@ def create_module_logger(module_name=None): def log_debug(*args, **kwargs): module_name = _resolve_module_name(stack_depth=2) if _initialized: - kwargs.setdefault("stacklevel", 3) + kwargs.setdefault("stacklevel", 4) debug(module_name, *args, **kwargs) else: print(f"[DEBUG] [{module_name}]", *args) @@ -208,7 +208,7 @@ def log_debug(*args, **kwargs): def log_info(*args, **kwargs): module_name = _resolve_module_name(stack_depth=2) if _initialized: - kwargs.setdefault("stacklevel", 3) + kwargs.setdefault("stacklevel", 4) info(module_name, *args, **kwargs) else: print(f"[INFO] [{module_name}]", *args) @@ -217,7 +217,7 @@ def log_info(*args, **kwargs): def log_warn(*args, **kwargs): module_name = _resolve_module_name(stack_depth=2) if _initialized: - kwargs.setdefault("stacklevel", 3) + kwargs.setdefault("stacklevel", 4) warn(module_name, *args, **kwargs) else: print(f"[WARN] [{module_name}]", *args) @@ -226,7 +226,7 @@ def log_warn(*args, **kwargs): def log_error(*args, **kwargs): module_name = _resolve_module_name(stack_depth=2) if _initialized: - kwargs.setdefault("stacklevel", 3) + kwargs.setdefault("stacklevel", 4) error(module_name, *args, **kwargs) else: print(f"[ERROR] [{module_name}]", *args) @@ -235,7 +235,7 @@ def log_error(*args, **kwargs): def log_exception(*args): module_name = _resolve_module_name(stack_depth=2) if _initialized: - exception(module_name, *args, stacklevel=3) + exception(module_name, *args, stacklevel=4) else: print(f"[ERROR] [{module_name}]", *args) traceback.print_exc() diff --git a/core/log_system/logger.py b/core/log_system/logger.py index 6bfd06f..b403675 100644 --- a/core/log_system/logger.py +++ b/core/log_system/logger.py @@ -17,6 +17,7 @@ import sys import json import re import logging +import time from enum import IntEnum from logging.handlers import RotatingFileHandler import traceback @@ -46,6 +47,7 @@ COLORS = { LogLevel.INFO: "\033[94m", # Blue LogLevel.WARN: "\033[93m", # Yellow LogLevel.ERROR: "\033[91m", # Red + "MESSAGE": "\033[96m", # Cyan "RESET": "\033[0m", # Reset } @@ -59,8 +61,8 @@ DEFAULT_CONFIG = { "max_file_size_mb": 10, "backup_count": 5, "timestamp_format": "%H:%M:%S", - "level_field_width": 9, - "source_field_width": 72, + "level_field_width": 5, + "source_field_width": 0, } @@ -86,25 +88,18 @@ class ColoredFormatter(logging.Formatter): if record.exc_info: message += "\n" + self.formatException(record.exc_info) - levelname = record.levelname - level = f"[{levelname}]".center(self.level_field_width) - source = f"[{record.name}:{record.lineno}]".ljust(self.source_field_width) + levelname = self._display_level_name(record.levelname) + level = levelname.ljust(self.level_field_width) + logger_name = self._display_logger_name(record.name) + source = f"({logger_name}:{record.lineno})" + if self.source_field_width: + source = source.ljust(self.source_field_width) - # Build the log prefix - prefix = "[{}] {} {}".format( - self.formatTime(record, self.datefmt), - level, - source, - ) + if self.use_colors: + level = self._color_level(levelname, level) + message = f"{COLORS['MESSAGE']}{message}{COLORS['RESET']}" - # Apply color and bold styling to the prefix - if self.use_colors and hasattr(LogLevel, levelname): - level_enum = getattr(LogLevel, levelname) - if level_enum in COLORS: - # Apply bold (\033[1m) and color, then reset - prefix = f"\033[1m{COLORS[level_enum]}{prefix}{COLORS['RESET']}" - - return f"{prefix} {message}" + return f"[{self._format_time(record)}] {level} {source}: {message}" def _field_width(self, value): try: @@ -112,6 +107,25 @@ class ColoredFormatter(logging.Formatter): except (TypeError, ValueError): return 0 + def _display_logger_name(self, name): + return str(name or "").removeprefix("azlogs.") + + def _display_level_name(self, levelname): + return "WARN" if levelname == "WARNING" else str(levelname or "") + + def _format_time(self, record): + timestamp = time.strftime( + self.datefmt or "%H:%M:%S", self.converter(record.created) + ) + return f"{timestamp}.{int(record.msecs):03d}" + + def _color_level(self, levelname, text): + level_enum = getattr(LogLevel, levelname, None) + color = COLORS.get(level_enum) + if not color: + return text + return f"\033[1m{color}{text}{COLORS['RESET']}" + class AzLogsLogger: """Main logger class for AzLogs"""