Мониторинг error.log Xray: что такое XrayPulse и чем это может пригодиться

в 13:43, , рубрики: xray, XrayPulse

У кого на сервере крутится Xray, рано или поздно сталкивается с ошибками вerror.log: обрывы, таймауты, несовпадение SNI, исчерпанные попытки переподключения и прочая диагностика. Смотреть «хвостом» в консоли можно, но это плохо масштабируется: хочется понимать причины, динамику, кто к нам ломится — и желательно без тяжёлого стека вроде ELK на домашней VPS.

Я собрал XrayPulse — небольшой дашборд под эту задачу и залил на github, чтобы им могли воспользоваться другие. Ниже — что именно делает приложение, из чего оно состоит и какие решения мне кажутся стоящими внимания.

Мониторинг error.log Xray: что такое XrayPulse и чем это может пригодиться - 1

Что делает XrayPulse

  • Читает error.log, инкрементально подхватывает новые строки через фоновый планировщик, пишет нормализованные события в SQLite.

  • Парсер вытаскивает из строк IPv4/IPv6, контексты вроде SNI, приводит типы ошибок к виду, удобному для группировки и фильтров.

  • Дашборд: KPI за выбранный интервал, топ причин, тренд по времени, таблица истории с пагинацией.

  • Фильтры: типы ошибок, поиск по IP источника.

  • Детализация по типу ошибки: боковая панель со списком вхождений, сырой лог, копирование строки.

  • Обогащение IP (гео, провайдер, ASN) через внешний API с кэшем в БД и дневным лимитом запросов — чтобы случайно не упереться в квоты и не долбить внешний сервис без меры.

  • Аутентификация, блокировка после нескольких неудачных попыток с одного IP, опция доверия X-Forwarded-For за reverse-proxy — это важно, если дашборд висит за nginx.

Наработки, которыми хочется поделиться

1. Пагинация истории без «плывущего» OFFSET.

Для больших таблиц классический LIMIT со временем становится дорогим. В проекте для истории используется курсор (время + rowid), кодируемый в компактный токен (base64url + JSON) — клиент передаёт «куда крутить дальше», сервер строит запрос от якоря. Это простая схема без отдельной очереди сообщений, но заметно приятнее для SQLite на длинной истории. (Были мысли поднять ELK, но это слишком тяжелое решение для такой задачи).

2. Геолокация как опция с лимитом.

Обогащение IP выключаемо; при включении — кэш хранится в SQLite и есть дневной счётчик запросов к https://ipwho.is, чтобы нас не забанили.

3. Безопасность входа за прокси.

Советую поднимать сервис за nginx, а сам сервис в systemd или контейнере (кому как удобнее) для блокировки по IP нужен реальный адрес клиента — для этого есть отдельный флаг для чтения IP из X-Forwarded-For=true.

Ограничения и честные оговорки

  • Качество классификации и парсинга зависит от формата строк; под свои кейсы может понадобиться доработать parser.py и database.py, в котором описаны типовые ошибки с которыми я сталкивался при разработке дашборда.

  • Для продакшена имеет смысл явно задать FLASK_SECRET_KEY, иначе при каждом перезапуске XrayPulse сессии пользователя сбрасываются.

  • Добавить TLS в nginx.

Как попробовать

Репозиторий: https://github.com/modi-dev/XrayPulse  

Первый стабильный релиз: https://github.com/modi-dev/XrayPulse/releases/tag/v1.0.0

Кратко:

python -m venv .venv

pip install -r requirements.txt

cp .env.example .env

# задать DASHBOARD_USER, DASHBOARD_PASS, ERROR_LOG_PATH и при необходимости остальное

python app.py

Для локальной отладки без пароля в README описан режим AUTH_ENABLED=false.

Заключение

XrayPulse родился из практической потребности: быстрее понимать, что ломается у Xray, не превращая каждую ошибку в ручной археологический grep. Если идея откликается — забирайте код, открывайте issues и PR: проект небольшой, точки для улучшений наверняка найдутся.

Если инструмент оказался полезен, в README перечислены способы поддержки проекта — но это опционально; главная цель публикации — поделиться рабочим решением с теми, кто в той же лодке.

Автор: ne_sergo

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js