Color logging using logging module in Python

Viewed 12430

Let's simplify this. My goal is to make color output in terminal using logging module in Python. I want info has a green prefix, warnings have a yellow prefix and errors have a red prefix. To make it simple let's use *** as the prefix i.e.

*** log text
*** another message with another prefix color

What I have done so far

# declaration of function (global scope)
log = None
warn = None
error = None 
def build_log_funcs():
    # why I initialize it inside the function ?
    # because script doesnt have to know about logging method
    # the function just provide log  functions
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)

    sh = logging.StreamHandler()
    # LOG_FORMAT just global variable with pattern including %(levelmarks)s
    # it will be replaced with ** with proper color 
    formatter = logging.Formatter(LOG_FORMAT)
    sh.setFormatter(formatter)
    logger.addHandler(sh)

    def make_log_func(func, color, is_exit = False):
        color_string = "\x1b[{};1m***\x1b[0m".format(color)
        def newfunc(*args, **kwargs):
            func(*args, extra={'levelmarks':color_string}, **kwargs)
            if is_exit:
                sys.exit(-1)

        return newfunc
    # 32, 33, 31 are color codes
    log = make_log_func(logger.info, 32)
    warn = make_log_func(logger.warning, 33)
    error = make_log_func(logger.error, 31, is_exit = True)

    return log, warn, error

And use it as

log, warn, error = build_log_funcs()

It works but what I don't like: (from small to big problems)

  1. I hide the capabilities of logging module. For example enabling/disabling debug messages
  2. I should use global declaration of functions before their initialization because I can't call a function before its declaration.
  3. It's too difficult to read and maintain the code. I believe that everything should be as simple as possible.

Why don't I just make simple log, warn, simple function? I don't know. logging is the very comprehensive module so may be I will need its features in the future.

My question is how would you solve this problem? May be there is a simple obvious way which I don't know.

1 Answers
Related