mumble/murmur nagios plugin.

As I’ve just installed a murmur server for mumble I need to monitor it to make sure it stays running.

I’ve been using Nagios for a while and have already done a shell script to monitor MySQL how I wanted. There is already a nagios plugin but it’s a shell script which calls a perl script and parses the output.

I don’t like doing things this way so set out to take the BSD/GPL licensed perl script as the base and turn it into my first perl nagios plugin.

It currently only monitors users but I’ve left most of the user/channel logic in from the original weblist.pl script so it can be expanded at a later date if required.

Here’s my check_murmur.pl script:

#! /usr/bin/perl
# Based on weblist.pl distributed with murmur/mumble server
# https://github.com/mumble-voip/mumble/blob/master/scripts/server/dbus/weblist.pl
use warnings;
use strict;
use Nagios::Plugin;
use Net::DBus;
my $np = Nagios::Plugin->new(  
     usage => "Usage: %s [ -c|--critical=<threshold> ] [ -w|--warning=<threshold> ]",
);
$np->add_arg(
     spec => 'warning|w=s',
     help => '-w, --warning=INTEGER:INTEGER .  See '
       . 'http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT '
       . 'for the threshold format. ',
   );
$np->add_arg(
     spec => 'critical|c=s',
     help => '-c, --critical=INTEGER:INTEGER .  See '
       . 'http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT '
       . 'for the threshold format. ',
   );
$np->getopts;
my $bus;
my $service;
# First try the system bus
eval {
  $bus=Net::DBus->system();
  $service = $bus->get_service("net.sourceforge.mumble.murmur");
};
# If that failed, the session bus
if (! $service) {
  eval {
    $bus = Net::DBus->session();
    $service = $bus->get_service("net.sourceforge.mumble.murmur");
  }
}
$np->nagios_exit(UNKNOWN, "Murmur service not found in DBUS") if (! $service);
# Fetch handle to remote object
my $object = $service->get_object("/");
# Call a function on the murmur object
my $servers = $object->getBootedServers();
my $params = [];
foreach my $server (@{$servers}) {
  my $name = $object->getConf($server, "registername");
  my $servobj = $service->get_object("/$server");
  my %users;
  # First, get channel names
  my $channels = $servobj->getChannels();
  my %channels;
  foreach my $c (@{$channels}) {
    my @c = @{$c};
    my $id = $c[0];
    my $name = $c[1];
    $channels{$id}=$name;
  }
  # Then, get and print the players
  my $players = $servobj->getPlayers();
  my $_total = 0;
  foreach my $p (@{$players}) {
    my @p = @{$p};
    my $chanid = $p[6];
    my $name = $p[8];
    my $chan = $channels{$chanid};
        $users{$chan} = [] unless $users{$chan};
        push @{$users{$chan}}, $name;
        $_total++;
  }
  my $_channels = [];
  for my $c (sort keys %users) {
        my $_users = [];
                for my $u (sort @{$users{$c}}) {
                        push @{$_users}, {'user' => $u};
                }
        push @{$_channels}, {
                'channel' => $c,
                'users' => $_users
        };
  }
  push @{$params}, {'server' => $server, 'name' => $name, 'total' => $_total, 'channels' => $_channels};
}
$np->add_perfdata( 
     label => "users",
     value => @{$params}[0]->{'total'},
     warning => $np->{'opts'}->{'warning'},
     critical => $np->{'opts'}->{'critical'},
);
my $code = $np->check_threshold(
     check => @{$params}[0]->{'total'},
     warning => $np->{'opts'}->{'warning'},
     critical => $np->{'opts'}->{'critical'},
);
$np->nagios_exit( $code, "" );

As I’m polling this server via NRPE I then add the below into the nrpe.cfg file and configure the monitoring server:

command[check_murmur]=/usr/lib/nagios/plugins/check_murmur.pl -w 20 -c 25