The Python logging module is the standard library facility used to track events, monitor application health, and debug problems instead of using print() statements. It provides features like log levels, custom formatting, and destinations like the console or log files.
Log Levels
- Python categorizes log logs by severity. By default, the system ignores logs below the WARNING level.
- When no log level is defined, the default log level is set to warning, so anything below warning (that is DEBUG, INFO) won't work.
Basic Configuration
import logging
logging.basicConfig(filename='sample.log',level= logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
def add(x,y):
return x + y
def subtract (x,y):
return x - y
logging.info(add(23,7))
logging.info(subtract(23,7))
Output
2026-11-06 15:06:04,927 - root - INFO - 30
2026-11-06 15:06:04,928 - root - INFO - 16
- The output of the logs are stored in sample.log file. This is where you can track events and debug problems.
- Format enables you to define how the logs will be written.
- The sample code above cannot use DEBUG level, because its below INFO. Otherwise WARNING, ERROR, CRITICAL can be used.
Production level configuration
-
__name__enables us to specify different loggings for different files even when imported, it still maintains and uses the defined configurations within the file.
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler = logging.FileHandler('class.log')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# logging.basicConfig(filename='class.log',level= logging.INFO,
# format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
class Employee:
def __init__(self, emp_name, emp_dept):
self.emp_name = emp_name
self.emp_dept = emp_dept
def info(self):
logger.info(f"{self.emp_name} works in {self.emp_dept} department")
emp1 = Employee("Lameck", "Data")
emp1.info()
Output:
2026-11-06 15:29:48,602 - __main__ - INFO - Lameck works in Data department
Log Streaming
- If you want to see the logs in the console and not in a specific file then we use
streamHandler()
# Create a logger named after the current module
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Create a console handler
console_handler = logging.StreamHandler()
# Define format
formatter = logging.Formatter('%(levelname)s: %(message)s')
console_handler.setFormatter(formatter)
# Add handler to the logger
logger.addHandler(console_handler)
def calculate_total(price = 3900, tax= 23):
logger.info("Starting total calculation...")
return price + (price * tax)
logger.info(calculate_total())
Output:
PS C:\Users\DELL\Documents\logging> python stream.py
INFO: Starting total calculation...
INFO: 93600
Handling Errors using Logging
- To log errors effectively in Python, we use the
logger.exception()method inside an except block. This automatically captures the full exception traceback alongside your custom message, which is essential for debugging.
import logging
logger = logging.getLogger(__name__)
try:
result = 10 / 0
except ZeroDivisionError:
# Automatically captures the complete stack trace at ERROR level
logger.exception("An error occurred while dividing numbers")
Conclusion
Python’s built-in logging module is the industry-standard tool for tracking application behavior, diagnosing bugs, and replacing brittle print() statements in production code. By utilizing hierarchical loggers, structured severity levels, and isolated handlers, it provides a flexible framework that scales easily from tiny scripts to massive microservices.

Top comments (0)