4.0 KiB
4.0 KiB
Logging Guidelines
How logging is done in this project.
Overview
Backend uses structlog integrated with stdlib logging configuration.
Evidence:
- Logger factory:
backend/src/core/logging/logger.py - Logging config and processors:
backend/src/core/logging/config.py - Formatter/JSON pipeline:
backend/src/core/logging/formatters.py - Request context middleware:
backend/src/core/logging/middleware.py - Runtime usage examples:
backend/src/app.py,backend/src/v1/todo/service.py
Log Levels
Observed level usage:
debug: low-level diagnostic events (e.g., JWT success branch)backend/src/v1/users/dependencies.py
info: normal lifecycle and business eventsbackend/src/app.py(startup/initialized)backend/src/v1/todo/service.py(todo_created,todo_updated, etc.)
warning: recoverable issues, unauthorized attempts, validation problemsbackend/src/app.py(HTTP and validation warnings)backend/src/v1/todo/service.py(unauthorized operations)
error/exception: failures needing investigationbackend/src/app.py(logger.exception("Unhandled error"))- repositories with
logger.exception(...)before re-raise
Structured Logging
Conventions from current setup:
- Always obtain logger through
core.logging.get_logger(...). - Use structured fields (keyword args / bound context), not string interpolation only.
- Request-level context can be attached by
RequestContextMiddleware(request_id,method,path,client_ip,user_id) when the middleware is mounted. - JSON output is enabled by default (
runtime.log_json = True), with fallback plain formatter supported.
Examples:
backend/src/core/logging/middleware.pybinds and propagates request context (middleware implementation)backend/src/core/logging/config.pyconfigures processors and handlersbackend/tests/integration/test_fastapi_logging_integration.pymounts the middleware in test FastAPI app and asserts context fields in emitted logs
Current wiring note:
backend/src/app.pycurrently does not callapp.add_middleware(RequestContextMiddleware); treat middleware context fields as opt-in wiring, not guaranteed global behavior.
What to Log
Log these consistently:
- Service lifecycle events (startup/shutdown/init failures)
backend/src/app.pybackend/src/services/base/service_interface.py
- Security/auth failures and unauthorized access attempts
backend/src/v1/users/dependencies.pybackend/src/v1/todo/service.py
- Database or external dependency failures with stable context fields
backend/src/v1/*/repository.pypatternsbackend/src/services/base/{redis.py,supabase.py}
What NOT to Log
Sensitive data should be redacted; avoid raw secrets/tokens/credentials.
Evidence:
- Sensitive field defaults in
backend/src/core/config/settings.py(password,token,authorization, etc.) - Redaction processor tests:
backend/tests/unit/test_logging_filters.pybackend/tests/unit/test_logging_config.py
Avoid logging:
- Raw access tokens / refresh tokens / cookies
- Passwords, API keys, secret values
- Full untrusted payload dumps containing PII
Anti-patterns / Forbidden Patterns
- Do not use
print()in backend runtime code; use project logger APIs.- Rule source:
backend/AGENTS.md
- Rule source:
- Do not bypass logging config by ad-hoc logger setup in feature modules.
- Use
configure_logging(...)frombackend/src/core/logging/config.py.
- Use
- Do not log sensitive fields without redaction.
- Do not assume request context fields exist unless
RequestContextMiddlewareis explicitly mounted.
Uncertainties (documented, not invented)
- This repo has tests for logging behavior and redaction, but no single documented required schema for every log event across all modules (beyond context fields and processor output).
core.logging.middleware.register_exception_handlers(...)exists but app-level error handling is primarily inbackend/src/app.py; effective production wiring should remain explicit per app bootstrap.