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 slightly formatted, that is, you see I instead of INFO, W instead of WARNING etc. In addition, the brackets are colored. I find this cool and would like to write my logs that way too. However, IPython uses tornado logging system.
I use the colorlog module to color the messages. In order to do the formatting, I subclassed the StreamHandler class, as described here:
How to get the level of the logging record in a custom logging.Handler 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, coloring does not work anymore.
Is there a way to have both logging level name formatting and coloring? Here is my full 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')
Do not change the level in handler.emit(). Instead, truncate 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 use the rest of Tornado or not: just call tornado.log.enable_pretty_logging() at the start of your program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With