Sentry: запуск self-hosted версии системы мониторинга ошибок на AWS EC2

Автор: | 05/18/2019
 

Для проекта мы пользовались Cloud-based версией Sentry, но в один прекрасный день исчерпали лимит на отправку сообщений, и бекенд-команда, по сути, осталась без мониторинга.

Давно собирались запустить Sentry на своём сервере, появился повод.

В посте описывается запуск Sentry с Docker Compose, настройка почты и пример перехвата ошибок в Python.

Используем репозиторий Sentry.

Запускаем AWS EC2, настраиваем SSL от Let’s Encrypt, NGINX, устанавливаем Docker и Docker Compose.

Эти шаги в деталях описаны в посте Bitwarden: менеджер паролей организации — установка self-hosted версии на AWS EC2.

Используем EC2 тип t3.medium, т.к. требуется минимум 3 ГБ памяти.

Запуск Sentry

Клонируем репозиторий:

root@bttrm-sentry:/home/admin# mkdir /opt/sentry
root@bttrm-sentry:/home/admin# cd /opt/sentry/
root@bttrm-sentry:/opt/sentry# git clone https://github.com/getsentry/onpremise.git
root@bttrm-sentry:/opt/sentry# cd onpremise/

Создаём Docker Volumes для данных Sentry и его базы данных PostgreSQL:

root@bttrm-sentry:/opt/sentry/onpremise# docker volume create --name=sentry-data && docker volume create --name=sentry-postgres
sentry-data
sentry-postgres

Создаём файл настроек:

root@bttrm-sentry:/opt/sentry/onpremise# cp -n .env.example .env

Собираем образы:

root@bttrm-sentry:/opt/sentry/onpremise# docker-compose build
smtp uses an image, skipping
memcached uses an image, skipping
redis uses an image, skipping
postgres uses an image, skipping
Building web
Step 1/1 : FROM sentry:9.1-onbuild
9.1-onbuild: Pulling from library/sentry
...
Successfully built 4840fec904c8
Successfully tagged onpremise_worker:latest

Генерируем SECRET_KEY:

root@bttrm-sentry:/opt/sentry/onpremise# docker-compose run --rm web config generate-secret-key
Creating network "onpremise_default" with the default driver
Pulling smtp (tianon/exim4:)...
latest: Pulling from tianon/exim4
...
Status: Downloaded newer image for tianon/exim4:latest
Pulling memcached (memcached:1.5-alpine)...
1.5-alpine: Pulling from library/memcached
...
Status: Downloaded newer image for memcached:1.5-alpine
Pulling redis (redis:3.2-alpine)...
3.2-alpine: Pulling from library/redis
...
Status: Downloaded newer image for redis:3.2-alpine
Pulling postgres (postgres:9.5)...
9.5: Pulling from library/postgres
...
Creating onpremise_smtp_1      ... done
Creating onpremise_postgres_1  ... done
Creating onpremise_memcached_1 ... done
Creating onpremise_redis_1     ... done
y0%***1yz

Последняя строка, с y0%***1yz — ключ.

Редактируем файл .env, задаём в нём SECRET_KEY.

Заполняем базу данных, и создаём первого пользователя:

root@bttrm-sentry:/opt/sentry/onpremise# docker-compose run --rm web upgrade
Starting onpremise_redis_1    ... done
Starting onpremise_postgres_1  ... done
Starting onpremise_memcached_1 ... done
Starting onpremise_smtp_1      ... done
12:06:24 [WARNING] sentry.utils.geo: settings.GEOIP_PATH_MMDB not configured.
12:06:27 [INFO] sentry.plugins.github: apps-not-configured
Syncing...
Creating tables ...
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table south_migrationhistory
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
Migrating...
Running migrations for sentry:
- Migrating forwards to 0472_auto__add_field_sentryapp_author.
...
Created internal Sentry project (slug=internal, id=1)
Would you like to create a user account now? [Y/n]: y
Email: admin@example.com
Password:
Repeat for confirmation:
Should this user be a superuser? [y/N]: Y
User created: admin@example.com
Added to organization: sentry
...

Запускаем:

root@bttrm-sentry:/opt/sentry/onpremise# docker-compose up
onpremise_redis_1 is up-to-date
onpremise_memcached_1 is up-to-date
onpremise_postgres_1 is up-to-date
onpremise_smtp_1 is up-to-date
Creating onpremise_worker_1 ... done
Creating onpremise_web_1    ... done
Creating onpremise_cron_1   ... done
...

Проверяем контейнеры:

root@bttrm-sentry:/opt/sentry/onpremise# docker ps

Открываем в браузере, проверяем, что Sentry работает:

Логинимся, можно сразу настроить отправку почты, я сделал позже, через AWS SES:

Ждём Далее, убеждаемся, что всё ОК:

Что с worker? Пока не ясно, а потом само пропало.

Останавливаем контейнеры, создаём systemd unit-файл — /etc/systemd/system/sentry.service:

root@bttrm-sentry:/opt/sentry/onpremise# systemctl edit --force sentry

Указываем:

[Unit]
Description=Sentry service
Requires=docker.service
After=docker.service

[Service]
Restart=always
WorkingDirectory=/opt/sentry/onpremise

# Compose up
ExecStart=/usr/local/bin/docker-compose -f docker-compose.yml up

# Compose down, remove containers and volumes
ExecStop=/usr/local/bin/docker-compose -f docker-compose.yml down -v

[Install]
WantedBy=multi-user.target

В случае ошибки при старте вида:

May 18 12:38:33 bttrm-sentry systemd[1]: sentry.service: Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.

Добавляем ещё один ExecStart, пустой:

[Unit]
Description=Sentry service
Requires=docker.service
After=docker.service

[Service]
Restart=always
WorkingDirectory=/opt/sentry/onpremise

# Compose up
ExecStart=
ExecStart=/usr/local/bin/docker-compose -f docker-compose.yml up

# Compose down, remove containers and volumes
ExecStop=/usr/local/bin/docker-compose -f docker-compose.yml down -v

[Install]
WantedBy=multi-user.target

Не встречал такого раньше, решение нагуглено тут>>>.

Запускаем:

root@bttrm-sentry:/opt/sentry/onpremise# systemctl start sentry

Проверяем статус:

root@bttrm-sentry:/opt/sentry/onpremise# systemctl status sentry
● sentry.service - Sentry service
Loaded: loaded (/etc/systemd/system/sentry.service; disabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/sentry.service.d
└─override.conf
Active: active (running) since Sat 2019-05-18 12:39:21 UTC; 12min ago
Main PID: 9209 (docker-compose)
CPU: 643ms
CGroup: /system.slice/sentry.service
├─9209 /usr/local/bin/docker-compose -f docker-compose.yml up
└─9210 /usr/local/bin/docker-compose -f docker-compose.yml up
May 18 12:44:24 bttrm-sentry docker-compose[9209]: redis_1      | 1:M 18 May 12:44:24.080 * 100 changes in 300 seconds. Saving...
May 18 12:44:24 bttrm-sentry docker-compose[9209]: redis_1      | 1:M 18 May 12:44:24.081 * Background saving started by pid 11
May 18 12:44:24 bttrm-sentry docker-compose[9209]: redis_1      | 11:C 18 May 12:44:24.086 * DB saved on disk
May 18 12:44:24 bttrm-sentry docker-compose[9209]: redis_1      | 11:C 18 May 12:44:24.086 * RDB: 0 MB of memory used by copy-on-write
May 18 12:44:24 bttrm-sentry docker-compose[9209]: redis_1      | 1:M 18 May 12:44:24.181 * Background saving terminated with success
May 18 12:49:25 bttrm-sentry docker-compose[9209]: redis_1      | 1:M 18 May 12:49:25.066 * 100 changes in 300 seconds. Saving...
May 18 12:49:25 bttrm-sentry docker-compose[9209]: redis_1      | 1:M 18 May 12:49:25.066 * Background saving started by pid 12
May 18 12:49:25 bttrm-sentry docker-compose[9209]: redis_1      | 12:C 18 May 12:49:25.072 * DB saved on disk
May 18 12:49:25 bttrm-sentry docker-compose[9209]: redis_1      | 12:C 18 May 12:49:25.073 * RDB: 0 MB of memory used by copy-on-write
May 18 12:49:25 bttrm-sentry docker-compose[9209]: redis_1      | 1:M 18 May 12:49:25.167 * Background saving terminated with success

Окей, работает.

Добавляем в автозагрузку:

root@bttrm-sentry:/opt/sentry/onpremise# systemctl enable sentry

Email

Документация по настройке почты — тут>>>.

Редактируем docker-compose.yml, задаём переменные, тут пример для AWS SES:

...
    SENTRY_EMAIL_HOST: email-smtp.us-east-1.amazonaws.com
    SENTRY_EMAIL_PORT: 587
    SENTRY_EMAIL_PASSWORD: BH3***gpM
    SENTRY_EMAIL_USER: AKI***OAQ
    SENTRY_EMAIL_USE_TLS: "true"
    SENTRY_SERVER_EMAIL: no-reply@example.com
...

Обратите внимание, что «true» передана в кавычках:

SENTRY_EMAIL_USE_TLS: «true»

Сохраняем, перезапускаем:

root@bttrm-sentry:/opt/sentry/onpremise# systemctl restart sentry

Python Sentry

Создаём новый проект:

Сразу получаем токен:

Проверяем с рабочей машины — устанавливаем sentry-sdk:

[setevoy@setevoy-arch-work ~ ] $ sudo pip install sentry-sdk
[setevoy@setevoy-arch-work ~ ] $ python
...
>>> import sentry_sdk
>>> sentry_sdk.init("https://96e***c44@sentry.example.com/2")
<sentry_sdk.hub._InitGuard object at 0x7efd4c487128>
>>> sentry_sdk.capture_message("Hello World")
'736347c534cb4e3eb27fb3e3c0641439'

Проверяем события в Sentry:

И почту:

Готово.