Наблюдаемость
Дашборд, /top, Prometheus, профиль тика и доступ к метрикам.
Сервер снимает нагрузку раз в секунду и отдаёт её без внешних агентов. Один и тот же снимок доступен из игры, из терминала, в браузере и в Prometheus.
| Способ | Когда нужен |
|---|---|
/top в игре | посмотреть нагрузку из чата, не переключаясь в терминал |
chunkwake top | разовый снимок или --watch в соседнем окне |
GET / в браузере | живой дашборд: графики за 15 минут, ядра, мир, сеть |
GET /metrics | Prometheus и Grafana |
GET /snapshot | chunkwake top и лаборатория, JSON |
GET /api/events | поток SSE, которым живёт дашборд |
GET /api/profile | профиль тика по подсистемам, JSON |
Дашборд в браузере
http://127.0.0.1:25585/ — та же нагрузка, что в chunkwake top, но с графиками. Страница вшита в бинарник, внешних библиотек и CDN нет, интернет не нужен.
На странице:
- KPI — TPS за 1/5/15 минут, MSPT (last, p95, p99 и бюджет), загрузка машины и процесса, RSS, игроки, чанки в симуляции.
- Графики за 15 минут — TPS с линией цели, MSPT с p95 и бюджетом, CPU машины и сервера, RSS, сеть в обе стороны, игроки онлайн.
- Ядра — полоска на каждое ядро: зелёная до 70 %, жёлтая до 90 %, красная выше.
- Тик, мир, сеть — те же строки, что в ANSI-таблице
chunkwake top.
Данные идут потоком GET /api/events (Server-Sent Events): сервер присылает кадр после каждой публикации снимка, страница ничего не опрашивает. Если поток оборвался, браузер переподключается, а страница подстраховывается /api/snapshot. История — 900 точек по секунде, доступна как GET /api/history, поэтому графики не теряются при перезагрузке.
Дашборд слушает тот же адрес, что и метрики (metrics-bind). По умолчанию это loopback: наружу страница и цифры не уходят.
Доступ и токен
На loopback настройка не нужна: chunkwake top и браузер на этой же машине работают без пароля. Если metrics-bind смотрит в сеть, сервер не запустит эндпоинт без токена и напишет в лог:
ERROR metrics disabled: metrics-bind=0.0.0.0 is reachable from the network,
but metrics-token is empty; set one with `chunkwake config set metrics-token
<long random string>` or bind to 127.0.0.1Задайте токен длиной не меньше 16 символов, без пробелов:
metrics-bind=0.0.0.0
metrics-token=длинная-случайная-строкаВход:
- браузер — откройте
http://адрес:25585/?token=...один раз: сервер поставит кукуcw_metrics(HttpOnly, SameSite=Strict) и перекинет на/без токена в адресе. Без куки и токена страница покажет форму входа. chunkwake top— читает токен изserver.propertiesи отправляет заголовкомAuthorization: Bearer.- Prometheus — тот же заголовок в
scrape_configs.
DNS rebinding закрыт: если браузер прислал Origin, он должен указывать на тот же хост, иначе ответ 403. Токен сравнивается побайтово без раннего выхода, чтобы его нельзя было подобрать по задержке.
Что меряется
Тик. Кольцевой буфер на 18 000 тиков (15 минут): TPS по окнам 1/5/15 минут, средний MSPT за минуту, p50/p95/p99, худший тик и число опоздавших тиков.
Процесс и машина. Загрузка по каждому ядру, средняя по машине, доля процесса в процентах одного ядра, RSS и виртуальная память, память системы.
Мир. Игроки, мобы, предметы, стрелы, сферы опыта, чанки в симуляции и известные миру, очереди редстоуна/жидкостей/воронок, печи, костры, задачи генерации.
Сеть. Байты и пакеты в обе стороны, средний и худший пинг по RTT keep_alive.
Память по частям. CHUNKWAKE_MEMSTATS=1 раз в 10 секунд пишет в лог столбцы в памяти, кэш кадров, мобов и предметов, прото-чанки генератора, кэши высот и раскладок структур. CHUNKWAKE_MEMSTATS_MI=1 добавляет статистику mimalloc после mi_collect.
/top
/top всё
/top tick только тик
/top cpu только процессор
/top mem память
/top world мир
/top net сетьКаждая строка — отдельный элемент с подсказкой при наведении. Полоска █░ показывает загрузку: зелёная до 70 %, жёлтая до 90 %, красная выше.
chunkwake top
$ chunkwake top --dir ./server
================= My Server · 26.3 · up 02:14:07 =================
── TICK
rate 20/s running ticks 161234
TPS now 20.0 1m 19.9 5m 20.0 15m 20.0
MSPT last 0.31 1m avg 0.28 p50 0.21 p95 0.60 p99 1.10 max 12.40
budget 50.0 ms ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0%
...| Флаг | По умолчанию | Что делает |
|---|---|---|
--dir PATH | текущий каталог | где взять server.properties с metrics-* |
--host HOST | metrics-bind | адрес эндпоинта |
--port PORT | metrics-port | порт эндпоинта |
--watch SEC | — | перерисовывать каждые SEC секунд |
--json | — | печатать снимок как JSON |
--no-color | — | без ANSI-цветов, для логов |
Настройки
metrics-enabled=true
metrics-bind=127.0.0.1
metrics-port=25585
metrics-token=По умолчанию эндпоинт слушает только loopback. metrics-token нужен только при внешнем metrics-bind.
Страница отдаётся сжатой (gzip), если браузер это умеет: 80 КБ превращаются в 24. Скрытая вкладка закрывает поток и не тянет кадры. Если metrics-port занят, сервер пробует 25586 и 25587 и пишет в лог, на каком порту слушает. chunkwake top перебирает те же три порта.
Prometheus
chunkwake_up
chunkwake_tps{window="1m"|"5m"|"15m"}
chunkwake_tick_rate
chunkwake_tick_frozen
chunkwake_mspt{quantile="0.5"|"0.95"|"0.99"|"max"}
chunkwake_mspt_last
chunkwake_ticks_total
chunkwake_late_ticks_total
chunkwake_process_cpu_percent
chunkwake_process_rss_bytes
chunkwake_process_threads
chunkwake_system_cpu_percent
chunkwake_system_memory_used_bytes
chunkwake_system_memory_total_bytes
chunkwake_cpu_core_percent{core="0"}
chunkwake_players
chunkwake_entities
chunkwake_dropped_items
chunkwake_chunks_simulated
chunkwake_chunks_loaded
chunkwake_chunkgen_pending
chunkwake_network_bytes_total{direction="in"|"out"}
chunkwake_network_packets_total{direction="in"|"out"}
chunkwake_ping_milliseconds
chunkwake_uptime_secondsПример prometheus.yml:
scrape_configs:
- job_name: chunkwake
static_configs:
- targets: ["127.0.0.1:25585"]Профиль тика
/debug start или /perf start пишет в debug/profile-<время>.txt строки тик<TAB>MSPT; /debug stop возвращает путь. Запись ограничена пятью минутами тиков.
Отдельно сервер всегда снимает разбивку тика по подсистемам — как spark, только без стеков:
| Где | Что видно |
|---|---|
GET / → «На что уходит тик» | стековая диаграмма по секундам и список групп |
chunkwake top | секция PROFILE: группы, ms/тик и доля |
GET /api/profile | JSON: 900 секунд по { at, ticks, total[18], max[18] } |
По умолчанию показываются группы, а не внутренние фазы:
| Группа | Что внутри |
|---|---|
| Мобы и животные | ИИ, движение, спавн |
| Хопперы и механизмы | печи, костры, поршни, редстоун, жидкости, плиты |
| Предметы и снаряды | дроп на земле, стрелы, опыт |
| Отправка игрокам | пакеты о блоках и позициях |
| Чанки в симуляции | пересчёт чанков рядом с игроками |
| Плагины | код плагинов в тике |
| Служебное | часы мира и прочая мелочь |
Точные 18 фаз остаются под переключателем «Подробно» и в JSON. Время показывается в мс на тик, а не суммой за секунду. Замер — одно чтение Instant на фазу и два на тик сверху, поэтому профиль работает всегда, а не только под /debug start.
Чего здесь нет, в отличие от spark: стеков вызовов, конкретных блоков и чанков. Разбивка отвечает на вопрос «куда уходит время тика», а не «какой именно моб тормозит». Разбор внутри подсистемы — /debug start плюс профиль-файл.
Связанное
- Эксплуатация — служба, логи, бэкапы и Velocity.
- Справочник команд —
/top,/perfи/debug. - Замеры — методика и сырые числа.
- Исходная документация —
docs/observability.mdв репозитории.