Python Logging - save to file with formatting

Viewed 466

I have python's logging module configured with all sorts of colour-coded lines. However the colours are lost when using a file handler to export to a log file and then tail -f to follow the file live.

Is there any way to export the colour formatting to the output file such that tail, less and co. could properly show it?

The configuration on the python side is done by something like:

coloredlogs.install(
logger=_logger, fmt='%(asctime)s %(message)s', use_chroot=False,
field_styles={'asctime': {'color': 'cyan'}}, datefmt='%d.%m.%Y %H:%M',
level_styles={
    'info': {'color': 'white', 'bold': False},
    'warn': {'color': 'blue', 'bold': True},
    'error': {'color': 'magenta', 'bold': False}
}

)

Thanks

2 Answers

You might disable the auto-detection if a colored formatter (default: in a terminal session) should be used or not by setting the isatty parameter.

https://coloredlogs.readthedocs.io/en/latest/api.html#coloredlogs.install

short example

import coloredlogs, logging

_logger = logging.getLogger(__name__)

coloredlogs.install(
    logger=_logger, fmt='%(asctime)s %(message)s', use_chroot=False,
    field_styles={'asctime': {'color': 'cyan'}}, datefmt='%d.%m.%Y %H:%M',
    level_styles={
        'info': {'color': 'white', 'bold': False},
        'warn': {'color': 'blue', 'bold': True},
        'error': {'color': 'magenta', 'bold': False}
    },
    isatty=True
)

_logger.debug("a debug message")
_logger.info("an info message")
_logger.warning("a warning message")
_logger.error("an error message")
_logger.critical("a critical message")

When you redirect the output to a file the file will contain the ANSI escape sequences.

00000000  1b 5b 33 36 6d 31 34 2e  31 30 2e 32 30 31 39 20  |.[36m14.10.2019 |
00000010  31 35 3a 31 35 1b 5b 30  6d 20 1b 5b 33 37 6d 61  |15:15.[0m .[37ma|
00000020  6e 20 69 6e 66 6f 20 6d  65 73 73 61 67 65 1b 5b  |n info message.[|
00000030  30 6d 0a 1b 5b 33 36 6d  31 34 2e 31 30 2e 32 30  |0m..[36m14.10.20|
00000040  31 39 20 31 35 3a 31 35  1b 5b 30 6d 20 1b 5b 31  |19 15:15.[0m .[1|
00000050  3b 33 34 6d 61 20 77 61  72 6e 69 6e 67 20 6d 65  |;34ma warning me|
00000060  73 73 61 67 65 1b 5b 30  6d 0a 1b 5b 33 36 6d 31  |ssage.[0m..[36m1|
00000070  34 2e 31 30 2e 32 30 31  39 20 31 35 3a 31 35 1b  |4.10.2019 15:15.|
00000080  5b 30 6d 20 1b 5b 33 35  6d 61 6e 20 65 72 72 6f  |[0m .[35man erro|
00000090  72 20 6d 65 73 73 61 67  65 1b 5b 30 6d 0a 1b 5b  |r message.[0m..[|
000000a0  33 36 6d 31 34 2e 31 30  2e 32 30 31 39 20 31 35  |36m14.10.2019 15|
000000b0  3a 31 35 1b 5b 30 6d 20  61 20 63 72 69 74 69 63  |:15.[0m a critic|
000000c0  61 6c 20 6d 65 73 73 61  67 65 0a                 |al message.|

There is few options for this, you can use sed function for it like: echo "WARN"|sed 's#WARN#\x1b[34m&#;'

or you can use grc for this porpuse, im using it sometime when i read logs

Related