import logging import sys from datetime import datetime class LocalTimeFormatter(logging.Formatter): """ Custom formatter to display time with milliseconds and a (UTC+HH) offset. """ def formatTime(self, record, datefmt=None): # Convert log record's creation time to a local, timezone-aware datetime object dt = datetime.fromtimestamp(record.created).astimezone() # Format the main time part time_part = dt.strftime('%Y-%m-%d %H:%M:%S') # Get the UTC offset and format it as (UTC+HH) offset = dt.utcoffset() offset_str = "" if offset is not None: offset_hours = int(offset.total_seconds() / 3600) sign = '+' if offset_hours >= 0 else '' offset_str = f" (UTC{sign}{offset_hours})" # --- FIX: Cast record.msecs from float to int before formatting --- # Combine time, milliseconds, and the offset string return f"{time_part},{int(record.msecs):03d}{offset_str}" def setup_logging(log_level: str, process_name: str): """ Configures logging for a process. Args: log_level: The desired logging level ('off', 'normal', 'debug'). process_name: The name of the current process for log formatting. """ level_map = { 'normal': logging.INFO, 'debug': logging.DEBUG, } if log_level == 'off': logging.getLogger().addHandler(logging.NullHandler()) return log_level_val = level_map.get(log_level.lower()) if log_level_val is None: print(f"Invalid log level '{log_level}'. Defaulting to 'normal'.") log_level_val = logging.INFO logger = logging.getLogger() if logger.hasHandlers(): logger.handlers.clear() handler = logging.StreamHandler(sys.stdout) # This will produce timestamps like: 2025-10-13 14:30:00,123 (UTC+2) formatter = LocalTimeFormatter( f'%(asctime)s - {process_name} - %(levelname)s - %(message)s' ) handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(log_level_val)