aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Game Server

Server Monitoring for Game Servers with Grafana & Prometheus

A solid server monitoring setup is the insurance policy of running a game server: you see the CPU maxing out, RAM filling up, or a process crashing before players ever feel the lag. In this guide I'll walk you through making a Linux game server (Metin2, Minecraft, CS, a Discord bot host — it doesn't matter) fully observable using the Prometheus + node_exporter + Grafana trio. It's all open source and it all runs on a single VPS.

Why Prometheus + Grafana?

The roles of this duo are cleanly separated:

  • Prometheus — the time-series database and collector. It "scrapes" the targets (exporters) you define at regular intervals, stores the metrics and makes them queryable.
  • node_exporter — Prometheus's official exporter; it publishes OS-level CPU, RAM, disk, network and load metrics on an HTTP endpoint.
  • Grafana — the visualization layer. You connect Prometheus as a data source and build dashboards and alerts.

The data flows in one direction: node_exporter → Prometheus → Grafana. This architecture stays the same as you scale: you install an exporter on each new machine and add it as a target in Prometheus.

Installing node_exporter

node_exporter is a single static binary with no dependencies. Let's download the official release and run it as a systemd service:

cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter

Then create a systemd unit file:

sudo tee /etc/systemd/system/node_exporter.service >/dev/null <<'EOF'
[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter

Verify it: curl http://localhost:9100/metrics should return a long list of metrics. node_exporter listens on port 9100 by default.

Setting up Prometheus and defining targets

You can download Prometheus as a binary the same way or run it with Docker. Its heart is the prometheus.yml config file, where you define your scrape targets:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
        labels:
          instance: 'metin2-vps-1'

scrape_interval sets how often data is collected; 15 seconds is enough resolution for most game servers. If you have several machines, add new ip:9100 lines under targets. Spinning up Prometheus with Docker is the most practical route:

docker run -d --name prometheus -p 9090:9090 \
  -v /etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

Check that your target shows up as UP at http://server-ip:9090/targets.

Player counts and custom game metrics

node_exporter gives you system metrics but can't answer "how many players are online?" There are two practical approaches:

  • process metrics — with process-exporter you can track the CPU and memory usage of game server processes (e.g. Metin2 channel/game processes) individually. If one channel suddenly eats RAM, you see it immediately.
  • custom exporter — the player count usually lives in a database or in the server's own API. A small script can push values to Prometheus's Pushgateway or you can use the textfile collector.

The textfile collector method is the simplest: start node_exporter with --collector.textfile.directory=/var/lib/node_exporter, then a cron script writes the metric to a .prom file:

#!/bin/bash
# read the online player count from MySQL
COUNT=$(mysql -N -e "SELECT COUNT(*) FROM player_online;" game_db)
echo "game_players_online ${COUNT}" > /var/lib/node_exporter/players.prom.$$
mv /var/lib/node_exporter/players.prom.$$ /var/lib/node_exporter/players.prom

Using an atomic mv prevents node_exporter from reading a half-written file. Now you can graph the game_players_online metric in Grafana.

Grafana dashboard and alerts

After installing Grafana (Docker: grafana/grafana, port 3000), the first step is adding Prometheus as a data source under Connections → Data sources; set the URL to http://prometheus:9090 or your server IP. Instead of building a dashboard from scratch, importing a ready-made one is fastest: for node_exporter the community dashboard ID 1860 (Node Exporter Full) brings dozens of panels for CPU, RAM, disk and network.

The real value is in alerts. A few practical PromQL expressions:

  • CPU usage: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) — warn when it exceeds 90%.
  • Free RAM ratio: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes — warn when it drops below 10%.
  • Disk fill: node_filesystem_avail_bytes on the root partition falling below a critical threshold.

In Grafana you create an Alert rule from a panel, define the threshold, and route the notification to a Discord webhook, email or Telegram. That way your phone buzzes at 3 a.m. when the server goes down — instead of waking up to player complaints.

A security note

Never expose the exporter and Prometheus ports (9100, 9090) to the public internet. They carry no authentication and leak information about your system. The right approach: restrict these ports in the firewall (e.g. ufw) to your internal network or trusted IPs only, and for machine-to-machine traffic put them behind a VPN (WireGuard) or a reverse proxy with basic auth. Put Grafana's port 3000 behind a TLS reverse proxy (Nginx/Caddy) too — that's the cleanest setup.

Frequently Asked Questions

Can Prometheus and the game server run on the same VPS?

Yes, at small to medium scale it's fine. Prometheus and node_exporter are very lightweight. Just keep the retention period (say 15 days) and scrape interval reasonable; storing months of per-second data wastes disk for no reason.

How do I monitor multiple game servers?

Install node_exporter on each machine, gather them all under targets in a single Prometheus prometheus.yml, and give each a meaningful instance label. In Grafana you watch them all from one dashboard by selecting the instance.

Should I use something other than Grafana alerting?

Grafana alerts are enough for most use cases. If you want more complex silencing/grouping rules, add Prometheus's own Alertmanager component; the two also work together.

Stop flying your game server blind. Want me to make your server properly observable with a Prometheus + Grafana monitoring setup, process tracking and alerts dropped into Discord? Get in touch — I'll handle everything from install to dashboards.

Bu kategorideki tüm yazılar →

Devamı için