Hone logo
Hone
Problems

Python Logging Setup: From Debugging to Production

A robust logging system is crucial for any software application, enabling developers to track program execution, diagnose errors, and monitor performance. This challenge focuses on setting up a flexible and informative logging mechanism in Python using the built-in logging module. You'll learn to configure log levels, format messages, and direct output to different destinations.

Problem Description

Your task is to implement a Python logging setup that can handle various logging scenarios. You should configure the logging system to:

  1. Set a default logging level: This determines the minimum severity of messages that will be processed.
  2. Define a log message format: This specifies how each log entry will appear, including timestamp, log level, module name, and the message itself.
  3. Log to the console (standard output): For immediate feedback during development and debugging.
  4. Log to a file: For persistent record-keeping, especially in production environments.

Consider how different logging levels (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) should be handled and how your setup will accommodate them.

Key Requirements:

  • Use Python's standard logging module.
  • Configure a StreamHandler to output logs to sys.stdout.
  • Configure a FileHandler to write logs to a specified file.
  • Implement a Formatter to define the structure of log messages.
  • Allow for the configuration of the root logger or a specific named logger.
  • The setup should be easily reusable across different parts of an application.

Expected Behavior:

When the script runs, you should see log messages printed to the console and written to a file. The messages should adhere to the specified format, and only messages at or above the configured logging level should appear in either destination.

Edge Cases to Consider:

  • File not writable: What happens if the directory for the log file doesn't exist or the user lacks write permissions? (For this challenge, assume a writable path is provided.)
  • Log file rotation: For long-running applications, log files can become very large. While not a strict requirement for this basic setup, consider how you might approach this in a more advanced scenario (though you don't need to implement it for this challenge).

Examples

Example 1: Basic Configuration

import logging
import sys

# Assume this is your logging setup function
def setup_logging(log_level=logging.INFO, log_file="app.log"):
    # ... your implementation here ...
    pass

# Simulate calling the setup and logging messages
setup_logging(log_level=logging.DEBUG, log_file="debug_app.log")

logging.debug("This is a debug message.")
logging.info("This is an informational message.")
logging.warning("This is a warning message.")
logging.error("This is an error message.")
logging.critical("This is a critical message.")

Expected Output (Console - sys.stdout):

[DEBUG] <module>: This is a debug message.
[INFO] <module>: This is an informational message.
[WARNING] <module>: This is a warning message.
[ERROR] <module>: This is an error message.
[CRITICAL] <module>: This is a critical message.

Expected Output (File - debug_app.log):

(Content of debug_app.log would be identical to the console output, assuming the file is created successfully.)

Explanation:

The setup_logging function is called with logging.DEBUG as the level and "debug_app.log" as the file name. All messages from DEBUG to CRITICAL are configured to be output to both the console and the log file. The format includes the log level, module name (which will be <module> for top-level script execution), and the message.

Example 2: Different Logging Level

import logging
import sys

# Assume this is your logging setup function (same as above)
def setup_logging(log_level=logging.INFO, log_file="app.log"):
    # ... your implementation here ...
    pass

setup_logging(log_level=logging.WARNING, log_file="warning_app.log")

logging.debug("This is a debug message.")
logging.info("This is an informational message.")
logging.warning("This is a warning message.")
logging.error("This is an error message.")
logging.critical("This is a critical message.")

Expected Output (Console - sys.stdout):

[WARNING] <module>: This is a warning message.
[ERROR] <module>: This is an error message.
[CRITICAL] <module>: This is a critical message.

Expected Output (File - warning_app.log):

(Content of warning_app.log would be identical to the console output.)

Explanation:

This time, setup_logging is called with logging.WARNING. Therefore, only messages with a severity of WARNING or higher (ERROR, CRITICAL) are processed and outputted.

Constraints

  • The Python version used must be 3.6 or higher.
  • The logging module must be used. No third-party logging libraries are allowed.
  • The solution should be a Python script or a function within a Python script that configures the logging.
  • The log file should be created if it doesn't exist.
  • The log message format should be: [LEVEL] <module_name>: MESSAGE. For example: [INFO] my_script: Application started.

Notes

  • You will need to import the logging module.
  • Consider using logging.getLogger() to get a logger instance, and then add handlers and formatters to it. You can configure the root logger or a named logger. For this challenge, configuring the root logger is sufficient.
  • Remember to set the level for both the logger and the handlers.
  • The logging.basicConfig() function is a convenient way to set up basic logging, but for this challenge, you are encouraged to manually configure handlers and formatters to gain a deeper understanding.
  • Think about how to clear existing handlers if you were to call setup_logging multiple times to avoid duplicate log outputs.
Loading editor...
python