Skip to content

feat(logging): implement comprehensive logging infrastructure with loguru#794

Merged
seapagan merged 9 commits intomainfrom
feature/comprehensive-logging
Dec 29, 2025
Merged

feat(logging): implement comprehensive logging infrastructure with loguru#794
seapagan merged 9 commits intomainfrom
feature/comprehensive-logging

Conversation

@seapagan
Copy link
Owner

@seapagan seapagan commented Dec 29, 2025

Summary

Implemented a comprehensive logging infrastructure using loguru with categorical logging support, replacing the basic print-based logging system.

Key Features

  • Categorical Logging System: Flag-based logging categories (REQUESTS, AUTH, DATABASE, EMAIL, ERRORS, ADMIN, API_KEYS)
  • CategoryLogger Wrapper: Custom logger wrapper that filters logs by category
  • LoggingMiddleware: HTTP request/response logging middleware
  • Flexible Configuration: Configure via environment variables (log path, level, rotation, retention, compression, categories)
  • 100% Test Coverage: Comprehensive test suite for all logging components

Changes

New Files

  • app/config/log_config.py - LogConfig and LogCategory Flag enum
  • app/logs.py - CategoryLogger wrapper class
  • app/middleware/logging_middleware.py - HTTP logging middleware
  • tests/unit/test_logging.py - 14 comprehensive tests for logging infrastructure

Modified Files

  • app/main.py - Initialize logging and add middleware
  • app/managers/user.py - Add logging for user operations (register, login, delete, update, ban, role changes)
  • app/managers/email.py - Add logging for email operations
  • app/managers/auth.py - Add logging for authentication operations
  • app/config/settings.py - Add logging configuration settings
  • pyproject.toml - Add loguru dependency, disable PLE1205 for test files
  • tests/unit/test_email_manager.py - Add exception handling test

Configuration

New environment variables:

  • LOG_PATH - Log file location (default: ./logs)
  • LOG_LEVEL - Minimum log level (default: INFO)
  • LOG_ROTATION - When to rotate logs (default: 1 day)
  • LOG_RETENTION - How long to keep logs (default: 30 days)
  • LOG_COMPRESSION - Compression format (default: zip)
  • LOG_CATEGORIES - Comma-separated categories or ALL/NONE (default: ALL)

Test Coverage

All logging files now have 100% coverage:

  • app/config/log_config.py: 86% → 100%
  • app/logs.py: 90% → 100%
  • app/managers/email.py: 91% → 100%
  • app/middleware/logging_middleware.py: 94% → 100%

✅ All 515 tests passing
✅ All linting and type checking passing

Example Usage

from app.logs import LogCategory, category_logger

# Logs only if DATABASE category is enabled
category_logger.info("User created: user@example.com", LogCategory.DATABASE)

# Logs only if AUTH category is enabled
category_logger.warning("Failed login attempt", LogCategory.AUTH)

🤖 Generated with Claude Code

Add comprehensive structured logging throughout the application with
granular category-based control:

- **New logging system**:
  - Loguru-based logging with automatic rotation, retention, and
compression
  - Category-based control (REQUESTS, AUTH, DATABASE, EMAIL, ERRORS,
ADMIN, API_KEYS)
  - Console and file logging with different formats
  - Lazy initialization to avoid circular dependencies

- **Middleware**: HTTP request/response logging (uvicorn-compatible
format)

- **Manager logging**:
  - Auth: Token operations, authentication attempts, password resets
  - User: Registration, login, CRUD operations, role/ban changes
  - Email: Sending operations with success/failure tracking
  - API Keys: Creation, deletion, authentication events

- **Configuration**: All settings configurable via .env (path, level,
rotation, retention, categories)

- **Documentation**: Updated .env.example with detailed logging
configuration options
Reverted bootstrap code (helpers.py, main.py) to use standard logging
for pytest caplog compatibility. Fixed auth.py to use try/except/else
pattern for TRY300 compliance and safe user.id access with getattr for
test compatibility.
… complexity warnings

Created a CategoryLogger wrapper class that encapsulates the
category-enabled check, removing the need for if-statements in calling
code. This reduces cyclomatic complexity while maintaining the same
logging functionality.

All 500+ tests passing. All ruff checks passing (including removal of 4
C901 warnings).
…ture

Created new test file test_logging.py with 14 tests covering:
- LogCategory Flag enum operations and bitwise combinations
- LogConfig category parsing (NONE, comma-separated, invalid, mixed
case)
- CategoryLogger wrapper methods (info, error, warning, debug)
- LoggingMiddleware HTTP request logging

Updated test_email_manager.py with exception handling test for
simple_send.
Updated pyproject.toml to ignore PLE1205 for test files (false
positive).

Coverage improvements:
- app/config/log_config.py: 86% → 100%
- app/logs.py: 90% → 100%
- app/managers/email.py: 91% → 100%
- app/middleware/logging_middleware.py: 94% → 100%

All 515 tests passing.
@seapagan seapagan changed the title test(logging): add comprehensive test coverage for logging infrastructure feat(logging): implement comprehensive logging infrastructure with loguru Dec 29, 2025
@codacy-production
Copy link

codacy-production bot commented Dec 29, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.00% (target: -1.00%) 100.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (f2daeee) 1736 1736 100.00%
Head commit (7468186) 1909 (+173) 1909 (+173) 100.00% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#794) 192 192 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Implemented LOG_FILENAME setting to allow customization of log file
names,
enabling clean separation between test and production logs.

Changes:
- Added log_filename setting to Settings class (default: "api.log")
- Updated LogConfig to read and validate log_filename
- Added path separator validation to prevent directory traversal attacks
- Configured pytest to use "test_api.log" via environment variable
- Updated .env.example with LOG_FILENAME documentation
- Updated test mocks to include log_filename attribute

Features:
- Tests automatically write to ./logs/test_api.log
- Production/dev writes to ./logs/api.log (default)
- Customizable via LOG_FILENAME environment variable
- Security: validates filename doesn't contain path separators
- Follows existing settings pattern (log_path, log_level, etc.)

All 515 tests passing.
Added tests to cover path separator validation in log_filename setting,
improving coverage for app/config/log_config.py from 60% to 80%.

Tests added:
- test_log_filename_with_forward_slash_raises_error: Validates "/"
rejection
- test_log_filename_with_backslash_raises_error: Validates "\\"
rejection

Coverage improvements:
- app/config/log_config.py: 60% → 80% (lines 49-53 now covered)

All 517 tests passing.
…nt guide

Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Made loguru console logging optional and disabled by default to
eliminate
duplicate console output with FastAPI/Uvicorn's built-in logging.

Changes:
- Added log_console_enabled setting (default: False) to Settings
- Modified setup_logging() to conditionally add console handler
- Updated .env.example with LOG_CONSOLE_ENABLED documentation
- File logging always enabled regardless of console setting

Tests added:
- test_console_logging_disabled_by_default: Verifies config reads False
default
- test_console_logging_can_be_enabled: Verifies config reads True when
set
- test_setup_logging_skips_console_when_disabled: Verifies console
handler
  NOT added when disabled (default behavior)
- test_setup_logging_adds_console_when_enabled: Verifies console handler
  IS added when enabled, confirming sys.stderr as first handler

Coverage improvements:
- app/config/log_config.py: Lines 87-93 now covered (conditional console
handler)

Updated existing test mocks to include log_console_enabled=False for
consistency.

All 521 tests passing.
…tation

Added detailed documentation for all Admin Pages and Logging environment
variables to docs/usage/configuration/environment.md.

Admin Pages Configuration (5 variables):
- ADMIN_PAGES_ENABLED: Enable/disable admin panel
- ADMIN_PAGES_ROUTE: Customize admin panel route
- ADMIN_PAGES_TITLE: Customize browser/page title
- ADMIN_PAGES_ENCRYPTION_KEY: Session encryption key (with security
warnings)
- ADMIN_PAGES_TIMEOUT: Session timeout configuration

Logging Configuration (8 variables):
- LOG_PATH: Log output directory
- LOG_LEVEL: Logging verbosity (DEBUG/INFO/WARNING/ERROR/CRITICAL)
- LOG_ROTATION: When to rotate log files
- LOG_RETENTION: How long to keep old logs
- LOG_COMPRESSION: Compression format for rotated logs
- LOG_CATEGORIES: Fine-grained category control
(ALL/NONE/REQUESTS/AUTH/etc.)
- LOG_FILENAME: Custom log filename
- LOG_CONSOLE_ENABLED: Enable console output (with duplicate warning)

Documentation includes:
- Clear explanations for each setting
- Security warnings for sensitive settings (encryption key)
- Multiple practical configuration examples (dev, production, minimal)
- Production recommendations for LOG_CATEGORIES
- Troubleshooting section for common issues
- Cross-references to admin-panel.md

Added ~380 lines of comprehensive documentation following existing
style.
@seapagan seapagan force-pushed the feature/comprehensive-logging branch from 183037f to 7468186 Compare December 29, 2025 22:18
@seapagan seapagan self-assigned this Dec 29, 2025
@seapagan seapagan added the enhancement New feature or request label Dec 29, 2025
@seapagan seapagan merged commit c9e0f71 into main Dec 29, 2025
17 checks passed
@seapagan seapagan deleted the feature/comprehensive-logging branch December 29, 2025 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant