[ACCEPTED]-How does one make logging color in Django/Google App Engine?-colors
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',
},
}
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:
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.
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,)
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:
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
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.
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.
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?
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',
},
},
...
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,
},
},
}
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,
}
}
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.