Самый дешёвый полезный способ следить за сервером Valheim - спросить у него по протоколу запросов Steam, сколько на нём игроков. Сервер отвечает на запросы A2S на игровом порту плюс один - по умолчанию это UDP 2457, - и любой инструмент A2S за несколько миллисекунд возвращает имя сервера и число игроков. Это отвечает на вопросы "работает ли он" и "играет ли кто-нибудь". Чтобы узнать, кто зашёл, кто вышел и кто погиб, читайте лог сервера, потому что он записывает каждое подключение. Добавьте внешнюю проверку, которая поднимает тревогу, когда запрос не отвечает два-три раза подряд, и вы узнаете о падении сервера раньше своей группы.
Дальше разобран каждый уровень: запрос, лог, проверки аптайма, действительно понимающие UDP, мониторинг ресурсов и то, как не превратить оповещения в шум, который все отключают.
За чем стоит следить#
Мониторинг полезен только тогда, когда каждый сигнал отвечает на вопрос, после которого вы что-то сделаете. Для сервера Valheim таких сигнала четыре:
| Вопрос | Сигнал | Откуда берётся |
|---|---|---|
| Доступен ли сервер? | Ответ на запрос A2S | UDP-порт запросов, снаружи |
| Играет ли кто-нибудь? | Число игроков | Запрос A2S или лог |
| Кто зашёл, вышел или погиб? | Строки подключений и персонажей | Лог сервера |
| Не собирается ли он упасть? | Память и CPU относительно лимита | Хост или панель |
Работающий процесс - это не то же самое, что сервер, к которому можно подключиться. Процесс может быть жив, застряв на загрузке мира, пока файрвол блокирует порт, или пока он ждёт мод, который не загрузился. Запрос снаружи - проверка, соответствующая тому, что видят игроки, поэтому именно по ней и нужно поднимать тревогу. Всё остальное нужно для диагностики.
Общий довод в пользу оповещений по симптомам, а не по причинам, изложен в статье мониторинг, который что-то говорит. Для Valheim это значит: тревога срабатывает, когда запрос не проходит, а на память и лог вы смотрите уже после этого.
Порт запросов Steam и A2S#
Выделенный сервер Valheim использует два UDP-порта. Игровой порт (-port, по умолчанию 2456) несёт игровой трафик. Порт выше него несёт запросы Steam - протокол A2S, который используют браузеры серверов, чтобы показать сервер в списке и его число игроков.
| Порт | Протокол | Что отвечает |
|---|---|---|
2456 | UDP | Игровой трафик |
2457 | UDP | Запросы A2S: info, players, rules |
Если вы меняете -port, порт запросов смещается вместе с ним: -port 2466 означает запросы на 2467. Оба должны быть открыты в каждом файрволе между инструментом мониторинга и сервером. Запрос, который завершается по таймауту снаружи, но отвечает с самой машины, - это проблема файрвола, а не сервера.
У A2S три запроса. A2S_INFO возвращает имя сервера, карту, число игроков и максимум игроков. A2S_PLAYER возвращает список подключённых игроков с именем, счётом и временем подключения. A2S_RULES возвращает пары "ключ-значение", которые сервер решает опубликовать. Для Valheim надёжен A2S_INFO. Список игроков менее полезен, чем кажется: имена могут быть пустыми или обобщёнными в зависимости от версии и платформы, - поэтому считайте истиной число, а список - бонусом. Протокол и то, почему некоторые игры отвечают на него по-разному, объясняет статья Порты запросов и A2S.
Запросы с python-a2s и GameDig#
Почти все потребности закрывают два инструмента. python-a2s - небольшая библиотека Python, которая отправляет запросы A2S и возвращает разобранные результаты:
$ pip install python-a2simport a2sADDRESS = ("203.0.113.10", 2457) # query port, not game portinfo = a2s.info(ADDRESS, timeout=3.0)print(f"{info.server_name}: {info.player_count}/{info.max_players}")for player in a2s.players(ADDRESS, timeout=3.0): print(player.name or "(no name)", round(player.duration / 60), "min")Таймаут вызывает исключение, и это то, что нужно: скрипт мониторинга может считать "исключение" равным "сервер лежит". Один раз выведите весь объект info, чтобы увидеть, что возвращает ваша версия сервера: поля одинаковы для всех игр с A2S, но то, что Valheim кладёт в некоторые из них, со временем менялось.
GameDig - инструмент на Node.js, знающий особенности сотен игр, в том числе какой порт запрашивать:
$ npm install -g gamedig$ gamedig --type valheim 203.0.113.10:2456Профиль Valheim в GameDig учитывает смещение порта запросов, поэтому вы указываете игровой порт. Если происходит таймаут, посмотрите в документации к вашей версии, как он обращается с портом, и попробуйте запросить порт запросов напрямую. Он возвращает JSON с name, numplayers, maxplayers и ping, что позволяет легко передать его во что угодно.
Есть также IGameServersService/GetServerList из Steam Web API, который перечисляет серверы, зарегистрированные на главном сервере Steam, и требует ключ Steam Web API. Он показывает то, что видит браузер сообщества, и это полезно, когда вопрос звучит как "почему мой сервер пропал из списка". Проверкой работоспособности он не является: регистрация отстаёт от реальности на минуты. Этот случай разобран в статье Сервер Valheim не отображается в списке.
Учёт игроков по логу#
Лог - единственный источник, который знает, кто что сделал. Каждое подключение, появление персонажа и отключение порождает строку. Формулировки меняются между версиями, а кроссплей-серверы пишут в лог идентификаторы платформ через PlayFab, а не простые SteamID, так что сверьтесь со своим логом, прежде чем полагаться на шаблон. На недавнем сервере только для Steam строки, которые стоит искать через grep, выглядят так:
Got connection SteamID 76561198012345678Got character ZDOID from Ragnar : 1234567890:1Got character ZDOID from Ragnar : 0:0Closing socket 76561198012345678World saved ( 412.338ms )Что говорит каждая из этих строк:
Got connection SteamID- клиент подключился, ещё не выбрав персонажа. Используйте идентификатор для списков админов и банов.Got character ZDOID from <name> : <id>- персонаж игрока появился, так что это настоящий момент "зашёл", с именем персонажа.- Та же строка, оканчивающаяся на
0:0, - персонаж погиб. На этой строке построены оповещатели о смертях в Discord. Closing socket- клиент ушёл.World saved- сохранение завершилось, с указанием времени. Время сохранения, которое всё растёт, - ранний признак того, что мир становится тяжёлым.
В установке на systemd следите за логом в реальном времени с помощью journalctl -u valheim -f. С -logFile следите за файлом через tail -F; -F следует за файлом при его ротации. Для ленты входов и выходов хватит небольшого цикла:
#!/usr/bin/env bashjournalctl -u valheim -f -o cat | while read -r line; do case "$line" in *"Got character ZDOID from"*": 0:0"*) echo "DEATH ${line#*from }" ;; *"Got character ZDOID from"*) echo "JOIN ${line#*from }" ;; *"Closing socket"*) echo "LEAVE ${line##* }" ;; esacdoneШаблон смерти нужно проверять раньше шаблона входа, потому что у обоих один и тот же префикс. Замените echo вызовом webhook Discord, и у вас будет простой оповещатель без модов. Полный разбор лога, включая строки запуска и ошибки, на которые стоит реагировать, есть в статье Лог сервера Valheim: разбор.
Если не хочется поддерживать скрипт, мод Discord Connector делает то же изнутри сервера и заодно обрабатывает идентификаторы кроссплея - см. Discord Connector для Valheim.
Проверки аптайма, понимающие UDP#
Большинство сервисов аптайма проверяют сайты: HTTP-запрос или TCP-соединение с портом. Для Valheim не подходит ни то ни другое. Сервер не говорит по HTTP, а оба его порта - UDP, поэтому проверка TCP-порта 2456 завершается неудачей, даже когда сервер вполне здоров. Простой ICMP ping доказывает лишь то, что машина работает, но не игру.
Что работает:
- Самостоятельно размещённая проверка, говорящая на A2S. У Uptime Kuma, популярного варианта для самостоятельного размещения, есть типы мониторов игровых серверов; в последних версиях есть тип на основе GameDig. Укажите адрес игрового сервера с типом Valheim, и он будет оповещать через Discord, почту, Telegram и большинство других каналов. Старые версии предлагали тип игрового сервера Steam, которому нужен был ключ Steam Web API, так что проверьте, что есть в вашей версии.
- Задание cron на другой машине. Запускайте приведённый выше скрипт на Python каждую минуту с другого сервера, считайте подряд идущие неудачи и поднимайте тревогу на третьей. Пятнадцать строк кода и никаких зависимостей, кроме
python-a2s. - Конечная точка статуса из вашего контейнера. Образ Docker
lloesche/valheim-serverможет запускать небольшой веб-сервер статуса, который публикует результат запроса в виде JSON (переменныеSTATUS_HTTPв его README). Обычная HTTP-проверка аптайма может затем следить за ним. Учтите, что он работает внутри того же контейнера, поэтому не скажет вам, что внешний мир не может достучаться до игрового порта.
Запускайте проверку вне собственной сети сервера. Проверка с той же машины ничего не говорит о файрволе, маршрутизации или провайдере - а именно они ломаются так, что процесс этого не замечает.
Память, CPU и диск#
Запрос говорит, что что-то не так; графики ресурсов обычно говорят, что именно. Следите за тремя числами.
| Метрика | Норма | Когда действовать |
|---|---|---|
| Память | Стабильна после загрузки мира, медленно растёт в течение дней | В пределах 10-15% от лимита или скачок после установки мода |
| CPU | Всплески, когда игроки сражаются, строят или прибывают в новые зоны | На пределе при малом числе игроков |
| Диск | Медленно растёт вместе с миром и бэкапами | Бэкапы заполняют диск или .db мира удвоился за неделю |
Именно память обрывает сессии. Потребление Valheim растёт вместе с исследованной и застроенной областью, а сервер, достигший лимита памяти, останавливается жёстко, без сохранения. Нужно высматривать медленный подъём в течение дней без выхода на плато - его и выравнивает плановый перезапуск, о котором рассказано в статье плановые перезапуски Valheim. Реалистичные цифры по размеру группы приведены в статье сколько RAM нужно серверу Valheim.
На вашей собственной Linux-машине systemctl status valheim показывает текущую память для юнита, а ps -o rss,cmd -C valheim_server.x86_64 даёт резидентную память процесса в килобайтах. Для истории подойдёт всё, что записывает метрики, - node_exporter и Prometheus, Netdata или собственные графики хоста.
На RE:NODE консоль показывает живые графики памяти, CPU и диска относительно лимитов тарифа, так что вопрос "насколько я близко" решается без установки чего-либо. Кроме того, наблюдатель каждые две минуты опрашивает сервер, который ушёл в офлайн или у которого аптайм пошёл назад. Перезапуски, которые вы запросили, не учитываются; три неожиданных перезапуска за час выставляют предупреждение на странице сервера и автоматически открывают тикет, так что цикл сбоев замечают, даже если вы спите. В разделе о консоли в руководствах показано, где находятся графики.
Оповещения, которые не отключают#
Оповещение, срабатывающее при каждом колебании пинга игрока, отключат за неделю, а затем оно пропустит настоящий сбой. Несколько правил делают оповещения осмысленными:
- Требуйте подряд идущие неудачи. Один потерянный UDP-пакет - норма. Поднимайте тревогу после трёх неудачных проверок с интервалом в минуту, а не после одной.
- Оповещайте и о восстановлении. "Снова в сети через 4 минуты" подсказывает, нужно ли разбираться или можно проигнорировать.
- Разделяйте оповещения для админов и новости для игроков. Сообщения о входах и смертях относятся в канал, который читают игроки. Простои и предупреждения о памяти - туда, куда заглядывают только админы.
- Глушите плановые работы. Если сервер перезапускается каждый день в 05:00, проверка не должна будить никого в 05:01. Либо приостановите её на это окно, либо требуйте, чтобы сбои длились дольше, чем занимает перезапуск.
- Включайте то, что знаете. Оповещение "запрос не прошёл из Франкфурта, последнее число игроков 3, память 92% от лимита" можно разобрать с телефона.
Минимальная проверка с подсчётом подряд идущих неудач:
import a2s, json, pathlib, sys, urllib.requestADDRESS = ("203.0.113.10", 2457)WEBHOOK = "https://discord.com/api/webhooks/REPLACE/ME"STATE = pathlib.Path("/var/tmp/valheim_failures")def notify(text): body = json.dumps({"content": text}).encode() req = urllib.request.Request(WEBHOOK, body, {"Content-Type": "application/json"}) urllib.request.urlopen(req, timeout=5)fails = int(STATE.read_text()) if STATE.exists() else 0try: a2s.info(ADDRESS, timeout=3.0) if fails >= 3: notify("Valheim is answering again.") fails = 0except Exception: fails += 1 if fails == 3: notify("Valheim has not answered queries for 3 minutes.")STATE.write_text(str(fails))Запускайте её каждую минуту из cron на другой машине. Она оповещает один раз на третьей неудаче и один раз при восстановлении, а не каждую минуту между ними. Форматирование и ограничения скорости Discord описаны в статье Webhook Discord для статуса сервера.
Типичные проблемы мониторинга#
Запрос завершается по таймауту, но игроки могут зайти. Инструмент мониторинга обращается к игровому порту вместо порта запросов, порт запросов закрыт в файрволе или сервер работает с кроссплеем и отвечает на запросы Steam не так, как ждёт ваш инструмент. Выполните запрос с самой машины, чтобы разделить случаи.
Число игроков застыло на нуле, пока люди играют. Те же причины или инструмент опрашивает другой сервер по тому же адресу. Проверьте имя сервера в ответе.
Число верное, но имён нет. Ожидаемо для многих версий Valheim. Для имён используйте лог.
Проверка аптайма каждое утро говорит, что сервер лежит. Плановый перезапуск. Приостановите проверку на это окно или требуйте, чтобы сбои держались дольше, чем занимает перезапуск.
Шаблоны лога перестали совпадать после обновления. Iron Gate изредка меняет формулировки в логе. Смотрите свежий лог после каждого крупного патча и обновляйте свои шаблоны.
FAQ#
На какой порт отправлять запрос, чтобы узнать число игроков сервера Valheim?
На игровой порт плюс один, по UDP. При -port 2456 по умолчанию запрашивайте 2457. GameDig принимает игровой порт и сам добавляет смещение; python-a2s и большинству других библиотек A2S нужен порт запросов.
Можно ли узнать, какие игроки онлайн, без мода?
Да, из лога сервера. Каждое появление персонажа записывается с его именем, а каждое отключение - с идентификатором игрока, поэтому скрипт, следящий за логом, может вести живой список. Список игроков в A2S может содержать имена, а может и не содержать, в зависимости от версии.
Почему проверка TCP-порта говорит, что мой сервер Valheim лежит?
Потому что Valheim не использует TCP. Оба его порта - UDP, поэтому попытка TCP-соединения всегда терпит неудачу. Используйте проверку, которая отправляет запросы A2S по UDP.
Как часто запускать проверку аптайма?
Раз в минуту с тревогой после трёх неудач подряд. Так реальный сбой обнаруживается примерно за три минуты и никого не будит из-за потерянного пакета.
Замедляет ли мониторинг сервер?
Нет. Запрос A2S - это один небольшой UDP-пакет и ответ на него, обрабатываемый вне главного игрового потока. Даже один запрос в секунду был бы незаметен на фоне трафика одного игрока.


