Skip to content

Телеметрия ошибок

Встроенный крэш-репортёр: необработанные ошибки веба, бота и воркера не роняют процесс и не теряются в логах, а собираются на отдельный сервер приёма с дашбордом и Telegram-алертами. Вы видите падения раньше, чем клиент напишет в поддержку, и чините по готовому трейсу.

Куда шлётся по умолчанию

Из коробки репорты уходят на сервер приёма продукта — разработчики видят падения всех установок и чинят баги до вашего обращения. Выключается одной строкой TELEMETRY__ENABLED=false в .env; свой сервер приёма — TELEMETRY__URL=https://errors.<домен>/ingest. Коды ошибок для юзеров работают в любом случае, даже с выключенной отправкой.

Что видит юзер и владелец

Ошибка перестаёт быть тишиной или падением:

  • бот — юзеру уходит «⚠️ Что-то пошло не так… Код ошибки: E1a2b3c4d», бот продолжает работать;
  • web/API — чистый JSON {"ok": false, "detail": "внутренняя ошибка сервера", "error_id": "E…"}, без стектрейса наружу;
  • воркер — задача ретраится как раньше, ошибка дополнительно репортится.

Код ошибки детерминирован: один и тот же баг всегда даёт один и тот же E…-код. Юзер называет его в поддержке — на дашборде вы находите по нему точный трейс.

Что отправляется — и что вычищается

В событии: класс исключения, сообщение (до 500 символов), трейс с относительными путями (File "src/…" вместо абсолютных), источник (web/bot/worker), небольшой контекст (путь запроса / команда / имя задачи), версия приложения и анонимный id установки — необратимый хэш от токена бота.

Перед отправкой текст ошибки и трейс проходят скраб PII и секретов:

  • хвосты SQLAlchemy с SQL и подставленными параметрами вырезаются целиком;
  • строки вида телеграм-токена заменяются на <token>, email — на <email>;
  • длинные цифровые последовательности (Telegram ID, номера платежей) — на <id>;
  • абсолютные пути к домашним каталогам приводятся к относительным.

Данные юзеров, токены и конфиги не покидают сервер. Отправка fire-and-forget: события копятся в очередь и уходят батчами раз в ~30 секунд, повторы одной ошибки схлопываются в счётчик, недоступность сервера приёма ни на что не влияет — отправка просто отложится с бэкоффом.

Свой сервер приёма

Приёмник лежит в репозитории — каталог telemetry-server/: один файл server.py, SQLite, без внешней БД. Деплой на любой сервер:

bash
cd telemetry-server
cat > .env <<'EOF'
TS_DASH_USER=admin
TS_DASH_PASS=поменяй-меня
TS_INGEST_TOKEN=длинный-случайный-токен
EOF
docker compose up -d --build

Проверка: curl http://127.0.0.1:8088/health{"ok":true}. Сверху — nginx на поддомен вида errors.<домен> (проксирование на 127.0.0.1:8088, обязательно с заголовком X-Forwarded-For — по нему работает пер-IP rate-limit) и сертификат certbot.

ПеременнаяЧто делает
TS_DASH_USER / TS_DASH_PASSBasic Auth на дашборд; без них дашборд отдаёт 503
TS_INGEST_TOKENТокен приёма: POST /ingest требует заголовок X-Telemetry-Token. Ставьте всегда
TS_TG_BOT_TOKEN + TS_TG_CHAT_IDTelegram-алерты: 🆕 новая ошибка, ♻️ регрессия решённой
TS_DB_PATHПуть к SQLite (в контейнере уже /data/telemetry.db)

Дашборд группирует ошибки по fingerprint: счётчик повторов, затронутые установки и версии, трейс, кнопка resolve. Решённая ошибка уходит из списка, но вернётся сама — с алертом про регрессию, — если снова прилетит с установок. Алерты приходят только на новые проблемы и регрессии, не на каждое событие.

Подключение установки

В .env установки HUB-BOT:

bash
TELEMETRY__URL=https://errors.<домен>/ingest
TELEMETRY__TOKEN=длинный-случайный-токен   # тот же, что TS_INGEST_TOKEN приёмника

Один приёмник — много установок

Id установки — хэш от токена бота, поэтому на дашборде установки различимы, но не идентифицируемы. Если вы обслуживаете несколько магазинов, наведите их все на один сервер приёма и смотрите ошибки в одном месте.

Справочник кодов

Каждая ошибка теперь несёт номер класса проблемы (E5103-…) — расшифровка всех номеров в справочнике кодов ошибок.

MIT License · сделано для тех, кто продаёт VPN, а не настраивает ботов