[ACCEPTED]-How does one make logging color in Django/Google App Engine?-colors

Accepted answer
Score: 22

We use colorlog and it does exactly what you expect.

For 1 posterity, the formatter config we use is:

'color': {
    '()': 'colorlog.ColoredFormatter',
    'format': '%(log_color)s%(levelname)-8s %(message)s',
    'log_colors': {
        'DEBUG':    'bold_black',
        'INFO':     'white',
        'WARNING':  'yellow',
        'ERROR':    'red',
        'CRITICAL': 'bold_red',
    },
}
Score: 10

Django already has support for color output 7 through the 'DJANGO_COLORS' environment variable used 6 for example when running the built in development 5 server. Some person has noticed this and 4 created a plug-and-play solution https://github.com/tiliv/django-colors-formatter; with 3 that package on the project's python path 2 my logging settings.py is as follow:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'formatters': {
        'verbose': {
            '()': 'djangocolors_formatter.DjangoColorsFormatter', # colored output
            'format': '%(levelname)s %(name)s %(asctime)s %(module)s %(process)d %(thread)d %(pathname)s@%(lineno)s: %(message)s'
        },
        'simple': {
            '()': 'djangocolors_formatter.DjangoColorsFormatter', # colored output
            'format': '%(levelname)s %(name)s %(filename)s@%(lineno)s: %(message)s'
        },
    },
     # omitting the handler 'level' setting so that all messages are passed and we do level filtering in 'loggers'
    'handlers': {
        'null': {
            'class':'django.utils.log.NullHandler',
        },
        'console':{
            'class':'logging.StreamHandler',
            'formatter': 'simple',
        },
        'mail_admins': {
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        '': { 
            'handlers': ['mail_admins', 'console'],
            'level': 'WARNING',
        },
    }
}

Sample console 1 logging output using django-colors-formatter: Sample console logging output

Score: 5

I also wanted color output for the dev_appserver. I 6 found the solutions here a little OTT (all 5 I wanted was to make my logging.error() calls 4 stand out. I ended up monkeypatching the 3 logging module by dropping this in my main.py 2 as a quick solution:

# monkey patch logger to dump ERRORs in red
import os
if os.environ['SERVER_SOFTWARE'].find('Development') >= 0:
    import logging
    old_error = logging.error
    def red_error(msg,*args,**kwargs):
        old_error("\033[22;31m%s\033[0;0m" % msg, *args, **kwargs)
    logging.error = red_error

This will only for on 1 ANSI-color terminals.

Score: 4

Here is a sample formater:

class Formatter(logging.Formatter) :
    _level_colors  = {
      "DEBUG": "\033[22;32m", "INFO": "\033[01;34m",
      "WARNING": "\033[22;35m", "ERROR": "\033[22;31m",
      "CRITICAL": "\033[01;31m"
     };    

    def format(self, record):
        if(Formatter._level_colors.has_key(record.levelname)):
            record.levelname = "%s%s\033[0;0m" % \
                            (Formatter._level_colors[record.levelname],
                             record.levelname)
        record.name = "\033[37m\033[1m%s\033[0;0m" % record.name
        return logging.Formatter.format(self, record)    

You need to configure 1 it, for example:

...
[formatters]
keys=console_formatter
...
[handler_console_handler]
class=StreamHandler
formatter=console_formatter
args=(sys.stdout,)
Score: 4

Although this is not quite what the OP wanted 24 (each line colored by level), I wanted to 23 share a nice alternative for log output 22 coloring called rich - an awesome library for 21 various rich text stuff to display in terminal, authored 20 by @will-mcgugan.

Simple example

Activating rich coloring for Django logs 19 is easy: just use rich.logging.RichHandler instead of logging.StreamHandler, e.g.

# project/settings.py

...

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'rich.logging.RichHandler',  # <-- this
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO',
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
            'propagate': False,
        },
    },
}

(this 18 is the modified example from Django logging docs). This will 17 produce terminal logs like these ones:

django-rich-logs

Changing output format

Format 16 customizations are done as usual via passing 15 the handler arguments. E.g. to turn on rich tracebacks and 14 hide the timestamp column:

LOGGING = {
    ...
    'handlers': {
        'console': {
            'class': 'rich.logging.RichHandler',
            'rich_tracebacks': True,
            'show_time': False,
        },
    },
}

will yield

enter image description here

Changing output colors

Changing 13 the coloring is possible, but not via logging 12 config as multiple colors and different 11 styles are applied to each line; you will 10 have to provide a customized theme for that. Example 9 that changes coloring of INFO label from default 8 blue to bold magenta:

import rich
import rich.theme

my_theme = rich.theme.Theme({
    'logging.level.info': 'bold magenta',
})
rich.reconfigure(theme=my_theme)

LOGGING = {
    ...  # no changes here
}

For more details, see 7 Styles documentation. To inspect available theme 6 keys and default values, issue

$ python -mrich.theme

and look for 5 keys prefixed with log. or logging..

Outro

Note that rich is so 4 much more than just colored logging, go 3 check it out:

$ python -mpip install rich
$ python -mrich

Specifically for the logging 2 use case, check out the output of

$ python -mrich.logging

to see 1 more rendering examples than in the screenshots.

Score: 2

The reset codes mentioned in the answer 8 you linked to will work on a console in 7 the local development server (but will likely 6 take some tweaking - you'll have to chain 5 it with the existing App Engine logging 4 handler), but won't work in production, since 3 in production log entries are output to 2 an HTML page in your admin console.

You can, however, filter 1 by log level in the admin console.

Score: 2

I don't believe that you should create a 10 logger subclass just for this - airmind's 9 answer is fine as far as creating a specialised 8 Formatter and specifying its use on a StreamHandler. But there's 7 no need for a logger subclass. In fact airmind's 6 use of a logger class adds a handler to 5 every logger created, which is not what 4 you want.

The solution airmind gave only 3 works for terminals which support ANSI escape 2 sequences - are you sure that your console 1 does support them?

Score: 2

I used the coloredlogs package. Unlike DJANGO_COLORS, it's not specific 4 to Django commands, and unlike django-colors-formatter, it's actively 3 maintained.

I added a single line to my logging 2 config, and now I get configurable coloured 1 logs.

logging.config.dictConfig({
    ...
    'formatters': {
        'console': {
            # This line right here:
            "()": "coloredlogs.ColoredFormatter",
            'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(message)s',
        },
    },
    ...
Score: 1

Install colorlog

(don't forget to put colorlog in 2 INSTALLED_APPS)

create 'colored' in your formatter

 'colored': {
        '()': 'colorlog.ColoredFormatter',
        'format': "%(log_color)s %(levelname)-8s %(asctime)s %(module)s %(reset)s %(blue)s%(message)s",
    }

full example of 1 logger in settings.py

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
    'colored': {
        '()': 'colorlog.ColoredFormatter',
        'format': "%(log_color)s %(levelname)-8s %(asctime)s %(module)s %(reset)s %(blue)s%(message)s",
    }
},
'handlers': {
    'console': {
        'class': 'logging.StreamHandler',
        'formatter': 'colored'
    },
},
'root': {
    'handlers': ['console'],
    'level': 'WARNING',
},
'loggers': {
    'django': {
        'handlers': ['console'],
        'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        'propagate': False,
     },
  },
}

enter image description here

Score: 0

Here is my solution for Django with colorlog. It 2 just colors simple django messages as they 1 are. You only need to put it in your settings.py.

pip install colorlog
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'special': {
            '()': 'colorlog.ColoredFormatter',
            'format': '%(log_color)s[%(asctime)s] %(message)s'
        }
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'special'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'propagate': True,
        }
    }
}

Screen

More Related questions