Using print vs logging
Using print() vs. Logging in Python
When beginning their programming journey, almost all developers rely on print() statements to inspect variables and track program execution. While print() is convenient for quick one-line script checks, it quickly breaks down in production-grade software. Python's built-in logging module offers a professional, configurable alternative designed specifically for monitoring, diagnostics, and audit tracking.
1. Why print() Fails in Production
Using print() for debugging introduces several critical defects into software architecture:
- 1No Severity Distinction: An urgent database connection timeout looks identical to a routine informational message.
- 2Difficult to Turn Off: When moving to production, developers must search and manually comment out or delete dozens of
print()lines. - 3No Contextual Metadata:
print()lacks automatic timestamps, filenames, line numbers, and thread identifiers. - 4Output Destination Locked:
print()sends text exclusively to standard output (sys.stdout), whereas servers require structured log files, syslog daemons, or centralized monitoring services (e.g. Datadog, AWS CloudWatch).
2. Introducing Python's Built-in logging Module
Python provides the logging standard library module out of the box—no installation required.
Basic Setup with logging.basicConfig
Output Produced:
3. Writing Logs Directly to a File
By simply providing the filename argument, all log events are automatically appended to disk without modifying any of your business logic:
4. Modern Modular Logging: getLogger(__name__)
In multi-file modular applications, avoid calling the root logging.info() directly. Instead, instantiate a named logger per module using the module's __name__:
This pattern enables configuring distinct log levels for individual packages (e.g. keep your core database module at DEBUG while keeping external HTTP libraries at WARNING).
5. Architectural Comparison: print() vs. logging
| Feature | print() | Python logging Module |
|---|---|---|
| Intended Purpose | Displaying text directly to user | Diagnostic records, error auditing, monitoring |
| Categorization | None | 5 Standard Levels (DEBUG to CRITICAL) |
| Metadata | Manual string formatting | Automatic timestamp, file, function, line number |
| Redirection | Only stdout | Files, sockets, HTTP endpoints, email alerts |
| Toggling | Manual deletion/commenting | Single configuration flag (level=...) |
| Performance | Synchronous blocking I/O | Highly optimized, can be asynchronous/buffered |
Multiple Choice Questions
1. What is the primary disadvantage of using print() statements for debugging in production applications?
A. print() only supports ASCII characters B. print() cannot be toggled off globally, lacks timestamps/severity, and clutters stdout C. print() is deprecated in Python 3.12 D. print() causes memory leaks Answer: B Explanation: print() lacks severity categorization, automatic timestamps, and file routing, and requires manual code deletion before shipping to production.
2. Which function in the logging module is used to establish baseline formatting and logging levels?
A. logging.init() B. logging.configure() C. logging.basicConfig() D. logging.setup() Answer: C Explanation: logging.basicConfig(**kwargs) configures the root logger with formatting strings, log levels, and destination filenames.
3. What does %(asctime)s represent inside a logging format string?
A. The execution duration of the current function B. Human-readable creation time of the log record C. System CPU clock cycles D. The timezone offset Answer: B Explanation: %(asctime)s inserts the timestamp when the LogRecord was created.
4. What is the recommended way to create a module-level logger in modular Python applications?
A. logger = logging.new() B. logger = logging.getLogger(__name__) C. logger = logging.RootLogger() D. logger = logging.create_stream() Answer: B Explanation: logging.getLogger(__name__) creates or retrieves a logger identified by the current module path, facilitating hierarchical configuration.
5. If logging.basicConfig(level=logging.WARNING) is set, which of the following log calls will NOT produce any output?
A. logging.warning("Disk full") B. logging.error("Crash detected") C. logging.info("User logged in") D. logging.critical("Power outage") Answer: C Explanation: logging.INFO is of lower severity than WARNING, so all INFO and DEBUG calls are suppressed.
Logging Levels
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Project: Weather Data Fetcher | Logging Levels |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.