Brazil's biggest MU Online portal — since 2003
Tutorial Advanced Infrastructure

How to monitor your MU Online server with Grafana and Prometheus

Install Prometheus and Grafana to monitor CPU, memory, MySQL, and online players on your MU Online server in real time, with ready-made dashboards and automatic alerts before players feel the problem.

RO Rodrigo · Updated on Jan 23, 2019 · ⏱ 18 min read
Quick answer

Running a MU Online server without monitoring is like flying blind: you only find out MySQL froze, CPU spiked, or GameServer crashed once players are already complaining on Discord. Prometheus and Grafana are the industry-standard duo for observability — the former collects CPU, memory, disk, networ

Running a MU Online server without monitoring is like flying blind: you only find out MySQL froze, CPU spiked, or GameServer crashed once players are already complaining on Discord. Prometheus and Grafana are the industry-standard duo for observability — the former collects CPU, memory, disk, network, and database metrics over time, and the latter turns that data into visual dashboards and automatic alerts. This tutorial covers installing both, configuring exporters for MySQL and the operating system, building a custom exporter for online players, ready-made dashboards, and alerts that notify your team before players notice the problem.

Why monitor proactively

Most private server administrators only react after the fact — a lag spike, a GameServer crash, a full disk that hangs MySQL. With historical metrics, you spot patterns (for example, MySQL always chokes at 9 PM when player population peaks) and act before the complaint shows up on Discord. Monitoring is also concrete evidence to justify hardware upgrades or a migration to a dedicated server, instead of decisions based on "gut feeling."

Architecture overview

ComponentFunction
PrometheusCollects and stores metrics as time series
Node ExporterExposes operating system metrics (CPU, RAM, disk, network)
MySQL ExporterExposes MySQL metrics (queries/s, connections, slow queries)
Custom exporterExposes online players, active accounts, ongoing castle siege
GrafanaVisualizes metrics in dashboards and triggers visual alerts
AlertmanagerSends notifications (Discord, email, Telegram) based on rules

Prerequisites

  • Linux server (or WSL/dedicated Windows with adaptations) with root/sudo access.
  • MU Online server already running (see the server creation tutorial).
  • Docker installed (recommended, simplifies installing the whole stack).
  • Read access to MySQL for the database exporter.

Step 1 — Install Prometheus and Grafana via Docker Compose

The simplest way to bring up the entire stack is with Docker Compose, isolating each service in its own container.

version: "3.8"
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
  node_exporter:
    image: prom/node-exporter
    ports:
      - "9100:9100"
  mysqld_exporter:
    image: prom/mysqld-exporter
    environment:
      - DATA_SOURCE_NAME=exporter:password@(mysql-host:3306)/
    ports:
      - "9104:9104"
docker compose up -d

Step 2 — Configure Prometheus to scrape the exporters

Edit prometheus.yml, adding each target that Prometheus should query periodically:

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['node_exporter:9100']
  - job_name: 'mysql'
    static_configs:
      - targets: ['mysqld_exporter:9104']
  - job_name: 'mu_online'
    static_configs:
      - targets: ['mu_exporter:9200']

Restart the Prometheus container and confirm at http://server-ip:9090/targets that all targets show as UP.

Step 3 — Create a dedicated MySQL user for the exporter

Never use the MySQL root account in the exporter. Create a user with minimal metrics-reading permissions:

CREATE USER 'exporter'@'%' IDENTIFIED BY 'strong_password' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';

Step 4 — Build a custom exporter for online players

There's no official exporter for MU Online-specific metrics, but it's simple to build a periodic script that queries the database (connected-accounts table or a ConnectServer count) and exposes the result in Prometheus format:

from prometheus_client import Gauge, start_http_server
import mysql.connector
import time

players_online = Gauge('mu_players_online', 'Currently connected players')

def collect():
    conn = mysql.connector.connect(host="localhost", user="exporter", password="strong_password", database="MuOnline")
    cursor = conn.cursor()
    cursor.execute("SELECT COUNT(*) FROM MEMB_STAT WHERE ConnectStat = 1")
    players_online.set(cursor.fetchone()[0])
    conn.close()

if __name__ == "__main__":
    start_http_server(9200)
    while True:
        collect()
        time.sleep(30)

Step 5 — Connect Grafana to Prometheus

Access http://server-ip:3000 (default login admin/admin on first run), go to Data Sources and add Prometheus with the URL http://prometheus:9090. Save and test the connection before moving on to dashboards.

Step 6 — Import ready-made dashboards

The Grafana community offers ready-made dashboards for Node Exporter (ID 1860) and MySQL Exporter (ID 7362), which you can import directly by ID from the Import Dashboard screen. For MU Online's custom metrics, build a simple panel with a line graph using the mu_players_online metric over time.

PanelMetricSuggested chart type
Players onlinemu_players_onlineLine, last 24h
Server CPUnode_cpu_seconds_totalLine, with moving averages
MySQL connectionsmysql_global_status_threads_connectedLine
Slow queriesmysql_global_status_slow_queriesCounter/bar
Disk usagenode_filesystem_avail_bytesGauge

Step 7 — Configure alerts with Alertmanager

Create alert rules in Prometheus for critical conditions, such as CPU above 90% for 5 minutes or a drop in online players (a sign that GameServer is down):

groups:
  - name: mu_alerts
    rules:
      - alert: HighCPU
        expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "CPU above 90% for 5 minutes"
      - alert: ServerDown
        expr: mu_players_online == 0
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "No players online — possible GameServer outage"

Configure Alertmanager with a Discord webhook to receive these notifications automatically in the admin team's channel.

Step 8 — Define metrics retention and backup

Configure Prometheus retention (default 15 days) according to available disk space, and include the Prometheus and Grafana data volumes in your server's backup routine, so you don't lose history in case of a disk failure.

Common errors and fixes

SymptomLikely causeFix
Target shows as DOWN in PrometheusExporter isn't running or port is blockedCheck the container/service and firewall rules
Grafana dashboard shows no dataData source misconfiguredReview the Prometheus URL in Data Sources
MySQL exporter fails to connectWrong user/password or permissionsRecreate the exporter user with the correct GRANT
Alert doesn't reach DiscordAlertmanager webhook misconfiguredTest the webhook manually with curl
Online players metric always zeroWrong custom query for the emulator's schemaAdjust the query to match the real sessions table

Monitoring checklist

  • Prometheus, Grafana, and exporters running via Docker Compose.
  • All targets showing UP status in Prometheus.
  • Dedicated MySQL user for the exporter, with minimal permissions.
  • Custom online players exporter working.
  • Dashboards imported and showing real data.
  • Alert rules configured for CPU, disk, and player drops.
  • Alertmanager integrated with the team's Discord.
  • Data retention and backup of the monitoring stack defined.

With monitoring active, the natural next step is to tie these metrics into your team's incident response process — knowing the disk is filling up doesn't help if no one gets notified in time to act; also review the MU Online server creation tutorial to make sure the base infrastructure supports this level of observability.

Frequently asked questions

Do I need to know how to code to set up Grafana and Prometheus?

You don't need to code, but understanding basic YAML (config files) and Linux command-line concepts helps. Most of the work is editing config files and importing ready-made community dashboards, without writing code.

Do Grafana and Prometheus consume a lot of server resources?

They consume moderate resources — usually less than 5% CPU and a few hundred MB of RAM on a medium-sized server. It's worth running them on a separate VM or container from the GameServer so they don't compete for resources at peak player counts.

Can I monitor the number of MU Online players online directly?

Yes, with a custom exporter (a script that reads the connection count from ConnectServer or queries the database) that exposes that metric in the format Prometheus understands. There's no official ready-made exporter, but it's simple to build with a periodic script.

What's the difference between Prometheus and Grafana?

Prometheus collects and stores metrics over time (time series); Grafana is the visual layer that reads those metrics and builds the dashboards and alerts. You need both: one without the other only solves half the problem.

How do I get an alert on Discord when the server goes down?

Configure Alertmanager (a component of the Prometheus ecosystem) with a Discord webhook, and create alert rules in Prometheus for conditions like 'GameServer offline' or 'CPU above 90% for 5 minutes'. Alertmanager automatically sends the notification to the configured channel.

RO
Founder & editor-in-chief

Rodrigo has run ViciadosMU since the portal's early days. A specialist in MU Online server creation and administration, game history and the evolution of the seasons — he wrote much of the archive before 2024.

Keep reading

Related articles