Aggregating Exceptions and Logs with Sentry

This is an “exception” aggregator split into two parts: server and client. Exceptions are aggregated on the server, where you can search, filter, and so on. The client side simply sends “exceptions” to the server, and that’s it.
This cool tool is made by the well-known David Cramer and the DISQUS team.
It can plot event graphs for the “exceptions” that occur. For a particular “exception,” it can display headers, cookies, and other details, a stack trace with context (rather than the bare one you get by email), the user’s environment (browser, OS, etc.), details about the authenticated user (for requests), information about installed applications, and so on.
You can add groups of errors to your favorites. And with plugins enabled, you can, for example, register “exceptions” in Jira, Assembla, and Trello.
Besides Python projects (I’m particularly interested in Django and Flask), PHP, Ruby, Node.js, Java, and Javascript are also supported. All official clients work through raven.
sentry itself runs on Django + dependencies. It uses gunicorn as its WSGI server.
It has this sexy interface built on Twitter Bootstrap:
The current version of Sentry is 5.0.21
Setting up the server side
There is paid storage at getsentry.com, where you can store your “exceptions,” with prices currently starting at just $9/mo. In other words, you can skip installing the server side entirely and go straight to setting up the client side. This option didn’t suit me because of a certain amount of paranoia surrounding the project. If your project doesn’t have that issue, it’s certainly easier to rent a Sentry server.
So, let’s get started with installing and configuring the server side! Log in to the server, install Sentry, and generate a configuration file:
virtualenv --no-site-packages --distribute /var/www/sentry
source /var/www/sentry/bin/activate
pip install sentry
sentry init /etc/sentry.conf
Next, specify the backend you want (the ENGINE section in DATABASES) for storing error data. Personally, I prefer MySQL:
emacs /etc/sentry.conf
# Укажите настройки для подключения к БД
DATABASES = {
'default': {
# You can swap out the engine for SQLite easily by changing this value
# to ``django.db.backends.sqlite3`` or to PostgreSQL with
# ``django.db.backends.postgresql_psycopg2``
'ENGINE': 'django.db.backends.mysql',
'NAME': 'sentry',
'USER': 'sentry',
'PASSWORD': '<password>',
'HOST': '',
'PORT': '',
}
}
...
# Установите в False чтобы требовать авторизацию
SENTRY_PUBLIC = False
...
# Укажите URL по которому будет находиться ваш Sentry
# SENTRY_URL_PREFIX = 'http://www.example.org/sentry'
SENTRY_URL_PREFIX = "http://sentry.example.org"
Install MySQL-python as well:
pip install MySQL-python
Connect to our mysql-server:
$ mysql -uroot -p
mysql> CREATE DATABASE sentry CHARSET utf8 COLLATE utf8_general_ci;
mysql> SELECT password('<PASSWORD>');
mysql> GRANT USAGE ON sentry.* TO 'sentry'@'localhost' IDENTIFIED BY PASSWORD '<PASSWORD_HASH>';
mysql> GRANT ALL PRIVILEGES ON `sentry`.* TO 'sentry'@'localhost';
Set up proxying through Nginx:
server {
listen 80;
server_name sentry.example.org;
location / {
proxy_pass http://localhost:9000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Now create a configuration file for supervisor:
[program:sentry]
directory=/var/www/sentry
command=/var/www/sentry/bin/sentry --config=/etc/sentry.conf start http
autostart=true
autorestart=true
redirect_stderr=true
And start the web server:
sudo supervisorctl start sentry
sudo nginx -s reload
If for some reason you don’t use supervisor, you need to start Sentry like this:
sentry --config=/etc/sentry.conf start
You can read the rest in the documentation, and read about running Sentry in this section of the documentation.
Adding a superuser
Run this and enter a username, password, and email address—in short, the usual procedure for a Django project:
sentry --config=/etc/sentry.conf createsuperuser
If you get this error:
Traceback (most recent call last): ... TypeError: decode() argument 1 must be string, not NoneThen set the language in the console and run
createsuperuseragain:export LANG="ru_RU.UTF-8" sentry --config=/etc/sentry.conf createsuperuser
Adding new users is a two-step process: first create the user in the admin interface at http://sentry.example.org/admin/auth/user/, then add them in the project settings.
Client-side settings
Since I have a Django-based project, I’ll show how to configure it for Django 1.4.2. Log in at http://sentry.example.org/,, where you’ll be asked to enter a “project name” and “your team name.” You’ll then be redirected to the “documentation for configuring the client for your project” page.
First, install raven (the client for Sentry):
pip install raven
The documentation for configuring raven and Django is here.
Specify the following settings in your project’s <project>/settings.py (more precisely, in local_settings.py):
# Этот DSN вы получите на странице "документации по настройке клиента для вашего проекта"
SENTRY_DSN = 'http://<PUBLIC_KEY>:<SECRET_KEY>@sentry.example.org/2'
# Добавьте raven в INSTALLED_APPS
INSTALLED_APPS = (
# ...
'raven.contrib.django',
)
# Теперь настроим LOGGING
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'root': {
'level': 'WARNING',
'handlers': ['sentry'],
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
},
'handlers': {
'sentry': {
'level': 'ERROR',
'class': 'raven.contrib.django.handlers.SentryHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'django.db.backends': {
'level': 'ERROR',
'handlers': ['console'],
'propagate': False,
},
'raven': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
'sentry.errors': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': False,
},
}
}
Wrap WSGIHandler in Sentry, in the file <project>/wsgi.py:
from django.core.handlers import wsgi
from raven.contrib.django.middleware.wsgi import Sentry
application = Sentry(wsgi.WSGIHandler())
An example uWSGI-configuration, in the file <project>/uwsgi/production.ini:
[uwsgi]
chdir=/path/to/<project>
pidfile=/var/run/<project>/uwsgi.pid
socket=/var/run/<project>/uwsgi.sock
chmod-socket=777
virtualenv=venv
pythonpath=.
pythonpath=<project>
module=<project>.wsgi:application
env=DJANGO_SETTINGS_MODULE=<project>.settings
master=true
processes=10
harakiri=30
buffer-size=32768
procname-prefix=<project>_
That’s basically it: Sentry solved the problem of collecting “exceptions” and provided a convenient interface for working with them! I recommend giving this wonderful tool a try!
Comments are closed. Read the original discussion in Russian →
