pythonloggingdesign-patterns

Python Design Pattern Logger Class


Seeking for your advice, currently doing self studies regarding the Python Design Pattern. In chapter 2 I stock with this class. It has 2 module, logger_class.py and new_script_with_logger.py

for the module logger_class.py

class Logger(object):
    """A file-based message logger with the following properties
    Attributes:
        file_name: a string representing the full path of the log file to which this logger will write it messages
    """
    def __init__(self, file_name):
        """Return a logger object whose file_name is * file_name*"""
        self.file_name = file_name
    def _write_log(self, level, msg):
        """Writes a message to the file_name for a specific Logger instance"""
        with open(self.file_name, 'a') as log_file:
            log_file.write('[{0} {1}\n'.format(level, msg))
    def critical(self, level, msg):
        self._write_log('CRITICAL', msg)
    def error(self, level, msg):
        self._write_log(self, level, msg)
    def warn(self, level, msg):
        self._write_log('WARN', msg)
    def info(self, level, msg):
        self._write_log('INFO', msg)
    def debug(self, level, msg):
        self._write_log('DEBUG', msg)

And here the other module new_script_with_logger.py

from logger_class import Logger

logger_object = Logger('/var/log/class_logger.log')
logger_object.info('this is an info message')

The above code is came from the book of "Practical Python Design Patterns Pythonic Solution to Common Problems by Wessel Badenhorst"

When I run the code of new_script_with_logger.py, I got error message from PyCharm IDE In the console command running it

python new_script_with_logger.py

The result is like this

Traceback (most recent call last):
  File "C:\Users\Python Design Pattern\Practical_Design\Practical_Python_Design_PaTTERN\new_script_with_logger.py", line 4, in <module>
    logger_object.info('this is an info message')
TypeError: Logger.info() missing 1 required positional argument: 'msg'

I'm newbie please respect and understand my post thank you in advance

Explanation of how the code run


Solution

  • There are multiple flaws in the definition of the Logger class.

    How it is supposed to work

    The flaws

    'Correct' version

    Here is a revised version of the code you provided:

    class Logger(object):
        """A file-based message logger with the following properties
        Attributes:
            file_name: a string representing the full path of the log file to which this logger will write it messages
        """
        def __init__(self, file_name):
            """Return a logger object whose file_name is * file_name*"""
            self.file_name = file_name
        def _write_log(self, level, msg):
            """Writes a message to the file_name for a specific Logger instance"""
            with open(self.file_name, 'a') as log_file:
                log_file.write('[{0}] {1}\n'.format(level, msg))
        def critical(self, msg):
            self._write_log('CRITICAL', msg)
        def error(self, msg):
            self._write_log('ERROR', msg)
        def warn(self, msg):
            self._write_log('WARN', msg)
        def info(self, msg):
            self._write_log('INFO', msg)
        def debug(self, msg):
            self._write_log('DEBUG', msg)
    

    Now you can see that there is a consistent use of the _write_log accross every application below it. If you have more question feel free to ask them in comments