Amereco Crash Reports
Приём краш-репортов и логов от AmerecoLauncher — плагин WordPress
by Lanode · github.com/merkel-games/amereco-crashreports · website
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.zipReadme
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, имя пользователя ОС и игровой чат вырезаются на клиенте до отправки. Сырой лог едет отдельным запросом и только с отдельного согласия игрока.