builder_peppermint_void/builder/configs/logger_config.py
2025-04-25 12:38:42 +00:00

136 lines
5.1 KiB
Python

# -*- coding: utf-8 -*-
"""
SPDX-FileCopyrightText: 2023-2025 PeppermintOS Team
(peppermintosteam@proton.me)
SPDX-License-Identifier: GPL-3.0-or-later
This module sets up the logging system used throughout the PeppermintOS Builder project.
It provides functionalities to record messages at different severity levels (DEBUG, INFO, WARNING, ERROR, CRITICAL)
both to the console (with colors for better visualization) and to a rotating log file.
The main objective of this module is to provide a centralized and configurable way to track the execution
of the builder, facilitating debugging and monitoring of the ISO building process.
Credits:
- PeppermintOS Team (peppermintosteam@proton.me) - Development and maintenance of the project.
License:
This code is distributed under the GNU General Public License version 3 or later (GPL-3.0-or-later).
For more details, please refer to the LICENSE file included in the project or visit:
https://www.gnu.org/licenses/gpl-3.0.html
"""
import logging
from logging.handlers import RotatingFileHandler
import sys
import os
from pathlib import Path
# Define color codes as constants for readability and maintainability
COLOR_DEBUG = '\033[94m' # Blue
COLOR_INFO = '\033[92m' # Green
COLOR_WARNING = '\033[93m' # Yellow
COLOR_ERROR = '\033[91m' # Red
COLOR_CRITICAL = '\033[95m' # Magenta
COLOR_RESET = '\033[0m'
def supports_color():
"""Check if the system supports color output in the terminal."""
return hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
class ColorFormatter(logging.Formatter):
"""A custom log formatter that adds colors to messages based on the severity level."""
level_colors = {
logging.DEBUG: COLOR_DEBUG,
logging.INFO: COLOR_INFO,
logging.WARNING: COLOR_WARNING,
logging.ERROR: COLOR_ERROR,
logging.CRITICAL: COLOR_CRITICAL,
}
def __init__(self, fmt=None, datefmt=None, style='%'):
"""
Initializes the color formatter.
Args:
fmt (str, optional): Format string for the log message. Defaults to None.
datefmt (str, optional): Format string for the date and time. Defaults to None.
style (str, optional): Formatting style ('%', '{' or '$'). Defaults to '%'.
"""
super().__init__(fmt=fmt, datefmt=datefmt, style=style)
def format(self, record):
"""
Formats a log record, adding colors if the terminal supports it.
Args:
record (logging.LogRecord): The log record to be formatted.
Returns:
str: The formatted log message.
"""
message = super().format(record)
if supports_color():
color = self.level_colors.get(record.levelno, COLOR_RESET)
message = f"{color}{message}{COLOR_RESET}"
return message
def setup_logger(builder, log_filename='builder.log', log_level=logging.DEBUG):
"""
Sets up the logger for the builder with the following features:
- Logger name based on the 'builder' argument.
- Specified logging level.
- Handler for the console (StreamHandler) with colored formatting.
- Handler for a rotating log file (RotatingFileHandler) without colored formatting.
- The log file is stored in "~/logs/".
Args:
builder (str): The name of the logger (usually the module or component name).
log_filename (str, optional): The name of the log file. Defaults to 'builder.log'.
log_level (int, optional): The logging level to be used (e.g., logging.DEBUG, logging.INFO). Defaults to logging.DEBUG.
Returns:
logging.Logger: The configured logger object.
"""
logger = logging.getLogger(builder)
logger.setLevel(log_level)
# Basic format for the file logger, customized formatting for the console logger
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_formatter = ColorFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# Configuration for the console handler
console_handler = logging.StreamHandler()
console_handler.setLevel(log_level)
console_handler.setFormatter(console_formatter)
# Configuration for the rotating file handler
log_file = Path(os.path.expanduser("~")) / 'logs' / log_filename
log_dir = log_file.parent
log_dir.mkdir(parents=True, exist_ok=True) # Ensure the log directory exists
file_handler = RotatingFileHandler(
log_file, maxBytes=1024 * 1024, backupCount=5, encoding='utf-8')
file_handler.setLevel(log_level)
file_handler.setFormatter(file_formatter)
# Add the handlers to the logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
# Determine the log level from the environment variable or use the default (DEBUG)
log_level_str = os.environ.get("PEPPERMINT_BUILDER_LOG_LEVEL", "DEBUG").upper()
try:
log_level = getattr(logging, log_level_str)
except AttributeError:
log_level = logging.DEBUG
print(f"Invalid log level '{log_level_str}' in environment variable. Using DEBUG.")
# Variables Arguments used for the logger setUp for all files.
builder_logger = setup_logger('builder', 'builder.log', log_level)