Issue
I am running Python notebooks on Jupyter Notebook server. I am using Python logging
module for logging, currently wired up to log to stdout
like any console application, do display logging messages in Jupyter Notebook output.
But the default stdout
based logging output feels limited. There is so much more you can do with HTML output over plain text/ANSI output.
Are there any advanced Jupyter Notebook logging handlers and formatters that would understand that the output is HTML and adjust accordingly? E.g. offer richer formatting options with colors and font sizes and interactively explore logging message context parameters like Sentry allows one to do?
Solution
Never thought to try this before, but yes you can do this using IPython.display.display
and a custom logging.Handler
which calls it:
import logging
from IPython.display import display, HTML
class DisplayHandler(logging.Handler):
def emit(self, record):
message = self.format(record)
display(message)
This could be used to display anything the notebook can display, including HTML, Markdown, images???, audio???? (if you want your notebook to read your logs to you).
I combined this with a custom logging.Formatter
that outputs an HTML
object for passing to display()
. It's not pretty but you can take the basic concept and improve it, or combine both classes into a single NotebookHTMLHandler
class or something like that:
class HTMLFormatter(logging.Formatter):
level_colors = {
logging.DEBUG: 'lightblue',
logging.INFO: 'dodgerblue',
logging.WARNING: 'goldenrod',
logging.ERROR: 'crimson',
logging.CRITICAL: 'firebrick'
}
def __init__(self):
super().__init__(
'<span style="font-weight: bold; color: green">{asctime}</span> '
'[<span style="font-weight: bold; color: {levelcolor}">{levelname}</span>] '
'{message}',
style='{'
)
def format(self, record):
record.levelcolor = self.level_colors.get(record.levelno, 'black')
return HTML(super().format(record))
Put all together you can use it like this:
log = logging.getLogger()
handler = DisplayHandler()
handler.setFormatter(HTMLFormatter())
log.addHandler(handler)
log.setLevel(logging.DEBUG)
Here's an example of how it looks:
For the HTML version you could tidy this up further, if the HTML grows complicated enough, by combining with an HTML templating engine like Jinja, or add JavaScript/Widgets to make log messages expandable to show more of the log record context, per your idea. A full solution I think would be beyond the scope of this answer.
Answered By - Iguananaut
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.