Why Use Logging Instead of Print?
As a Technical Lead, you know that print() is for development, but Logging is for production. When your Flutter backend is running on a remote server, you can't see the standard output. The logging module provides a flexible framework for emitting log messages from Python programs, allowing you to categorize events by severity and direct them to different destinations (files, consoles, or external monitoring services).
- Log Levels (Severity)
Logging levels allow you to filter the importance of the information being recorded. In production, you might only care about 'Error' and 'Critical', while in development, you want 'Debug' information.
| Level | Numeric Value | Usage |
|---|---|---|
| DEBUG | 10 | Detailed info for diagnosing problems |
| INFO | 20 | Confirmation that things are working as expected |
| WARNING | 30 | Indication that something unexpected happened (Default) |
| ERROR | 40 | A more serious problem; the software couldn't perform a function |
| CRITICAL | 50 | A serious error; the program itself may be unable to continue |
- The Logging Architecture
The logging flow involves three main objects: Loggers (the entry point), Handlers (where the log goes), and Formatters (how the log looks).
- Advanced Handlers
For enterprise applications, you don't want a single text file that grows to several gigabytes. You should use specialized handlers:
- RotatingFileHandler: Automatically 'rolls over' the log file when it reaches a certain size.
- TimedRotatingFileHandler: Rotates logs at specific time intervals (e.g., every midnight).
- StreamHandler: Sends logs to the console (useful for Docker/Container logs).
- SMTPHandler: Sends an email when a 'CRITICAL' error occurs.
Best Practices for Architecture
Always use __name__ when creating a logger: logger = logging.getLogger(__name__). This ensures the log message shows exactly which module produced the error, making debugging significantly easier in complex microservices.