WP Manifestindependent plugin directory
manifest / developer / amereco-crashreports

Amereco Crash Reports

Приём краш-репортов и логов от AmerecoLauncher — плагин WordPress

by Lanode · github.com/merkel-games/amereco-crashreports · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/merkel-games/amereco-crashreports/archive/refs/heads/master.zip

Readme

Amereco Crash Reports

Приём краш-репортов и логов от Amereco Launcher.

Плагин WordPress. Заменяет собой внешний сервис вроде Sentry: при аудитории в десятки-сотни игроков вся нужная функциональность — склейка одинаковых ошибок, счётчик попаданий, стектрейс и пометка «починено» — умещается в две таблицы и одну админ-страницу. Данные при этом не покидают сервер.

Почему отдельный плагин

Приёмнику нужно понимать, от кого пришёл отчёт, а токены живут в Authlib API. Соблазн положить код туда же есть, но диагностика — вспомогательная функция: её поломка не должна утаскивать за собой вход в игру. Поэтому плагины разные, а связь односторонняя и необязательная.

Связь с Authlib API

Единственная точка стыка — identity.php, функция identify(). Она через function_exists() ищет \AuthlibAPI\Utils\identify_by_token().

Что есть у отправителя Уровень доверия Что записывается
Живой Yggdrasil access-токен verified Настоящие ник и UUID из базы
Токена нет или протух, но клиент назвался claimed Ник со слов клиента, помечен как неподтверждённый
Ничего anonymous Только идентификатор установки

Если Authlib API не установлен или выключен, приём продолжает работать — просто ни один отчёт не получит verified, и админка об этом предупредит.

Приём открытый. Отчёт берётся и без токена. Токен нужен не для допуска, а для достоверности.

Эндпоинты

POST /wp-json/amereco-diag/v1/report   JSON, ≤ 64 КБ
POST /wp-json/amereco-diag/v1/log      multipart/form-data, gzip ≤ 1.2 МБ

Лаунчер ходит по форме ?rest_route=/amereco-diag/v1/report — она работает независимо от того, включены ли на сайте «красивые ссылки».

Токен передаётся в Authorization: Bearer <accessToken> и дублируется в X-Amereco-Token: первый заголовок на части конфигураций PHP до приложения не доходит.

Ответ на /report:

{"ok": true, "id": 123, "want_log": true, "attach_token": "9f2c…"}

want_log — нужен ли серверу лог. Он отвечает false, когда по этой ошибке уже сохранено три лога: четвёртая копия одного стектрейса ничего не добавляет. Клиент в этом случае не тратит трафик. Потолок проверяется и при самой загрузке: want_log — подсказка клиенту, а не ограничение, и верить ей на слово нельзя.

attach_token — одноразовый пропуск на догрузку лога, выдаётся только вместе с want_log: true. Без него хватило бы перебора последовательных report_id, чтобы приложить свой файл к чужому свежему отчёту. Гасится после первой загрузки.

Поля /log: report_id, attach_token, client_id, file.

Защита

Дверь открыта, поэтому всё держится на лимитах (limits.php, пороги в config.php):

  • потолок тела запроса — проверяется и по заголовку, и по фактически прочитанным байтам;
  • частота: 10 отчётов/час на установку, 30/час на IP, 3 лога/час;
  • суточная квота 20 МБ на установку;
  • общий потолок хранилища 2 ГБ с аварийным отключением приёма файлов;
  • лог можно приложить только к своему свежему отчёту, в течение часа и однократно.

Счётчик по IP проверяется до счётчика по установке: client_id подменяется клиентом, и обратный порядок позволил бы засорить wp_options транзиентами.

X-Real-IP учитывается, только если соединение пришло из приватной сети, то есть от своего nginx. Запрос снаружи такой заголовок себе не подделает.

IP-адреса не сохраняются. Для счётчика используется дневной HMAC.

Хранение логов

По умолчанию — /var/www/crashlogs, вне корня сайта. Файлы не доступны по прямому URL никогда: они отдаются только через админский обработчик с проверкой прав и nonce.

Смонтируйте каталог в контейнер:

  wordpress:
    volumes:
      - /srv/rpcraft-fabric/website/html:/var/www/html
      - /srv/rpcraft-fabric/website/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
      - /srv/rpcraft-fabric/website/crashlogs:/var/www/crashlogs

uploads.ini нужен потому, что в официальном образе wordpress upload_max_filesize = 2M, и превышение проявляется не ошибкой, а пустым $_FILES:

upload_max_filesize = 8M
post_max_size = 16M

Путь переопределяется в wp-config.php:

define('AMERECO_DIAG_DIR', '/var/www/crashlogs');

Если каталог недоступен, включается запасной путь в uploads со случайным суффиксом в имени, и админка выводит предупреждение. На .htaccess полагаться нельзя: nginx его не читает, а в контейнере apache стоит AllowOverride None.

Сроки хранения

Ежедневная задача amereco_diag_gc:

  • сырые логи — 30 дней;
  • структурированные отчёты — 90 дней;
  • группы без единого случая удаляются;
  • файлы-сироты старше суток удаляются.

Каждый прогон дописывает строку в gc-journal.log рядом с логами и дублирует её в админку. Это заготовка под подтверждение уничтожения персональных данных.

Что приходит в отчёте

Только перечисленное — на стороне лаунчера это явный список полей, а не дамп всего подряд: тип события, отпечаток, класс исключения, сообщение, стек, версии лаунчера/Java/ОС/игры/модлоадера, профиль сборки, размер кучи, профиль GC, код возврата игры, идентификатор установки, время.

Пароль, access-токен, e-mail, IP, имя пользователя ОС и игровой чат вырезаются на клиенте до отправки. Сырой лог едет отдельным запросом и только с отдельного согласия игрока.

Read the full README on GitHub →