Оригинальная статья "
Я люблю получать сообщения по e-mail, особенно, если они начинаются со слов “[Django] Error…”. Готов поспорить, что 95% всех Django-проектов на промышленных площадках использует для слежения за ошибками именно электронную почту. У нас, в
К счастью, есть отличный инструментальный пакет, который называется
Позвольте, я попытаюсь "продать" вам этот пакет, просто перечислив некоторые его характеристики из
- Интеллектуальная группировка сообщений об ошибках.
- Идентификация ошибок серверов, функций и URL.
- Направление потока ошибок в список по мере их возникновения, без необходимости в ручном обновлении списка.
В данной статье я покажу, как создать и настроить сервер журналирования, и как испытать его на вашем локальном Django-проекте. На моем сервере работает FreeBSD, но вы можете использовать мои инструкции для любой *Nix-системы.
Журналирование через UDP
Sentry использует соединение по протоколу TCP (HTTP). Это не очень здорово для журналирования, потому что этот протокол работает медленно из-за своей "гарантированной доставки". Для не слишком критичных приложений, таких, как журналирование, лучше подходит соединение по UDP. В данный момент последняя стабильная версия Sentry не поддерживает UDP. Однако для тех, кому важна производительность, версия с поддержкой UDP уже в работе и
Установка Sentry
Вначале добудьте себе сервер. Я взял свой на
Нашей базой данных будет PostgreSQL. Я не буду описывать процесс ее установки, поскольку это уже описано другими. Вот руководства для
Debian
Ubuntu
FreeBSD
Сервер PostgreSQL установлен? Хорошо! Давайте создадим базу данных для Sentry:
# Переключиться на пользователя pgsql
# Для Debian/Ubuntu это postgres
sudo su - pgsql
# Создать пользователя, ответить 'n' на все вопросы о роли
createuser -P pg_sentry
# Создать базу данных
createdb db_sentry -O pg_sentry --encoding=UNICODE
Мы установим
На FreeBSD перейдите в каталог /usr/ports/devel/py-pip, и выполните команду make install clean от имени root. Для других систем прочтите
pip install virtualenv
pip install virtualenvwrapper
Virtualenvwrapper требует правильной настройки среды окружения. Вот мои настройки из .zshrc, помещающие все виртуальные среды в каталог ~/.virtualenvs. Если у вас Bash, добавьте эти настройки в ваш .bashrc.
export WORKON_HOME=$HOME/.virtualenvs
# Проверить, установлена ли virtualenvwrapper, если да, запустить!
# Как видите, моя virtualenvwrapper находится в
# `/usr/local/bin/` но у вас это может быть `/usr/bin/`
if [ -e "/usr/local/bin/virtualenvwrapper.sh" ]; then
source /usr/local/bin/virtualenvwrapper.sh
fi
Выйдите из системы и зайдите снова, чтобы изменения вступили в силу. Если все прошло хорошо, вы получите сообщения об установке скриптов в каталоге .virtualenvs. Теперь все готово для создания виртуальной среды sentry:
mkdir ~/sentry
mkvirtualenv sentry
Ваша виртуальная среда будет активирована, когда вы вызовете скрипт mkvirtualenv, но не забудьте активировать ее снова при помощи workon sentry в следующий раз, когда будете работать с проектом sentry. Все теперь готово, пора установить Sentry. Я люблю работать с файлом требований (requirements) и с pip, поэтому давайте создадим файл requirements.txt в нашем каталоге sentry и заполним его требованиями для Sentry.
touch ~/sentry/requirements.txt
echo "Django==1.3.1" >> ~/sentry/requirements.txt
echo "sentry==2.0.0-RC6" >> ~/sentry/requirements.txt
echo "psycopg2==2.4.2" >> ~/sentry/requirements.txt
Вам не требуется добавлять в файл требований Django, поскольку Sentry позаботится обо всех зависимостях. Но нам нужна последняя стабильная версия Django, поэтому мы поместили сюда это требование.
Теперь, выполним установку при помощи команды pip install -r ~/sentry/requirements.txt. Будет установлено множество библиотек, но в результате вы должны увидеть:
Successfully installed Django sentry django-paging django-indexer django-templatetag-sugar raven python-daemon eventlet South kombu django-kombu simplejson lockfile greenlet anyjson amqplib psycopg2 Cleaning up…"
Нам нужно инициализировать конфигурацию базы для Sentry. Следующая команда создаст файл конфигурации в каталоге sentry :
sentry init ~/sentry/sentry.conf.py
Отредактируем конфигурацию. У меня получилось, в итоге, следующее:
import os.path
from sentry.conf.server import *
ROOT = os.path.dirname(__file__)
DATABASES = {
'default': {
# Используется база данных PostgreSQL, которую мы создали ранее
'ENGINE': "django.db.backends.postgresql_psycopg2",
'NAME': "db_sentry",
'USER': 'pg_sentry',
'PASSWORD': 'your_password',
'HOST': 'localhost',
}
}
SENTRY_KEY = "SOME_KEY"
# Установите позднее в false, чтобы требовалась аутентификация
SENTRY_PUBLIC = True
SENTRY_WEB_HOST = '0.0.0.0'
SENTRY_WEB_PORT = 9000
Обратите внимание, мы сохранили для SENTRY_PUBLIC значение True. Это сделано для того, чтобы упростить тестирование в дальнейшем. При переходе к реальной работе нужно будет вернуть значение False. Остальные настройки говорят сами за себя.
Довольно неудобно будет указывать местонахождение конфигурации Sentry при выполнении каждой команды. Поскольку Sentry ищет свою конфигурацию в каталоге ~/.sentry/sentry.conf.py, давайте добавим туда символическую ссылку.
mkdir ~/.sentry
ln -s ~/sentry/sentry.conf.py ~/.sentry/sentry.conf.py
Прежде чем запускать Sentry, нужно еще инициализировать базу данных:
cd ~/sentry
sentry upgrade
Теперь мы можем запустить сервер следующей командой:
cd ~/sentry
sentry start
Если порт у вас открыт, то вы можете теперь зайти на веб-сервер по порту 9000, например, http://example.com:9000
Nginx
Не очень удобно каждый раз заходить на сервер по порту “9000”, а в то же время имеется мощный сервер, хорошо подходящий для работы со статическим контентом. Давайте установим Nginx и используем его в качестве прокси для Sentry. На FreeBSD установить Nginx можно, перейдя в каталог /usr/ports/www/nginx и выполнив команду install clean от имени root. Добавьте строку nginx_enable="YES" в файл /etc/rc.conf, чтобы Nginx стартовал при загрузке системы. Запустите сервер при помощи следующей команды от имени root:
/usr/local/etc/rc.d/nginx start
Nginx для Ubuntu или Debian устанавливается также просто, достаточно заглянуть в одно из руководств в
Помните, однако, что Ubuntu и Debian работают с каталогом sites_enabled ,который они включают в основную конфигурацию. Вам в этом случае необходимо вставить раздел server { … } внутрь того файла. Например, /etc/nginx/sites-enabled/sentry.conf.
# На Ubuntu/Debian это, обычно, www-data
# На FreeBSD - www
user www www;
# Рабочие процессы, по 1 на процессор
worker_processes 2;
error_log /var/log/nginx-error.log;
# Оптимизация
worker_rlimit_nofile 8192;
events {
worker_connections 8000;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx-access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
keepalive_timeout 20;
# Оптимизация доступа к файлу
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
# Gzipping
gzip on;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_proxied any;
gzip_min_length 512;
gzip_buffers 4 8k;
gzip_vary on;
gzip_types
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
# Некоторые версии IE не понимают сжатие на некоторых типах mime
# поэтому, для них, отключим
gzip_disable "MSIE [1-6]\.";
server {
listen 80;
# Заменить именем своего хоста
server_name sentry.example.com;
access_log /home/example/sentry/logs/nginx-access.log;
# Задать кодировку
charset utf-8;
# Разрешить Nginx работать со статическими данными. Убедитесь,
# что указали их верное местоположение
location /_static {
alias /home/example/.virtualenvs/sentry/lib/python2.7/site-packages/sentry/static/;
expires 14d;
access_log off;
}
# Прокси для Sentry
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;
}
}
}
Перезапустите Nginx и вернитесь в каталог Sentry. Запустите Sentry следующим образом:
cd ~/sentry
sentry start --config=sentry.conf.py
Когда вы теперь зайдете на сервер своим браузером, то увидите страницу Sentry без необходимости добавлять номер порта - ":9000". Но вам вряд ли захочется запускать Sentry каждый раз вручную, поэтому давайте установим “Supervisor” для контроля над процессом.
Супервизор
Для установки супервизора в FreeBSD достаточно перейти в каталог /usr/ports/sysutils/py-supervisor и выполнить команду install clean от имени root. Для того, чтобы супервизор запускался при загрузке, добавьте в /etc/rc.conf следующую строку:
supervisord_enable="YES"
Запустите теперь супервизор командой от имени root:
/usr/local/etc/rc.d/supervisord start
Если у вас используется система, отличная от FreeBSD, следуйте указаниям из документации
Для слежения за процессом Sentry при помощи Supervisor, добавьте следующие строки в файл supervisord.conf. На FreeBSD он расположен в каталоге /usr/local/etc/supervisord.conf. (Конечно, снова замените "example" на имя вашего пользователя, выполняющего Sentry):
[program:sentry]
directory=/home/example/sentry
command=/home/example/.virtualenvs/sentry/bin/sentry start --config=/home/example/sentry/sentry.conf.py
user=example
umask=022
autostart=True
autorestart=True
redirect_stderr=True
Для того чтобы супервизор смог найти этот новый раздел, нам необходимо перезагрузить его конфигурацию командой supervisorctl reload от имени root. Проверьте, все ли работает правильно - для этого перезапустите свой VPS-сервер. Будем исходить из того, что все прошло гладко (а если нет, то из того, что вы хороший отладчик). Последний шаг состоит в том, чтобы защитить Sentry при помощи авторизации. Добавьте суперпользователя следующими командами:
workon sentry
cd ~/sentry
sentry manage createsuperuser --config=sentry.conf.py
Отредактируйте ваш файл sentry.conf.py и задайте:
SENTRY_PUBLIC = False
Перезапустите Sentry, чтобы новая конфигурация вступила в силу (команда supervisorctl restart sentry от имени root). Теперь откройте свой веб-сайт Sentry - все работает!
Интеграция с вашим Django-проектом
Подключение вашего Django-проекта к Sentry требует наличия Sentry-клиента. Для Python таким клиентом является
Затем следуйте инструкциям из документации Raven
Если вы настроили LOGGING в соответствии с описанной конфигурацией, вы можете проверить систему, добавив в нее одно из ваших представлений "view", и открыв его в браузере. Вы должны увидеть сообщение об ошибке без ручного обновления сервера Sentry.
import logging
# Получить экземпляр logger
logger = logging.getLogger(__name__)
logger.error('There was some crazy error',
exc_info=True,
extra={'request': request,})
Собственно журналирование
Ваша система централизованного журналирования работает. Самое время объяснить своим сотрудникам, как она устроена! Полезно будет также прочесть