How to format the name of the logging level

When I start IPython I see logs like this:

[I 17:03:59.993 NotebookApp] Using MathJax from CDN:       https://cdn.mathjax.org/mathjax/latest/MathJax.js
[W 17:04:00.292 NotebookApp] Terminals not available (error was No    module named terminado)
[I 17:04:00.293 NotebookApp] Serving notebooks from local directory: /home/oleg
[I 17:04:00.293 NotebookApp] 0 active kernels 
[I 17:04:00.293 NotebookApp] The IPython Notebook is running at: http://localhost:8888/
[I 17:04:00.293 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

      

Here, the levels of messages are formatted slightly, that is, instead of INFO

, W

instead of WARNING

, and I

etc. In addition, the brackets are colored. I think this is cool and I would love to write my own magazines too. However, IPython uses a tornado logging system.

I am using the colorlog module for colored messages. To do the formatting, I subclassed the class StreamHandler

as described here:   How to get the logging level in a custom .Handler protocol in Python?

class FormatLevelHandler(logging.StreamHandler):
    def emit(self, record):
        record.levelname = record.levelname[0]
        logging.StreamHandler.emit(self, record)

      

But when I do this the coloring doesn't work anymore.

Is there a way to format and color the logging level name? Here is my complete code:

import logging
from colorlog import ColoredFormatter
formatter = ColoredFormatter(
    "%(log_color)s[%(levelname)1s %(asctime)s] %(reset)s %(blue)s%(message)s",
    datefmt=None,
    reset=True,
    log_colors={
        'DEBUG':    'cyan',
        'INFO':     'green',
        'WARNING':  'yellow',
        'ERROR':    'red',
        'CRITICAL': 'red,bg_white',
    },
    secondary_log_colors={},
    style='%'
)
logger = logging.getLogger(__name__)

class FormatLevelHandler(logging.StreamHandler):
    def emit(self, record):
        record.levelname = record.levelname[0]
        logging.StreamHandler.emit(self, record)

ch = FormatLevelHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG)
logger.info('Hello')
logger.debug('Hi')

      

+3


source to share


2 answers


Do not change the level in handler.emit()

. Instead, trim the level in the format string itself using %(levelname)1.1s

(not %(levelname)1s

as in your example).



Or you can use the Tornado logging system whether you are using the rest of Tornado or not: just call tornado.log.enable_pretty_logging()

at the beginning of your program.

+2


source


Yes. While the problem seems rather complicated at first, the reason is simple: it colorlog

uses the dictionary you provide to match the level name after Handler.emit

.

Thus, you need to change the dictionary to



log_colors={
        'D': 'cyan',
        'I': 'green',
        'W': 'yellow',
        'E': 'red',
        'C': 'red,bg_white',
    },

      

+1


source







All Articles