Last active
October 22, 2024 08:05
-
-
Save jakob1379/25939ebe487653c8f949bcacaa536c7d to your computer and use it in GitHub Desktop.
Simple setup for beautiful logging using Rich
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import logging | |
| import os | |
| from logging.handlers import RotatingFileHandler | |
| from typing import Literal | |
| from rich.logging import RichHandler | |
| def setup_logging( | |
| log_file: str = None, | |
| log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = None, | |
| log_max_size: int = None, | |
| ) -> None: | |
| """ | |
| Configures logging for console and file outputs with different handlers and formats. | |
| Args: | |
| log_file (str): The file path to store log outputs. Defaults to environment variable LOG_FILE or "application.log". | |
| log_level (Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]): The log level for both console and file handlers. Defaults to environment variable LOG_LEVEL or "DEBUG". | |
| log_max_size (int): Maximum size of the log file before it gets rotated. Defaults to environment variable LOG_MAX_SIZE or 5 MB. | |
| """ | |
| # Set log_file, log_level, and log_max_size from environment variables if not provided | |
| log_file = log_file or os.environ.get("LOG_FILE", "application.log") | |
| log_max_size = log_max_size or int(os.environ.get("LOG_MAX_SIZE", 5 * 1024 * 1024)) | |
| log_level = log_level or os.environ.get("LOG_LEVEL", "DEBUG").upper() | |
| log_level_numeric = getattr(logging, log_level, logging.DEBUG) | |
| # Root logger configuration | |
| logger = logging.getLogger() | |
| logger.setLevel(log_level_numeric) | |
| # Rich Handler for console with timestamp | |
| console_handler = RichHandler(rich_tracebacks=True, show_path=False) | |
| console_handler.setLevel(log_level_numeric) | |
| console_handler.setFormatter( | |
| logging.Formatter(fmt="[%(asctime)s] %(message)s", datefmt="%m/%d/%y %H:%M:%S") | |
| ) | |
| logger.addHandler(console_handler) | |
| # File handler configuration (with rotation) | |
| file_formatter = logging.Formatter( | |
| "%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)d] - %(message)s" | |
| ) | |
| file_handler = RotatingFileHandler(log_file, maxBytes=log_max_size, backupCount=5) | |
| file_handler.setLevel(log_level_numeric) | |
| file_handler.setFormatter(file_formatter) | |
| logger.addHandler(file_handler) | |
| if __name__ == "__main__": | |
| # Test logging configuration with different levels | |
| setup_logging() | |
| logging.debug("This is a debug message.") | |
| logging.info("This is an info message.") | |
| logging.warning("This is a warning message.") | |
| logging.error("This is an error message.") | |
| logging.critical("This is a critical message.") |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Debugging from stdout will look like this:

whilst the file output will be as expected: