SoFunction
Updated on 2024-11-13

Write simple and practical log decorator based on Python

When writing code, the key element of logging is often missed, resulting in features that go wrong while in use but cannot be traced back.

In fact, just by writing a very simple log decorator, we can greatly improve the efficiency of troubleshooting problems.

1. A rudimentary version of the decorator

Writing a decorator is very simple, because essentially a decorator is just a "higher-order" function that returns a function:

1) Functions are passed as arguments into the decorator.

2) Define a function within the decorator that handles functions passed in as arguments.

3) return the function defined within this decorator

import datetime

def log(func):
    """
    Log Decorator,Logging of simple logging functions

    Args:
        func (function): function (math.)
    """
    def inner(*args):
        timestamp = str(()).split(".")[0]
        res = func(*args)
        print(f"[{timestamp}] ({func.__name__}) {args} -> {res}")
        return res
    return inner

Try using it:

@log
def pluser(a, b):
    return a + b

pluser(1, 2)

The effect is as follows:

While this achieves the functionality we need, there is actually a lot of room for optimization.

2. Ordinary version of the decorator

There was an obvious problem in the first version of the code, where the handler functions defined within the decorator did not support kwargs, and supporting kwargs in the decorator was just a matter of throwing up your hands.

The second problem is that the generation of timestamps in the form of string interception, this form is too crude. In fact, you can use strftime to do string conversion.

Modify the following:

import datetime

def log(func):
    """
    Log Decorator,Logging of simple logging functions

    Args:
        func (function): function (math.)
    """
    def inner(*args, **kwargs):
        timestamp = ().strftime("%Y-%m-%d %H:%M:%S")
        res = func(*args, **kwargs)
        print(f"[{timestamp}] ({func.__name__}) {args} -> {res}")
        return res
    return inner

It seems to be pretty much optimized, but there is still room for improvement.

3. Optimized version of the decorator

In the first two versions of the code, we used print for logging output, which is actually not a standard way of handling logging.

Using the logging module to control logging output is a better option.

In order to use the logging module for logging, we need to configure the logging-related options first.

1) First, generate a logger and configure the logging level:

import logging

# Get loggers, configure logging levels
logger = (__name__)
('DEBUG')

2) Configure log format, add handler to control output stream:

# Default log format
formatter = ("%(asctime)s - [%(levelname)s] - %(message)s")
# Handler for output to console
chlr = ()
# Configure the default log format
(formatter)

Here you can set the level of logging that the handler needs to process, if you don't set it, it will default to the logger's own Level, i.e. DEBUG level.

3) Finally, add this handler to the logger:

# Add this handler to the logger
(chlr)

The full configuration of logging is as follows:

import logging

# Get loggers, configure logging levels
logger = (__name__)
('DEBUG')

# Default log format
formatter = ("%(asctime)s - [%(levelname)s] - %(message)s")
# Handler for output to console
chlr = ()
# Configure the default log format
(formatter)

# Add this handler to the logger
(chlr)

It is very simple to use, just replace print:

def log(func):
    """
    Log Decorator,Logging of simple logging functions

    Args:
        func (function): function (math.)
    """
    def inner(*args, **kwargs):
        timestamp = ().strftime("%Y-%m-%d %H:%M:%S")
        res = func(*args, **kwargs)
        (f"func: {func.__name__} {args} -> {res}")
        return res
    return inner

The effect is as follows:

In this way, a more complete log decorator is completed.

With common logging level configurations:

The above is based on Python to write a simple and practical log decorator details, more information about Python log decorator please pay attention to my other related articles!