Of course! The phrase "python import logger" refers to using Python's built-in logging module. This is a fundamental and highly recommended practice for any Python application, whether it's a small script or a large-scale web service.

Here’s a complete guide covering everything from the basics to best practices.
The Basics: import logging
The first step is to import the module.
import logging
This gives you access to all the functions and classes needed for logging.
The Simplest Way: logging.basicConfig()
For a quick start, especially in scripts, you can configure the logger with basicConfig(). This sets up a default handler that prints messages to the console (standard error).

import logging
# --- Configure the basic settings ---
# level: The minimum severity of messages to be displayed.
# format: The layout of the log message.
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# --- Now, let's log some messages ---
# These messages will be displayed because their level is INFO or higher.
logging.debug("This is a debug message. It won't be shown.")
logging.info("This is an info message. It will be shown.")
logging.warning("This is a warning message. It will be shown.")
logging.error("This is an error message. It will be shown.")
logging.critical("This is a critical message. It will be shown.")
Output:
2025-10-27 10:30:00,123 - INFO - This is an info message. It will be shown.
2025-10-27 10:30:00,124 - WARNING - This is a warning message. It will be shown.
2025-10-27 10:30:00,125 - ERROR - This is an error message. It will be shown.
2025-10-27 10:30:00,126 - CRITICAL - This is a critical message. It will be shown.
Key Takeaway: The level=logging.INFO setting means that only messages with a severity of INFO or higher (WARNING, ERROR, CRITICAL) are processed. DEBUG is ignored.
Understanding Log Levels
The logging module has five standard levels, ordered by increasing severity. You can use these to filter your messages.
| Level | Numeric Value | Use Case |
|---|---|---|
DEBUG |
10 | Detailed information, typically of interest only when diagnosing problems. |
INFO |
20 | Confirmation that things are working as expected. |
WARNING |
30 | An indication that something unexpected happened, or a problem might occur soon (e.g., ‘disk space low’). The software is still working as expected. |
ERROR |
40 | Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
50 | A very serious error, indicating that the program itself may be unable to continue running. |
You can set the logging level to ignore messages below a certain threshold.

Understanding Log Message Format (format string)
The format string in basicConfig lets you customize what each log message looks like. It uses placeholders (like %()s) that get replaced by actual values.
Common placeholders:
%(asctime)s: The human-readable time when theLogRecordwas created.%(levelname)s: The text severity level of the message (DEBUG,INFO, etc.).%(message)s: The log message itself.%(name)s: The name of the logger (more on this later).%(funcName)s: The function name where the log call was made.%(lineno)d: The line number where the log call was made.
Example with a more detailed format:
import logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s'
)
logging.info("Application starting up...")
Output:
2025-10-27 10:35:00,456 - root - INFO - <module>:3 - Application starting up...
The Advanced Way: Loggers, Handlers, and Formatters
For larger applications, basicConfig is not enough. The power of the logging module comes from its flexible architecture:
- Loggers: Exposed in your application code. You create a logger for each part of your application (e.g., a module, a class). Loggers have a name (e.g.,
my_app.database). - Handlers: Send the log records to their destination. A logger can have multiple handlers. Examples:
StreamHandler: Prints to the console (likebasicConfigdoes).FileHandler: Writes logs to a file.RotatingFileHandler: Writes to a file and rotates it when it gets too big.SMTPHandler: Sends logs via email.
- Formatters: Define the layout of the log message. The same formatter can be used by multiple handlers.
Step-by-Step Example of Advanced Logging
Let's create a logger for a database module and send its logs to a file.
import logging
# 1. Create a logger with a specific name
logger = logging.getLogger('my_app.database')
logger.setLevel(logging.DEBUG) # Set the severity for this logger
# 2. Create a file handler to write logs to a file
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.WARNING) # Set the severity for this handler
# 3. Create a console handler to print to the screen
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.ERROR) # Only show errors and critical on console
# 4. Create a formatter and set it for both handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
# 5. Add the handlers to the logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)
# --- Now, use the logger ---
logger.debug("This is a debug message. It will be ignored by both handlers.")
logger.info("This is an info message. It will be ignored by both handlers.")
logger.warning("This is a warning. It will go to app.log but not the console.")
logger.error("This is an error. It will go to both app.log and the console.")
What happens:
app.logfile content:2025-10-27 10:40:00,789 - my_app.database - WARNING - This is a warning. It will go to app.log but not the console. 2025-10-27 10:40:00,790 - my_app.database - ERROR - This is an error. It will go to both app.log and the console.- Console output:
2025-10-27 10:40:00,790 - my_app.database - ERROR - This is an error. It will go to both app.log and the console.
This example shows how you can have different log levels for different handlers, giving you fine-grained control over your logging strategy.
Best Practices
-
Don't use the root logger directly. Always create a named logger using
logging.getLogger(__name__). Using__name__is a convention that gives you a logger named after the module (e.g.,my_project.my_module). This helps you identify where a log message came from.# In my_project/my_module.py import logging logger = logging.getLogger(__name__) logger.info("Doing something in my_module") -
Configure logging early. Configure your logging setup at the beginning of your application's entry point (e.g., in your main script or
__init__.py). Don't configure it inside library code, as this can conflict with the application's configuration. -
Use meaningful log levels.
INFO: For tracking the normal flow of the application (e.g., "User logged in," "Processing file X").WARNING: For unexpected but recoverable situations (e.g., "Deprecated function used," "File not found, using default").ERROR: For serious problems that prevent a part of the application from working (e.g., "Failed to connect to database," "Invalid input provided").
-
Log Exceptions properly. Use
logger.exception()inside anexceptblock. It automatically includes the stack trace in the log message.try: result = 10 / 0 except ZeroDivisionError: # This is the best way to log an exception logger.exception("Division by zero occurred!")Output:
ERROR:__main__:Division by zero occurred! Traceback (most recent call last): File "<stdin>",
