I’m quite a big fan of Sentry logging, especially for Django project, but for a project I needed to setup Graylog logging as it was already available in the infra structure.
Python has an excellent logging system and Django uses it since Django 1.3. To use it in views, models and tasks you add an import on top of the file:
Then you can use it everywhere in that python file with:
Inside an exception you can use “exception” logger to attach stack trace:
First a brief note about the vision behind logging.
Your app should not be concerned with where its logs go. Instead, it should log everything to the console (stdout/stderr) and let the production environment decide what to do with it from there. Typically this is put in a dedicated (and logrotated) file, captured by the Systemd journal or Docker, sent to a separate service such as ElasticSearch, Kibana, Logstash, or some combination of those.
Rule of thumb: Log storage is a deployment concern, not an application concern.
Your app does needs to concern itself with the format of the logs. Typically this is just a string with the relevant data, but if your server already adds a timestamp to the log, you probably want to exclude it from your own formatter. Likewise, if your log aggregator accepts JSON, a formatter like python-json-logger will be more appropriate.
By default Django does setup it’s production logging to mail errors to admins. This can be a nice feature for small sites as it alerts people when things go wrong. For larger sites it get annoying quite fast. An error on a heavy loaded site can easily spawn thousands of mails in a couple of seconds. As the default behaviour is quite difficult to change I normally rewrite the complete logging so I can benefit from other things as well:
So here we go, the following config can be used as a starting point:
Tweaking the noise level is quite easy: imagine you have a lot irrelevant logging from “noisy_module”
Add this to your loggers, below the “your_project_name” logger:
Now only errors are logged to console. If you don’t want to see it all:
If you need the default requests logging again: