├── setup.py ├── LICENSE ├── djangocolors_formatter └── __init__.py └── README.md /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | setup( 3 | name = "DjangoColorsFormatter", 4 | version = "1.0", 5 | packages = find_packages(), 6 | exclude_package_data = { 'djangocolors_formatter': ['*.pyc'] }, 7 | 8 | # metadata for upload to PyPI 9 | author = "Tim Valenta", 10 | author_email = "tonightslastsong@gmail.com", 11 | description = "Zero-config logging formatter that uses the built-in DJANGO_COLORS setting", 12 | license = "BSD", 13 | keywords = "django colors logging formatter DJANGO_COLORS", 14 | url = "https://github.com/tiliv/django-colors-formatter", 15 | ) 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2022 Scott Chacon and others 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /djangocolors_formatter/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import logging 3 | 4 | from django.core.management.color import color_style 5 | 6 | 7 | class DjangoColorsFormatter(logging.Formatter): 8 | def __init__(self, *args, **kwargs): 9 | if sys.version_info < (2, 7): 10 | logging.Formatter.__init__(self, *args, **kwargs) 11 | else: 12 | super(DjangoColorsFormatter, self).__init__(*args, **kwargs) 13 | self.style = self.configure_style(color_style()) 14 | 15 | def configure_style(self, style): 16 | style.DEBUG = style.HTTP_NOT_MODIFIED 17 | style.INFO = style.HTTP_INFO 18 | style.WARNING = style.HTTP_NOT_FOUND 19 | style.ERROR = style.ERROR 20 | style.CRITICAL = style.HTTP_SERVER_ERROR 21 | return style 22 | 23 | def format(self, record): 24 | message = logging.Formatter.format(self, record) 25 | if sys.version_info[0] < 3: 26 | if isinstance(message, unicode): 27 | message = message.encode('utf-8') 28 | colorizer = getattr(self.style, record.levelname, self.style.HTTP_SUCCESS) 29 | return colorizer(message) 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django-colors-formatter 2 | 3 | Zero-config logging formatter that uses the built-in DJANGO_COLORS setting 4 | 5 | ## Setup 6 | 7 | In your Django `LOGGING` settings, just add this to your formatters, and then reference it in (for example) a console logger: 8 | 9 | LOGGING = { 10 | 'version': 1, 11 | 'formatters': { 12 | 'colored': { 13 | '()': 'djangocolors_formatter.DjangoColorsFormatter', 14 | 'format': '%(levelname)s %(module)s %(message)s', 15 | }, 16 | }, 17 | 'handlers': { 18 | 'colored': { 19 | 'level': 'DEBUG', 20 | 'class': 'logging.StreamHandler', 21 | 'formatter': 'colored', 22 | }, 23 | }, 24 | 'loggers': { 25 | 'myproject': { 26 | 'handlers': ['colored'], 27 | 'level': 'DEBUG', 28 | }, 29 | }, 30 | } 31 | 32 | The formatter generates its colors with Django's own internal colorizing mechanism, which means that the [`DJANGO_COLORS`](https://docs.djangoproject.com/en/dev/ref/django-admin/#syntax-coloring) environment variable is respected. 33 | 34 | `DjangoColorsFormatter` maps Django's default HTTP status code colors to the built-in logging levels: 35 | 36 | * DEBUG = `HTTP_NOT_MODIFIED` (light=green; dark=cyan) 37 | * INFO = `HTTP_INFO` (plain/bold) 38 | * WARNING = `HTTP_NOT_FOUND` (light=red; dark=yellow) 39 | * ERROR = `ERROR` (red/bold) 40 | * CRITICAL = `HTTP_SERVER_ERROR` (magenta/bold) 41 | 42 | ## Environment variable: simple configuration 43 | 44 | Django lets you configure these values, as described [here](https://docs.djangoproject.com/en/dev/ref/django-admin/#syntax-coloring), but due to the way their palette generation works, you can't invent your own logging names. That is, if you want to change the `WARNING` color, you indeed have to set your environment variable to use an `HTTP_NOT_FOUND` color, which this formatting class will pull over for its own use. 45 | 46 | ## Subclassing the formatter: free-form configuration 47 | 48 | By subclassing the formatter, you can override the custom `configure_style()` method, which does the default color assignments. 49 | 50 | def configure_style(self, style): 51 | style.DEBUG = style.HTTP_NOT_MODIFIED 52 | style.INFO = style.HTTP_INFO 53 | style.WARNING = style.HTTP_NOT_FOUND 54 | style.ERROR = style.ERROR 55 | style.CRITICAL = style.HTTP_SERVER_ERROR 56 | return style 57 | 58 | `style` is just a dummy object that you assign arbitrary attributes to. At runtime, the logging level name is looked up. 59 | 60 | The attributes should be dictionaries, which define color options using the same environment variable names. For example, the Django documentation gives the following demonstration of setting the `DJANGO_COLORS` variable: 61 | 62 | export DJANGO_COLORS="error=yellow/blue,blink;notice=magenta" 63 | 64 | This would set "ERROR" messages in blinking yellow on blue, and "NOTICE" messages in magenta foreground. 65 | 66 | To accomplish this in a formatting subclass, you would do the following: 67 | 68 | def configure_style(self, style): 69 | style.ERROR = { 70 | 'fg': 'yellow', 71 | 'bg': 'blue', 72 | 'opts': ('blink',), 73 | } 74 | style.NOTICE = { 75 | 'fg': 'magenta', 76 | } 77 | 78 | This is the formatting design used internally by Django to set the default color palettes. 79 | 80 | To stylize a custom logging level name, you must use this subclassing method and assign that name a configuration dictionary (shown just above), or assign one of the default style names from the built-in palette. 81 | --------------------------------------------------------------------------------