structlog
structlog copied to clipboard
KeyValueRenderer with optional colors
I gave an implementation of a color keyvaluerenderer a shot:
import structlog
try:
import colorama
except ImportError:
colorama = None
class ColorKeyValueRenderer(structlog.processors.KeyValueRenderer):
def __init__(self, colors=True, force_colors=False, **kwargs):
super().__init__(self, **kwargs)
if colors and colorama:
if force_colors:
colorama.deinit()
colorama.init(strip=False)
else:
colorama.init()
styles = structlog.dev._ColorfulStyles
else:
styles = structlog.dev._PlainStyles
self._styles = styles
self._level_to_color = structlog.dev.ConsoleRenderer.get_default_level_styles(
colors)
for key in self._level_to_color.keys():
self._level_to_color[key] += styles.bright
def __call__(self, _, __, event_dict):
sio = StringIO()
for key, value in self._ordered_items(event_dict):
if key == 'level':
sio.write(
self._level_to_color[value] + key +
'=' + str(value) + self._styles.reset + ' '
)
elif key in ('time', 'timestamp'):
sio.write(
self._styles.timestamp + key + '=' +
str(value) + self._styles.reset + ' '
)
else:
# sio.write(self._styles.kv_key + key + '=' +
# self._repr(value) + self._styles.reset + ' ')
sio.write(
self._styles.kv_key + key + self._styles.reset +
"=" +
self._styles.kv_value + self._repr(value) +
self._styles.reset + ' '
)
return sio.getvalue()
Would render the following:
As you can see is a giant hack around KeyValueRenderer and ConsoleRenderer :-)
What do you think?
I made another version. This one uses an infinite color iterator to colorize key value pairs, I don't distinguish between the color of the key and the value:
LEVEL_COLORS = {
"critical": colorama.Fore.RED,
"exception": colorama.Fore.RED,
"error": colorama.Fore.RED,
"warn": colorama.Fore.YELLOW,
"warning": colorama.Fore.YELLOW,
"info": colorama.Fore.GREEN,
"debug": colorama.Fore.BLUE,
"notset": colorama.Back.RED,
}
COLORS = {
'timestamp': colorama.Style.DIM,
'time': colorama.Style.DIM,
'event': colorama.Fore.BLUE + colorama.Style.BRIGHT
}
# all ANSI colors, except black and white
KV_COLORS = (
colorama.Fore.RED, colorama.Fore.GREEN,
colorama.Fore.YELLOW, colorama.Fore.BLUE, colorama.Fore.MAGENTA,
colorama.Fore.CYAN)
class ColorKeyValueRenderer(structlog.processors.KeyValueRenderer):
def __init__(self, force_colors=False, **kwargs):
super().__init__(self, **kwargs)
if force_colors:
colorama.deinit()
colorama.init(strip=False)
else:
colorama.init()
def __call__(self, _, __, event_dict):
colors_iterator = itertools.cycle(reversed(KV_COLORS))
buffer = StringIO()
for key, value in self._ordered_items(event_dict):
if key == 'level':
buffer.write(
LEVEL_COLORS[value] + key +
'=' + str(value) + colorama.Style.RESET_ALL + ' '
)
else:
buffer.write(
self.color(key, colors_iterator) + key + '=' +
self._repr(value) + colorama.Style.RESET_ALL + ' '
)
return buffer.getvalue()
def color(self, key, colors):
return COLORS.get(key, next(colors))
Result:
What is it you’re trying to achieve here? A colorful ConsoleRenderer without field alignments? I’m not sure I quite understand the point, you wouldn’t put it into prod anyway?
@hynek just an experiment. I just added colors to the KV renderer basically. I'm not particularly interested in the alignment part of the ConsoleRenderer.
Why, apart from the fact that's an experiment, shouldn't I use it in production?
Thanks
Well I don’t know your setup, but I don’t want to have ANSI color sequences in my log files? :)
@hynek oh yes, that obviously :-)
While I don't want to have random colors around...I DO think it's useful to colorize the event dicts, is there a feature for this?
No, this is not something I'm willing to spend my time on, but it's absolutely something I encourage people to write and share. It's a matter of taste anyway and it's impossible for me to make everybody happy; especially given I don't care about it myself.