Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Error tracking: Sentry и ловля ошибок в проде

Error tracking с Sentry: видеть ошибки прода до жалоб пользователей

Как настроить ловлю ошибок: Sentry-интеграция в Python, что добавлять к событиям и чего не логировать, группировка и алерты, self-hosted вариант и связь с инцидентами.

Прямой ответ

Error tracking — слой между логами и инцидент-процессом: система автоматически ловит необработанные исключения прода, группирует тысячи одинаковых падений в один «issue» с числом затронутых пользователей, показывает стектрейс с переменными, версию релиза и пользователя, и алертит при новом/возросшем — команда узнаёт об ошибке до тикета от клиента. Sentry — де-факто стандарт (SDK в две строки: sentry_sdk.init(dsn=...) + интеграция фреймворка — FastAPI/Django/Celery из коробки; события автоматически обогащаются релизом, окружением, request-контекстом). Четыре правила, без которых система тонет в шуме: не слать ожидаемые ошибки (валидация ввода, 404, «карта отклонена» — бизнес-норма, не инцидент — фильтр before_send/исключения в конфиге); обезличивать (в событии не должно быть паролей/токенов/полных данных карт — send_default_pii=False по умолчанию и scrub-конфиг; приватность логов целиком применима); алертить на новое и растущее, не на каждое событие (иначе канал игнорируют за неделю — алерт-дисциплина); привязывать к релизам (release=git-sha — видно, какой деплой принёс ошибку, и работает suspect commits). Self-hosted Sentry закрывает требования «данные не покидают контур» ценой тяжёлой инфраструктуры (Kafka/ClickHouse в составе — не «одна баночка»).

Интеграция: что летит и в каком виде

Минимум: sentry_sdk.init(dsn=os.environ["SENTRY_DSN"], environment="prod", release=..., traces_sample_rate=0.1) — необработанные исключения веб-запросов, фоновых задач (Celery-интеграция ловит падения воркеров — Celery), startup-ошибок улетают автоматически. Что добавляет ценность: контекст — sentry_sdk.set_user({"id": ...}) (кто затронут — «ошибка у 3 пользователей, все с тарифом X» сужает поиск), теги окружения/версии/фичи (feature flags в тегах — «ошибка только при включённом флаге» видно сразу), breadcrumbs — хлебные крошки последних действий (логи/HTTP-вызовы до падения — часто ценнее самого стектрейса). Явные события: capture_message для критичных состояний без исключения (расхождение данных, исчерпание пула), не для потока бизнес-событий (Sentry — не замена логам/метрикам: тысяча capture_message в минуту — тарифный лимит и шум). Производительность: traces_sample_rate — сэмплирование трейсов (трассировки APM рядом с ошибками — связка «ошибка + медленный запрос» в одном месте); частые ожидаемые исключения фильтруются (ignore_errors=[ValidationError, Http404]) до отправки — дешевле и чище. Release-привязка: CI передаёт git-sha в init и создаёт релиз в Sentry (deploy-маркеры на графиках — «пик ошибок начался ровно с деплоя 14:32» — деплой-стратегии получают обратную связь).

Группировка, шум и алерты

Группировка (fingerprinting) — как события становятся issue: по умолчанию — по стектрейсу (одно место падения = один issue, тысячи вызовов не засоряют список); проблемы дефолта: одна причина — разные стеки (обёртки/async — дробление: кастомный fingerprint по коду ошибки), разные причины — один стек (общий обработчик — сливание: fingerprint по деталям). Рабочий процесс поверх: triage — новый issue получает владельца и статус (acknowledged/ignore — игнор с причиной, не молчаливое зарытие); алерты — правила «новое issue» (в канал команды, без пейджа — новое почти никогда не требует ночи), «N событий за M минут» (пейдж дежурному — массовое падение), «затронуто >X пользователей» (бизнес-масштаб вместо технического); регрессионные алерты (issue в статусе resolved снова появляется — сигнал «фикс не сработал»). Ключевая метрика здоровья самой системы — отношение actionable-событий к шуму: если из 50 алертов в неделю действий требуют 5 — фильтры и правила перенастраиваются (alert fatigue — главная причина смерти error tracking в командах). И связка с инцидентами: issue с пейджем → инцидент-процесс (runbook-дисциплина); postmortem ссылается на Sentry-issue как артефакт разбора.

Границы: PII, self-hosted, стоимость

Приватность: стектрейсы и breadcrumbs содержат локальные переменные — среди них токены и персональные данные; меры: дефолтный scrubbing (пароли/ключи по именам), before_send-хук для доменной чистки (номера телефонов/карт регуляркой), политика «что мы готовы отправить в облако провайдера» фиксируется до интеграции, а не после утечки в чужой SaaS; для жёстких требований — self-hosted. Self-hosted Sentry — полный контроль данных ценой кластера (Postgres + Kafka + ClickHouse + ~20 сервисов в compose/k8s — ставить осознанно, с ресурсами на поддержку; альтернатива легче — GlitchTip ( Sentry-совместимый DSN, один Postgres, без APM) — для команд, которым нужна только ловля ошибок. Стоимость SaaS — по числу событий: бесконечный поток одной ошибки в цикле съедает квоту (rate limit на стороне SDK — max_events, и серверный rate limit issue — настройка проекта); ошибки в циклах ретраев — сэмплировать/агрегировать до отправки. Оценка до внедрения: событий/день ≈ запросы × текущая доля ошибок × сэмпл — обычно скромно; взрывается при инциденте (миллионы повторов — серверный лимит issue защищает счёт, но квоту месяца).

Практический сценарий: от «пользователь написал» к «увидели за минуту»

До: об ошибках прода команда узнаёт из тикетов («у меня не сохраняется корзина» — без деталей, воспроизвести не смогли, закрыли). Внедрение: Sentry SDK в FastAPI + Celery, release=git-sha из CI, environment по конфигу (env), ignore-список бизнес-ошибок, scrubbing полей оплаты в before_send; алерты: новое issue — в Slack, >50 событий/5 мин — пейдж. Первая же неделя: пик issue «TypeError в расчёте доставки» — 300 событий за час, затронуты 40 пользователей, тег release указывает свежий деплой, breadcrumbs показывают общий паттерн (заказы без города) — фикс за час вместо недели переписки с клиентами; suspect commits назвал строку — ревью пропущенного None. Через месяц статистика: 12 issue в триаже, 8 закрыты, доля «узнали от пользователей» среди ошибок с трейсом — ноль; отдельная находка — редкое issue в Celery-воркере (падение при битом PDF) жило месяцами незамеченным (логи ротировались, жалоб не было) — error tracking ловит именно «тихие» ошибки, которые логи теряют. Итог: стоимость — день настройки; эффект — время обнаружения с дней до минут.

FAQ

Sentry против логирования в journald/Loki — замена? Дополнение: логи — полный поток для расследований и аудита (агрегация); Sentry — исключения как сущности (группировка, триаж, алерты, контекст пользователя/релиза); «всё в логи и grep» теряет группировку и проактивность, «всё в Sentry» — дорого и не для потоковых данных.

Что делать с сотней legacy-issue при первом подключении? Не triage'ить всё подряд: отсортировать по частоте/пользователям, разобрать топ-10 (обычно дают 90% событий), остальные — bulk ignore с пересмотром по регрессии; «разобрать всё сразу» — путь к заброшенной системе через месяц.

Ловить ли ошибки фронтенда тем же Sentry? Да (JS-SDK — ошибки рендера, source maps для читаемых стеков, session replay опционально) — половина пользовательских проблем живёт в браузере и в серверные логи не попадает вовсе; отдельные проекты backend/frontend — разные команды триажа.

Нужен ли error tracking на стейдже/dev? Стейдж — да (отдельный environment/project — ловит то, что не воспроизвели локально, до прода); dev — нет (локальные падения видны в консоли; шум и квота без пользы).

Источники: документация Sentry (Python SDK, alerts), Sentry developer docs — ссылки в шапке.