Welcome to It-Slav.Net blog
Peter Andersson
peter@it-slav.net

I've already got a female to worry about. Her name is the Enterprise.
-- Kirk, "The Corbomite Maneuver", stardate 1514.0

Background

My son got the amazing game Minecraft as a birthday present. Of course I think I should provide the service to him and his friends to have a couple of minecraftservers to be able to play together.

Soon it became business critical and I started to think about how to monitor that the Minecraft server is up and running. After searchin Internet I did not find anything that worked so I decided to write my own.

 

Prereq

I'm using the possibility to connect to the Rconn inteface at the Minecraftserver so it needs to be ebabled. Normaly by adding to Minecraft server.properties:

rcon.password=fjollboll

rcon.port=25578

 

I'm running the plugin on a vanilla Centos 6.3 box, and a perl CPAN module needs to be installed. Simply run the following command to install:

 

cpan Minecraft::RCON

I assume the reader knows howto monitor the basic stuff like: CPU usage, processes running, RAM usage, disk usage, disk I/O usage and everything else that should always be monitored on a system running business critical services.

 

 

Monitor the server

The easiest way to monitor that an instance of Minecraft server is running is to using check_tcp and the port defined for the server. However I read on some forums that the Minecraft server could hang and the tcp port still respond. So I wrote a plugin that connects to the Minecraft Rconn interface.

 

#!/usr/bin/perl

# Hint at http://search.cpan.org/~demmy/Minecraft-RCON-v0.1.2/lib/Minecraft/RCON.pm

#Licence GPLv2


use Minecraft::RCON;

use Getopt::Std;

use strict;


open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";



my(%ERRORS) = ( OK=>0, WARNING=>1, CRITICAL=>2, UNKNOWN=>3 );

my $status=$ERRORS{OK};;

my $rconresult;

my $numplayers;

my $maxplayers;

my $players;

my $message="OK";


our($opt_c, $opt_w, $opt_p, $opt_P, $opt_h, $opt_H);

getopts("p:P:hH:");


my $debug_flag=0;


sub printhelp () {

        print "Usage: check_minecraft [-h] -p password -P port -H host\n";

        print "-h Help, this text\n";

        print "-p password for rcon\n-P port number for rcon\n";

        print "-H ip-adress or servername of minecraftserver\n";

        print "\n\t\tby Peter Andersson\n\t\tpeter\@it-slav.net\n\t\thttp://www.it-slav.net/blogs/2012/10/06/monitor-minecraft-server-with-op5-monitor-or-nagios\n";

        if ($debug_flag) {

                print "opt_c:$opt_c opt_w:$opt_w opt_p:$opt_p opt_P:$opt_P opt_h:$opt_h opt_H:$opt_H\n";

        }


        exit $status;

} 


#sanity check

if (!defined $opt_p||!defined $opt_P||$opt_h||!defined $opt_H) {

        $status= $ERRORS{UNKNOWN};

        &printhelp;

}


my $rcon = Minecraft::RCON->new( { address => $opt_H, port => $opt_P, password => $opt_p } );

if ($rcon->connect){

  $rconresult =  $rcon->command('list');

  $_=$rconresult;

  if (/There are (\d+)\/(\d+) players online:(.*)/) {

    $status= $ERRORS{OK};

  }

}

else {

  print "CRITICAL - Could not connect to Minecraft server!\n";

  # Error capturing and fetching is in the works...

  $status= $ERRORS{CRITICAL};

  exit $status;

}

$rcon->disconnect;


print "OK - Minecraft server is running\n";

exit $status;

 

Monitor the numer of users

I think it would be interesting to monitor and graph the number of users using a Minecraft instance. Of course it returns perfdata for graphing.

 #!/usr/bin/perl

# Hint at http://search.cpan.org/~demmy/Minecraft-RCON-v0.1.2/lib/Minecraft/RCON.pm

# License GPLv2

use Minecraft::RCON;

use Getopt::Std;

use strict;


my(%ERRORS) = ( OK=>0, WARNING=>1, CRITICAL=>2, UNKNOWN=>3 );

my $status=$ERRORS{OK};;

my $rconresult;

my $numplayers;

my $maxplayers;

my $players;

my $message="OK";


our($opt_c, $opt_w, $opt_p, $opt_P, $opt_h, $opt_H);

getopts("c:w:p:P:hH:");


my $debug_flag=0;


sub printhelp () {

        print "Usage: check_minecraftusesr [-h] -c critical -w warning -p password -P port -H host\n";

        print "-h Help, this text\n-c num Critical threshold for number of players\n-w num Warning threshold for number of players\n";

        print "-p password for rcon\n-P port number for rcon\n";

        print "-H ip-adress or servername of minecraftserver\n";

        print "\n\t\tby Peter Andersson\n\t\tpeter\@it-slav.net\n\t\thttp://www.it-slav.net/blogs/2012/10/06/monitor-minecraft-server-with-op5-monitor-or-nagios/\n";

        if ($debug_flag) {

                print "opt_c:$opt_c opt_w:$opt_w opt_p:$opt_p opt_P:$opt_P opt_h:$opt_h opt_H:$opt_H\n";

        }


        exit $status;

} 


#sanity check

if (!defined $opt_c||!defined $opt_w||!defined $opt_p||!defined $opt_P||$opt_h||!defined $opt_H) {

        $status= $ERRORS{UNKNOWN};

        &printhelp;

} elsif ($opt_c < $opt_w) {

        print "Critical threshold must be higher or equal to warning threshold\n";

        $status= $ERRORS{UNKNOWN};

        &printhelp;

}


my $rcon = Minecraft::RCON->new( { address => $opt_H, port => $opt_P, password => $opt_p } );

if ($rcon->connect){

  $rconresult =  $rcon->command('list');

  $_=$rconresult;

  if (/There are (\d+)\/(\d+) players online:(.*)/) {

    $numplayers=$1;

    $maxplayers=$2;

    $players=$3;

    $players=~tr/a-zA-Z0-9 _,.-//cd;

    if ($debug_flag) {

      print "Number of players: $numplayers\n";

      print "Max players are: $maxplayers\n";

      print "Players are: $players\n";

    }

  }

}

else {

  print "Could not connect to Minecraft server!\n";

  # Error capturing and fetching is in the works...

  $status= $ERRORS{CRITICAL};

  exit $status;

}

$rcon->disconnect;


if ($numplayers >= $opt_w) {

  $status= $ERRORS{WARNING};

  $message="WARNING";

}

if ($numplayers >= $opt_c) {

  $status= $ERRORS{CRITICAL};

  $message="CRITICAL";

}


chomp ($players);


if ($numplayers > 0) { 

 print "$message:Number of players are $numplayers out of maximum $maxplayers. Players are: $players|players=$numplayers;$opt_w;$opt_c;0;$maxplayers;\n";

} else {

 print "$message:Number of players are $numplayers out of maximum $maxplayers.|players=$numplayers;$opt_w;$opt_c;0;$maxplayers;\n";

}

#print "$message: Number of players are $numplayers out of maximum $maxplayers:$players\|players=$numplayers\n";

exit $status;

 

Defining the commands in op5 Monitor or nagios

 

# command 'check_minecraft_server'

define command{

    command_name                   check_minecraft_server

    command_line                   $USER1$/custom/check_minecraft_server.pl -H $HOSTADDRESS$ -p $ARG1$ -P $ARG2$

    }


# command 'check_minecraft_users'

define command{

    command_name                   check_minecraft_users

    command_line                   $USER1$/custom/check_minecraft_users.pl -H $HOSTADDRESS$ -p $ARG1$ -P $ARG2$ -w $ARG3$ -c $ARG4$

    }

 

The result

Monitoring the number of users

 

Graphing the number of users

 

Using op5 BSM module to show the Business Service Minecraft

 

Final

  • MInecraft: an amazing game.
  • op5 Monitor, an enterpise class monitoring system based on Nagios
  • Nagios, an open and free tool for monitoring
  • BSM, op5 Business Service Management

 

I would also want to thank Mattias Ryrlen at op5, for helping me troubleshoot garbage characters from Rconn.


One Response to “Monitor Minecraft server with op5 Monitor or Nagios”

  1. Christian Says:

    Awesome bud, thanks for this! Works like a charm on a vanilla server but probably needs a few tweaks to work well with bukkit for us who use mods on our servers. 
    You should add a few checks on the server-logs as well as there's a few errors good to know about when running these business critical systems as we all know to well what happens if they don't work 100%…
    I've set up check_logfiles from our friends at consol: http://labs.consol.de/lang/en/nagios/check_logfiles/ specifying a simple search like this:
     
    @searches = (
      {
        tag => 'mc_server.log',
        logfile => '/home/mcadmin/minecraft_server/server.log',
        criticalpatterns => 'SEVERE',
        warningpatterns => 'WARNING',
        options => 'sticky=600, perfdata'
      },
    );
    and a command like so:
    /usr/lib/nagios/plugins/check_logfiles –config /usr/lib/nagios/plugins/check_logfiles.cfg
    Thanks mate!
    /Christian

Leave a Reply

You must be logged in to post a comment.





Book reviews
FreePBX 2.5
Powerful Telephony Solutions






Asterisk 1.6
Build a feature rich telephony system with Asterisk






Learning NAGIOS 3.0





Cacti 0.8 Network Monitoring,
Monitor your network with ease!