Skip to content

app_logging.py - Centralized Logging Configuration System

Purpose

Provides centralized, repeat-safe logging configuration for the ReViewPoint backend using Loguru as the primary logging framework. This module handles initialization of logging infrastructure with support for console output, file logging, JSON formatting, and seamless integration with standard Python logging while maintaining compatibility with testing frameworks.

Key Components

Core Functionality

init_logging() Function

  • Purpose: Main entry point for configuring the application's logging system
  • Design: Repeat-safe initialization that can be called multiple times without side effects
  • Features: Console/file output, JSON formatting, color support, test environment detection
  • Integration: Replaces Python's standard logging with Loguru while maintaining compatibility

Environment Detection

  • Purpose: Automatically detects testing environments to prevent file logging conflicts
  • Implementation: Multi-method detection using environment variables, sys.modules, and command-line arguments
  • Benefits: Prevents file handle conflicts during parallel test execution

Color Management

  • Purpose: Provides ANSI color codes for different log levels
  • Implementation: Immutable mapping with predefined color schemes
  • Usage: Enhances console readability with color-coded log levels

Technical Architecture

Loguru Integration

# Centralized logging configuration
from core.app_logging import init_logging

# Initialize with development settings
init_logging(level="DEBUG", color=True, json_format=False, logfile="app.log")

# Use in modules
from loguru import logger
logger.info("Application started")

Handler Management

class InterceptHandler(logging.Handler):
    """Intercepts standard logging calls and routes them to Loguru"""
    def emit(self, record: logging.LogRecord) -> None:
        # Convert standard logging to Loguru format
        # Maintains proper stack depth for accurate source location
        # Preserves exception information

Test Environment Handling

def _is_testing() -> bool:
    """Multi-method test environment detection"""
    return (
        "PYTEST_CURRENT_TEST" in os.environ or  # Pytest environment variable
        "pytest" in sys.modules or             # Pytest module loaded
        any("test" in arg.lower() for arg in sys.argv)  # Command line detection
    )

Dependencies

External Libraries

  • loguru: Primary logging framework providing structured, colored logging
  • pathlib: Modern path handling for log file creation
  • logging: Standard library integration for third-party compatibility

Internal Dependencies

  • No internal dependencies: Standalone module to prevent circular imports
  • Core module: Foundation for all other backend logging needs

Configuration Integration

  • Environment detection: Automatic test environment handling
  • File management: Safe log file creation with directory structure handling

Integration Patterns

Application Startup

# In main.py or application initialization
from core.app_logging import init_logging

def create_app():
    # Initialize logging first, before other components
    init_logging(
        level=settings.LOG_LEVEL,
        color=not settings.JSON_LOGS,
        json_format=settings.JSON_LOGS,
        logfile=settings.LOG_FILE
    )
    # Continue with app setup...

Module Usage Pattern

# In any backend module
from loguru import logger

def some_function():
    logger.info("Function called")
    try:
        # Business logic
        logger.debug("Processing data")
    except Exception as e:
        logger.error(f"Error occurred: {e}")
        raise

Testing Integration

# Automatic test environment detection prevents file logging
# Pytest handlers remain intact for test capturing
# Colors and formatting maintained for test readability

def test_with_logging():
    logger.info("Test message")  # Captured by pytest
    assert some_condition()

Configuration Options

Logging Levels

  • DEBUG: Detailed diagnostic information
  • INFO: General information messages (default)
  • WARNING: Warning messages for unusual conditions
  • ERROR: Error conditions that don't stop execution
  • CRITICAL: Critical errors that may stop execution

Output Formats

  • Human-readable: Colored, formatted output for development
  • JSON: Structured output for production log aggregation
  • Console: Standard output with optional colors
  • File: Persistent logging with UTF-8 encoding

Environment Adaptations

  • Development: Color output, debug level, file logging
  • Production: JSON format, structured output, centralized logging
  • Testing: Console only, pytest integration, no file conflicts

Error Handling

Initialization Safety

# Remove all existing loguru handlers safely
try:
    loguru_logger.remove()
except (ValueError, OSError):
    # Ignore errors during cleanup
    pass

File Logging Protection

# Optional file sink with test environment protection
if logfile is not None and not _is_testing():
    fp: Path = Path(logfile)
    fp.parent.mkdir(parents=True, exist_ok=True)  # Safe directory creation
    loguru_logger.add(str(fp), level=level, serialize=json_format, encoding="utf-8")

Handler Integration Robustness

# Safe level conversion with fallback
try:
    log_level = loguru_logger.level(record.levelname).name
except ValueError:
    log_level = str(record.levelno)  # Numeric fallback

Performance Considerations

Lazy Initialization

  • Repeat-safe: Multiple calls don't create duplicate handlers
  • Cleanup: Proper handler removal prevents memory leaks
  • Efficiency: Minimal overhead for logging operations

Test Performance

  • File avoidance: No file I/O during tests for faster execution
  • Handler preservation: Pytest handlers remain for test capturing
  • Memory management: Clean handler lifecycle

Production Optimization

  • JSON serialization: Efficient structured logging for log aggregation
  • Level filtering: Early filtering reduces processing overhead
  • Buffer management: Proper file buffering for high-throughput logging

Security Considerations

File System Safety

  • Directory creation: Safe creation of log directories with proper permissions
  • Path validation: Uses pathlib for safe file path handling
  • Encoding: UTF-8 encoding prevents character set issues

Information Disclosure

  • Level control: Appropriate log levels prevent sensitive information leakage
  • Test isolation: No file logging during tests prevents data exposure
  • Handler isolation: Clean separation between application and test logging

Usage Examples

Basic Initialization

from core.app_logging import init_logging

# Development setup
init_logging(level="DEBUG", color=True, logfile="debug.log")

# Production setup
init_logging(level="INFO", json_format=True, color=False)

# Testing setup (automatic detection)
init_logging(level="DEBUG")  # File logging automatically disabled

Advanced Configuration

# Environment-aware initialization
import os
from core.app_logging import init_logging

LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
JSON_LOGS = os.getenv("JSON_LOGS", "false").lower() == "true"
LOG_FILE = os.getenv("LOG_FILE", "app.log")

init_logging(
    level=LOG_LEVEL,
    json_format=JSON_LOGS,
    color=not JSON_LOGS,
    logfile=LOG_FILE if not JSON_LOGS else None
)

Module Integration

from loguru import logger

class UserService:
    def create_user(self, user_data):
        logger.info(f"Creating user: {user_data.email}")
        try:
            # User creation logic
            logger.debug("User validation passed")
            user = self.repository.create(user_data)
            logger.info(f"User created successfully: {user.id}")
            return user
        except ValueError as e:
            logger.warning(f"User creation failed: {e}")
            raise
        except Exception as e:
            logger.error(f"Unexpected error during user creation: {e}")
            raise

Testing Integration

Pytest Compatibility

# Automatic test detection maintains pytest log capturing
def test_logging_integration():
    from loguru import logger
    logger.info("Test message")  # Captured by pytest
    # Test assertions...

Log Testing

from loguru import logger
import pytest
from _pytest.logging import LogCaptureFixture

def test_service_logging(caplog: LogCaptureFixture):
    with caplog.at_level("INFO"):
        service.perform_operation()
        assert "Operation completed" in caplog.text

Migration Notes

From Standard Logging

# Old pattern
import logging
logger = logging.getLogger(__name__)
logger.info("Message")

# New pattern
from loguru import logger
logger.info("Message")

Configuration Migration

# Old logging.yaml configuration
# Replace with init_logging() calls in application startup
# Centralized configuration instead of external files

The app_logging.py module provides the foundation for all logging operations in the ReViewPoint backend, ensuring consistent, efficient, and test-friendly logging across the entire application while maintaining compatibility with existing Python logging ecosystem components.