Sentry: мониторинг и отслеживание ошибок
О проекте
Sentry — это платформа для отслеживания ошибок и мониторинга приложений. Данные, которые мы получаем в Sentry, содержат исчерпывающую информацию о контексте, в котором это произошло, что облегчает воспроизведение и поиск причины и значительно помогает в устранении ошибок. Хороший друг для разработчиков, тестировщиков и DevOps.
Это open-source проект, который можно развернуть и использовать на своем или облачном сервере.
Sentry начинался как web для отображения trace - exception в удобной форме и с группировкой по типу. С течением времени он разрастался дополнительными функциями, возможностями, интеграциями. Полностью показать и рассказать, на что он способен, в одной статье не получится, и даже краткий видеообзор займет часа три.
Зачем Sentry, когда есть логирование?
Просмотреть логи и узнать, что происходит с сервисом, — хорошо. Когда логи со всех сервисов собираются в одном месте, как Elastiс, OpenSearch, Loki — отлично.
Но анализировать ошибки и исключения можно быстрее, удобнее и подробнее как раз в Sentry. Бывают случаи, когда анализ логов не помогает понять проблему, а Sentry спасает.
Могут быть и другие ситуации, когда пользователь вашего сервиса не смог войти в учетку, купить товар или сделать что-то еще, и не стал писать тикет в саппорт, а просто ушел.
В логах такое выявить крайне сложно. И даже если в саппорт оставили обращение о проблеме, проанализировать, выявить и воспроизвести такую специфическую ошибку может дорого стоить:
- С какого устройства и каким браузером пользовались?
- Какая функция и из-за чего вызвала ошибку? Какую ошибку?
- Какие данные были на фронте, что отправилось в бэк?
- …
Самое главная «фишка» Sentry — предоставление в удобной форме подробной контекстной информации об ошибках, что позволяет быстрее реагировать и улучшать разработку.
Как заявляют разработчики проекта на своем сайте, «ваш код скажет вам больше, чем то, что показывают логи. Полный мониторинг стека Sentry покажет более полную картину того, что происходит в коде сервиса, и поможет выявлять проблемы до того, как они приведут к простою».
Как это работает?
В коде своего приложения мы устанавливаем DSN (URL) своей платформы, куда будут отправляться отчеты (ошибки, исключения, логи). При желании можно расширять, дорабатывать, скрывать (маскировать) отправляемые данные.
Поддерживаемые платформы и языки
Продукт поддерживает JavaScript, Node, Python, PHP, Ruby, Java и другие языки программирования.
Форма добавления проекта
На скриншоте видно, что есть как просто Python-проект, так и Django, Flask, FastAPI, в котором уже за нас в более удобной и детальной форме используются данные для отправки отчетов.
Варианты использования
Sentry может использоваться в следующих вариантах:
- Self-hosted (поднятый на своем сервере)
- Облачный (есть ограниченная бесплатная версия и платные с ежемесячной оплатой)
Developer — бесплатная облачная версия для знакомства
Лимиты версии Developer:
Тем, кого заинтересовал Sentry, я рекомендую попробовать хотя бы бесплатную облачную версию, она вполне подойдет для знакомства, а еще лучше — вариант на собственном сервере, т.к. задержки в ошибках облачной версии могут быть от 1 до 5 мин., что не очень удобно.
Установка self-hosted версии
Теперь перейдем к технической части. Для развертывания нам нужен репозиторий getsentry/self-hosted. Платформа будет развернута в docker-compose
.
Системные требования
- Docker 19.03.6+
- Compose 2.0.1+
- 4 CPU Cores
- 8 GB RAM
- 20 GB Free Disk Space
Для демонстрации я буду использовать виртуальную машину от Timeweb Cloud с Ubuntu 22.04.
Подготовка
Обновляем зависимости:
apt update && apt upgrade -y
Устанавливаем необходимые пакеты.
Для Docker apt
предлагает версию 20.10.24, установим ее.
apt install docker.io
Для docker-compose
— apt
предлагает установить версию 1.29.2-1. Она не сходится с требуемой, поэтому стандартная установка не подойдет. Потребуется устанавливать вручную с официального репозитория.
Получим последнюю версию в переменную:
VERSION=$(curl --silent https://api.github.com/repos/docker/compose/releases/latest | grep -Po '"tag_name": "\K.*\d')
Осталось скачать по указанному пути и выдать права:
DESTINATION=/usr/bin/docker-compose
sudo curl -L https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-$(uname -s)-$(uname -m) -o $DESTINATION
sudo chmod 755 $DESTINATION
Проверим:
docker-compose --version
Вывод:
Docker Compose version v2.20.3
Установка
Разработчики Sentry максимально упростили установку с помощью скрипта.
Выбираем и клонируем репозиторий и релизную ветку:
git clone https://github.com/getsentry/self-hosted.git
git checkout 23.8.0
cd self-hosted
Установка:
./install.sh --skip-user-prompt --no-report-self-hosted-issues
Флаги:
--skip-user-prompt
— пропустить запрос создания пользователя (создадим его отдельной командой, так будет проще).--no-report-self-hosted-issues
— пропустить запрос для анонимной отправки данных разработчикам Sentry с вашего хоста (помогает разработчикам улучшать продукт, но немного отъедает ресурсов; решите для себя, нужно ли вам это).
Начинается процесс проверки соответствия требованиям и скачивание необходимых образов (docker pull
).
После будет выведено сообщение, что можно запустить Sentry:
You're all done! Run the following command to get Sentry running:
docker-compose up -d
Запустим:
docker-compose up -d
И теперь уже по IP-адресу хоста по порту 9000 доступен веб-интерфейс.
Но мы пропустили создание пользователя. Сделаем это сейчас с помощью команды:
docker-compose run --rm web createuser
Вводим email, пароль и отвечаем на вопрос: Давать ли права суперпользователя этому пользователю?
При первом входе откроется окно первоначальной настройки, где можно указать URL, настройки почтового сервера для отправки писем, и разрешить самостоятельную регистрацию остальным пользователям.
На этом в целом Sentry готов к работе, подробнее про конфигурацию можно почитать тут.
Основные файлы конфигурации:
.env
self-hosted/sentry/config.yml
self-hosted/sentry/sentry.conf.py
По умолчанию поднимается 42 контейнера, и в конфигах есть что настроить.
Сразу возникает вопрос: зачем столько контейнеров? Можно ли убрать лишнее и собрать минимальную сборку?
Нет, на данный момент нельзя — из-за сложных архитектурных связей.
В .env
—файл добавляю переменную SENTRY_BEACON = False
. Она позволяет разработчикам собирать приватную статистику для улучшения продукта, я хочу ее отключить.
Срок хранения событий можно также изменить здесь, по умолчанию он равен 90 дням:
SENTRY_EVENT_RETENTION_DAYS=90
Данные проектов и учетные записи пользователей хранятся в PostgreSQL. Можно легко поменять в конфигах на свою DB, а также использовать свой Redis.
Осталось самостоятельно настроить HTTPS proxy для доступа к web-интерфейсу. В документации нет конкретных указаний, рекомендуют использовать любой reverse proxy на ваше усмотрение. После настройки обратного прокси-сервера, нужно будет изменить system.url-prefix
в файле config.yml
и обновить раздел SSL/TLS
в sentry/sentry.conf.py
.
Настройка и подключение первого проекта
Создание проекта
Нажимаем «Добавить новый проект» и выбираем платформу.
После этого для проекта генерируется его уникальный ID, который нужно будет использовать в приложении.
Обратите внимание на переменную traces_sample_rate=1.0
и комментарии от разработчиков. Чтобы не перезагружать платформу тысячами однотипных ошибок, рекомендуется настроить данную переменную. При указании 1.0 будут отправляться 100% всех событий, а, например, при 0.25 — 25%.
О дополнительных параметрах sentry_sdk
можно почитать в документации. На скрине выше показан пример использования.
Мы немного усложним пример из документации, добавив зависимые функции и свой Exception
.
import sentry_sdk
sentry_sdk.init(
dsn="http://979bc0c738a5e4d8b4709e50247035c7@sentry.akmalov.com:9000/3", # Ссылка DSN с ID=3 получаем при создании проекта
traces_sample_rate=1.0,
environment="production", # Возможность добавить среду выполнения
release="my-app-1.0.0", # Релизная версия приложения
send_default_pii=True,
)
class MyException(Exception):
pass
def my_function(user, email):
raise MyException(f"User {user} ({email}) encountered an error.")
def create_user():
print("Создадим пользователя")
my_function('Artur', 'artur@akmalov.com')
if __name__ == "__main__":
sentry_sdk.capture_message("Просто захотелось отправить сообщение")
create_user()
Запускаю скрипт:
python main.py
В результате в Sentry получаем следующее:
Новый issue
В тэгах отображаются переменная среды, версия релиза и даже имя сервера (hostname
):
На скрине видно подробную трассировку и переходы по функциям из скрипта, а также переменные, которые в них использовались:
И даже версии используемых пакетов:
Итоги
В этой статье мы рассмотрели, что такое Sentry и для чего ее использовать. Надеюсь, мне удалось заинтересовать вас ею достаточно, чтобы вы почитали документацию или попробовали Sentry в работе.
Несмотря на то, что это громоздкая платформа, ее легко установить и настроить. Самое главное — не забывать следить, закрывать, группировать и гибко настраивать события, чтобы не получилось хаоса, и тогда Sentry станет очень полезным и удобным инструментом для команды разработки.