Download behavior_backend/app/utils/logging_utils.py from urjob/test: direct link, hf CLI and curl.
- Browser
- Download file 8.95 kB
-
https://huggingface.co/spaces/urjob/test/resolve/main/behavior_backend/app/utils/logging_utils.py
- Command line
-
hf download hf://spaces/urjob/test/behavior_backend/app/utils/logging_utils.py
-
curl -L -o logging_utils.py https://huggingface.co/spaces/urjob/test/resolve/main/behavior_backend/app/utils/logging_utils.py
8.95 kB
| import logging | |
| import time | |
| import csv | |
| import os | |
| from pathlib import Path | |
| from datetime import datetime | |
| """ | |
| Logging Utilities Module | |
| ======================== | |
| This module provides enhanced logging capabilities for the behavior analytics application. | |
| Features include: | |
| - Emoji-enhanced log messages for better visual identification | |
| - Daily log file rotation with date-based filenames | |
| - Dual logging to both console and files | |
| - Performance timing and measurement utilities | |
| - Custom log levels and formatting | |
| Usage: | |
| ------ | |
| # Basic setup with both console and file logging | |
| logger = setup_logger("my_module") | |
| # Log at different levels with automatic emoji inclusion | |
| logger.debug("Debugging information") | |
| logger.info("General information") | |
| logger.warning("Warning message") | |
| logger.error("Error occurred") | |
| logger.critical("Critical failure") | |
| # Log success messages with checkmark emoji | |
| log_success(logger, "Operation completed successfully") | |
| # Measure function execution time | |
| @time_it | |
| def my_function(): | |
| # Function code here | |
| pass | |
| """ | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
| logger = logging.getLogger(__name__) | |
| # Create logs directory if it doesn't exist | |
| logs_dir = Path("logs") | |
| logs_dir.mkdir(exist_ok=True) | |
| # Time logs file | |
| TIME_LOGS_FILE = logs_dir / "time_logs.csv" | |
| # Emoji mappings for different log levels | |
| LOG_EMOJIS = { | |
| 'DEBUG': 'debug', | |
| 'INFO': 'info', | |
| 'WARNING': 'warning', | |
| 'ERROR': 'error', | |
| 'CRITICAL': 'critical', | |
| 'SUCCESS': 'success', | |
| 'TIMER': 'timer' | |
| } | |
| def get_daily_log_filename(base_name="app"): | |
| """ | |
| Generate a log filename with the current date. | |
| The function creates a filename in the format: {base_name}_{YYYY-MM-DD}.log | |
| This ensures that logs are automatically separated by day, making it easier | |
| to manage log files and implement log rotation policies. | |
| Args: | |
| base_name (str): Base name for the log file, defaults to "app" | |
| Returns: | |
| Path: Path object for the log file with current date | |
| Example: | |
| >>> get_daily_log_filename("api") | |
| Path('logs/api_2023-11-15.log') | |
| """ | |
| today = datetime.now().strftime("%Y-%m-%d") | |
| return logs_dir / f"{base_name}_{today}.log" | |
| def setup_logger(name, log_file=None, level=logging.INFO, enable_console=True, enable_file=True): | |
| """ | |
| Set up a logger with file and console handlers. | |
| This function configures a logger with the specified name and adds handlers for | |
| console output and/or file output based on the parameters. It also adds emoji | |
| support to make logs more visually informative. | |
| Args: | |
| name (str): Logger name, typically the module name using __name__ | |
| log_file (str, optional): Path to log file. If None and enable_file is True, | |
| a daily log file will be used. Defaults to None. | |
| level (int): Logging level (e.g., logging.INFO, logging.DEBUG). | |
| Defaults to logging.INFO. | |
| enable_console (bool): Whether to enable console logging. Defaults to True. | |
| enable_file (bool): Whether to enable file logging. Defaults to True. | |
| Returns: | |
| logging.Logger: Configured logger instance | |
| Example: | |
| >>> # Basic usage with both console and file logging | |
| >>> logger = setup_logger("my_module") | |
| >>> | |
| >>> # Console only (no file logging) | |
| >>> logger = setup_logger("console_only", enable_file=False) | |
| >>> | |
| >>> # File only with custom file path | |
| >>> logger = setup_logger("file_only", log_file="custom.log", enable_console=False) | |
| """ | |
| logger = logging.getLogger(name) | |
| logger.setLevel(level) | |
| # Remove existing handlers if any | |
| for handler in logger.handlers[:]: | |
| logger.removeHandler(handler) | |
| # Format with emojis | |
| log_format = '%(asctime)s - %(name)s - %(emoji)s %(levelname)s - %(message)s' | |
| # Create a filter to add emoji to the record | |
| class EmojiFilter(logging.Filter): | |
| """ | |
| Filter that adds an emoji field to the log record based on the log level. | |
| This filter enriches log records with emojis corresponding to their log levels, | |
| making logs more visually informative and easier to scan. | |
| """ | |
| def filter(self, record): | |
| """ | |
| Add an emoji attribute to the log record. | |
| Args: | |
| record (LogRecord): The log record to filter | |
| Returns: | |
| bool: Always returns True to include the record | |
| """ | |
| record.emoji = LOG_EMOJIS.get(record.levelname, '') | |
| return True | |
| # Create console handler | |
| if enable_console: | |
| console_handler = logging.StreamHandler() | |
| console_handler.setLevel(level) | |
| console_formatter = logging.Formatter(log_format) | |
| console_handler.setFormatter(console_formatter) | |
| console_handler.addFilter(EmojiFilter()) | |
| logger.addHandler(console_handler) | |
| # Create file handler | |
| if enable_file: | |
| # Use provided log_file or generate daily log file | |
| file_path = log_file if log_file else get_daily_log_filename() | |
| file_handler = logging.FileHandler(file_path) | |
| file_handler.setLevel(level) | |
| file_formatter = logging.Formatter(log_format) | |
| file_handler.setFormatter(file_formatter) | |
| file_handler.addFilter(EmojiFilter()) | |
| logger.addHandler(file_handler) | |
| return logger | |
| def log_time(function_name, time_taken): | |
| """ | |
| Log the time taken by a function to a CSV file and to the logger. | |
| This function records performance metrics for functions, storing them in a CSV file | |
| for later analysis and also outputting them to the log with a timer emoji. | |
| Args: | |
| function_name (str): Name of the function being timed | |
| time_taken (float): Time taken in seconds | |
| Example: | |
| >>> log_time("process_video", 2.345) | |
| # Writes to CSV and logs: "⏱️ Function process_video took 2.3450 seconds" | |
| """ | |
| # Create file with headers if it doesn't exist | |
| if not os.path.exists(TIME_LOGS_FILE): | |
| with open(TIME_LOGS_FILE, 'w', newline='') as f: | |
| writer = csv.writer(f) | |
| writer.writerow(['timestamp', 'function', 'time_taken_seconds']) | |
| # Append time log | |
| with open(TIME_LOGS_FILE, 'a', newline='') as f: | |
| writer = csv.writer(f) | |
| writer.writerow([datetime.now().isoformat(), function_name, time_taken]) | |
| logger.info(f"{LOG_EMOJIS['TIMER']} Function {function_name} took {time_taken:.4f} seconds") | |
| def time_it(func): | |
| """ | |
| Decorator to measure and log the execution time of a function. | |
| This decorator wraps a function to measure its execution time and automatically | |
| log the results using the log_time function. It's a convenient way to add | |
| performance monitoring to any function. | |
| Args: | |
| func (callable): The function to decorate | |
| Returns: | |
| callable: A wrapped function that logs its execution time | |
| Example: | |
| >>> @time_it | |
| >>> def process_data(data): | |
| >>> # Process data here | |
| >>> return result | |
| >>> | |
| >>> # When called, will automatically log execution time | |
| >>> result = process_data(my_data) | |
| """ | |
| def wrapper(*args, **kwargs): | |
| """ | |
| Wrapper function that times the execution of the decorated function. | |
| Args: | |
| *args: Arguments to pass to the decorated function | |
| **kwargs: Keyword arguments to pass to the decorated function | |
| Returns: | |
| Any: The return value of the decorated function | |
| """ | |
| start_time = time.time() | |
| result = func(*args, **kwargs) | |
| end_time = time.time() | |
| time_taken = end_time - start_time | |
| log_time(func.__name__, time_taken) | |
| return result | |
| return wrapper | |
| def log_success(logger, message, *args, **kwargs): | |
| """ | |
| Log a success message with a checkmark emoji. | |
| This function provides a convenient way to log successful operations with | |
| a distinctive checkmark emoji, making success messages stand out in the logs. | |
| Args: | |
| logger (logging.Logger): Logger instance to use | |
| message (str): Message to log | |
| *args: Additional positional arguments for logger.info | |
| **kwargs: Additional keyword arguments for logger.info | |
| Example: | |
| >>> logger = setup_logger("my_module") | |
| >>> log_success(logger, "User registration completed for user_id={}", user_id) | |
| # Logs: "✅ User registration completed for user_id=123" | |
| """ | |
| logger.info(f"{LOG_EMOJIS['SUCCESS']} {message}", *args, **kwargs) |