Provide reset_color key on log record

When logging with color, it is necessary to reset the color at the
end of each line to avoid the color bleeding into subsequent log
lines.  This change adds a new key to the record called 'reset_color'
that serves as a shortcut to the escape sequence to reset the color.
It also provides documentation for the ColorHandler class that
explains how to use it.

Change-Id: I68f1c716cbed241f79fa65dae1affe810b8e6e30
Closes-Bug: 1731477
This commit is contained in:
Ben Nemec 2018-06-01 17:51:53 +00:00
parent 89bbb3fb79
commit 9da1f158b2
2 changed files with 11 additions and 3 deletions

View File

@ -146,6 +146,12 @@ class OSJournalHandler(logging.Handler):
class ColorHandler(logging.StreamHandler):
"""Log handler that sets the 'color' key based on the level
To use, include a '%(color)s' entry in the logging_context_format_string
and a '%(reset_color)s' entry at the end of the format string so that the
color setting does not persist between log lines.
"""
LEVEL_COLORS = {
_TRACE: '\033[00;35m', # MAGENTA
logging.DEBUG: '\033[00;32m', # GREEN
@ -158,4 +164,5 @@ class ColorHandler(logging.StreamHandler):
def format(self, record):
record.color = self.LEVEL_COLORS[record.levelno]
record.reset_color = '\033[00m'
return logging.StreamHandler.format(self, record)

View File

@ -987,7 +987,8 @@ class FancyRecordTestCase(LogTestBase):
"[%(request_id)s]: "
"%(instance)s"
"%(resource)s"
"%(message)s",
"%(message)s"
"%(reset_color)s",
logging_default_format_string="%(missing)s: %(message)s")
self.colorlog = log.getLogger()
self._add_handler_with_cleanup(self.colorlog, handlers.ColorHandler)
@ -1040,7 +1041,7 @@ class FancyRecordTestCase(LogTestBase):
fake_resource = {'name': resource}
message = 'info'
self.colorlog.info(message, context=ctxt, resource=fake_resource)
expected = ('%s [%s]: [%s] %s\n' %
expected = ('%s [%s]: [%s] %s\033[00m\n' %
(color, ctxt.request_id, resource, message))
self.assertEqual(expected, self.stream.getvalue())
@ -1053,7 +1054,7 @@ class FancyRecordTestCase(LogTestBase):
'id': resource_id}
message = 'info'
self.colorlog.info(message, context=ctxt, resource=fake_resource)
expected = ('%s [%s]: [%s-%s] %s\n' %
expected = ('%s [%s]: [%s-%s] %s\033[00m\n' %
(color, ctxt.request_id, type, resource_id, message))
self.assertEqual(expected, self.stream.getvalue())