2
0
mirror of https://github.com/munin-monitoring/contrib.git synced 2018-11-08 00:59:34 +01:00
contrib-munin/plugins/other/shoutcast2_multi
2012-02-09 15:05:58 -08:00

352 lines
11 KiB
Perl
Executable File

#!/usr/bin/perl
#
=head1 Shoutcast 2.0.x Plugin
A Plugin for monitoring a Shoutcast 2.0.x Server (Multigraph)
=head1 Munin Configuration
[shoutcast2_multi]
env.host 127.0.0.1 *default*
env.port 8000 *default*
env.pass changeme *default*
=head2 Munin Configuration Explanation
host = host we are attempting to connection to, can be ip, or hostname
port = port we need to connect to in order to get to admin.cgi
pass = password to use to authenticate as admin user
=head1 License
GPLv2
=head1 Magic Markers
#%# family=auto
#%# capabilities=autoconf
=cut
use strict;
use warnings;
use LWP::UserAgent;
use XML::Simple;
use Munin::Plugin;
need_multigraph();
=head1 Variable Declarations
This section is mainly for importing / declaring our environment variables.
This is were we will import the data from our plugin-conf.d file so we can
override the default settings which will only work for Shoutcast test configs.
=cut
my $host = $ENV{host} || '127.0.0.1';
my $port = $ENV{port} || 8000;
my $pass = $ENV{pass} || 'changeme';
# Initialize hashref for storing results information...
my $dataRef;
# Create a hashref for our graph information that we will call up later...
my $graphsRef;
my $ua = LWP::UserAgent->new();
$ua->agent('Munin Shoutcast Plugin/0.1');
$ua->timeout(5);
$ua->credentials($host.':'.$port, 'Shoutcast Server', 'admin'=>$pass);
=head1 Graphs Declarations
The following section of code contains our graph information. This is the data
provided to Munin, so that it may properly draw our graphs based on the values
the plugin returns.
While you are free to change colors or labels changing the type, min, or max
could cause unfortunate problems with your graphs.
=cut
$graphsRef->{active} = {
config => {
args => '--base 1000 --lower-limit 0',
vlabel => 'Is a DJ Actively Connected?',
category => 'shoutcast2',
title => 'Active States',
info => 'This graph shows us the active state or not, depending on if a DJ is connected',
},
datasrc => [
{ name => 'active', draw => 'AREA', min => '0', max => '1', label => 'On or Off', type => 'GAUGE' },
],
};
$graphsRef->{listeners} = {
config => {
args => '--base 1000 --lower-limit 0',
vlabel => 'Listener Count',
category => 'shoutcast2',
title => 'Listeners',
info => 'This graph shows us the various counts for listener states we are tracking',
},
datasrc => [
{ name => 'maxlisteners', draw => 'STACK', min => '0', label => 'Max Listeners', type => 'GAUGE' },
{ name => 'currlisteners', draw => 'AREA', min => '0', label => 'Current Listeners', type => 'GAUGE' },
],
};
$graphsRef->{sid_active} = {
config => {
args => '--base 1000 --lower-limit 0',
vlabel => 'Is a DJ Actively Connected?',
title => 'Active State',
info => 'This graph shows us the active state or not, depending on if a DJ is connected',
},
datasrc => [
{ name => 'active', draw => 'AREA', min => '0', max => '1', label => 'On or Off', type => 'GAUGE', xmlkey => 'STREAMSTATUS' },
],
};
$graphsRef->{sid_listeners} = {
config => {
args => '--base 1000 --lower-limit 0',
vlabel => 'Listener Count',
title => 'Listeners',
info => 'This graph shows us the various counts for listener states we are tracking',
},
datasrc => [
{ name => 'maxlisteners', draw => 'STACK', min => '0', label => 'Max Listeners', type => 'GAUGE', xmlkey => 'MAXLISTENERS' },
{ name => 'currlisteners', draw => 'AREA', min => '0', label => 'Current Listeners', type => 'GAUGE', xmlkey => 'CURRENTLISTENERS' },
{ name => 'peaklisteners', draw => 'LINE2', min => '0', label => 'Peak Listeners', type => 'GAUGE', xmlkey => 'PEAKLISTENERS' },
{ name => 'uniqlisteners', draw => 'LINE2', min => '0', label => 'Unique Listeners', type => 'GAUGE', xmlkey => 'UNIQUELISTENERS' },
],
};
if (defined($ARGV[0]) && ($ARGV[0] eq 'config')) {
config();
exit;
}
if (defined($ARGV[0]) && ($ARGV[0] eq 'autoconf')) {
check_autoconf();
exit;
}
# I guess we are collecting stats to return, execute main subroutine.
main();
exit;
sub main {
my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port);
if ($returnBit == 0) {
exit;
}
my $streamConfigRef = $adminRef->{STREAMCONFIGS}->{STREAMCONFIG};
my $sidDataRef;
if ($adminRef->{STREAMCONFIGS}->{TOTALCONFIGS} == 1) {
my $sid = $streamConfigRef->{id};
my ($return,$tmpSidRef) = fetch_sid_data($sid);
if ($return == 0) {
# Only one stream, and we didn't get a good response.
exit;
}
$sidDataRef->{$sid} = $tmpSidRef;
} else {
foreach my $sid (keys %{$streamConfigRef}) {
my ($return,$tmpSidRef) = fetch_sid_data($sid);
if ($return == 0) {
next;
}
$sidDataRef->{$sid} = $tmpSidRef;
}
}
print_active_data($sidDataRef);
print_listener_data($adminRef->{STREAMCONFIGS}->{SERVERMAXLISTENERS}, $sidDataRef);
return;
}
sub print_active_data {
my ($sidDataRef) = (@_);
my $globalActive = 0;
foreach my $sid (sort keys %{$sidDataRef}) {
print "multigraph shoutcast2_active.active_sid_$sid\n";
foreach my $dsrc (@{$graphsRef->{sid_active}->{datasrc}}) {
print "$dsrc->{name}.value $sidDataRef->{$sid}->{$dsrc->{xmlkey}}\n";
if ($sidDataRef->{$sid}->{$dsrc->{xmlkey}} == 1) {
$globalActive = 1;
}
}
}
print "multigraph shoutcast2_active\n";
foreach my $dsrc (@{$graphsRef->{active}->{datasrc}}) {
print "$dsrc->{name}.value $globalActive\n";
}
return;
}
sub print_listener_data {
my ($maxListeners,$sidDataRef) = (@_);
my $globalListeners = 0;
foreach my $sid (sort keys %{$sidDataRef}) {
print "multigraph shoutcast2_listeners.listeners_sid_$sid\n";
foreach my $dsrc (@{$graphsRef->{sid_listeners}->{datasrc}}) {
print "$dsrc->{name}.value $sidDataRef->{$sid}->{$dsrc->{xmlkey}}\n";
if ($dsrc->{name} eq 'currlisteners') {
$globalListeners += $sidDataRef->{$sid}->{$dsrc->{xmlkey}};
}
}
}
print "multigraph shoutcast2_active\n";
foreach my $dsrc (@{$graphsRef->{listeners}->{datasrc}}) {
if ($dsrc->{name} eq 'maxlisteners') {
print "$dsrc->{name}.value $maxListeners\n";
} else {
print "$dsrc->{name}.value $globalListeners\n";
}
}
return;
}
sub config {
my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port);
if ($returnBit == 0) {
# $adminRef returned a string, we'll just print it out.
print "no (error response: $adminRef)\n";
exit;
}
my $streamConfigRef = $adminRef->{STREAMCONFIGS}->{STREAMCONFIG};
my $sidDataRef;
if ($adminRef->{STREAMCONFIGS}->{TOTALCONFIGS} == 1) {
my $sid = $streamConfigRef->{id};
my ($return,$tmpSidRef) = fetch_sid_data($sid);
if ($return == 0) {
# Only one stream, and we didn't get a good response.
exit;
}
$sidDataRef->{$sid} = $tmpSidRef;
} else {
foreach my $sid (keys %{$streamConfigRef}) {
my ($return,$tmpSidRef) = fetch_sid_data($sid);
if ($return == 0) {
next;
}
$sidDataRef->{$sid} = $tmpSidRef;
}
}
print_active_config($sidDataRef);
print_listener_config($sidDataRef);
return;
}
sub print_active_config {
my ($sidDataRef) = (@_);
foreach my $sid (sort keys %{$sidDataRef}) {
# Print the Config Info First
print "multigraph shoutcast2_active.active\_sid\_$sid\n";
print "graph_title ".$graphsRef->{sid_active}->{config}->{title}." for StreamID: $sid\n";
print "graph_args ".$graphsRef->{sid_active}->{config}->{args}."\n";
print "graph_vlabel ".$graphsRef->{sid_active}->{config}->{vlabel}."\n";
print "graph_category streamid_$sid\n";
print "graph_info ".$graphsRef->{sid_active}->{config}->{info}."\n";
# Print the Data Value Info
foreach my $dsrc (@{$graphsRef->{sid_active}->{datasrc}}) {
while ( my ($key, $value) = each (%{$dsrc})) {
next if ($key eq 'name');
next if ($key eq 'xmlkey');
print "$dsrc->{name}.$key $value\n";
}
}
}
print "multigraph shoutcast2_active\n";
print "graph_title ".$graphsRef->{active}->{config}->{title}."\n";
print "graph_args ".$graphsRef->{active}->{config}->{args}."\n";
print "graph_vlabel ".$graphsRef->{active}->{config}->{vlabel}."\n";
print "graph_category ".$graphsRef->{active}->{config}->{category}."\n";
print "graph_info ".$graphsRef->{active}->{config}->{info}."\n";
# Print the Data Value Info
foreach my $dsrc (@{$graphsRef->{active}->{datasrc}}) {
while ( my ($key, $value) = each (%{$dsrc})) {
next if ($key eq 'name');
print "$dsrc->{name}.$key $value\n";
}
}
return;
}
sub print_listener_config {
my ($sidDataRef) = (@_);
foreach my $sid (sort keys %{$sidDataRef}) {
# Print the Config Info First
print "multigraph shoutcast2_listeners.listeners\_sid\_$sid\n";
print "graph_title ".$graphsRef->{sid_listeners}->{config}->{title}." for StreamID: $sid\n";
print "graph_args ".$graphsRef->{sid_listeners}->{config}->{args}."\n";
print "graph_vlabel ".$graphsRef->{sid_listeners}->{config}->{vlabel}."\n";
print "graph_category streamid_$sid\n";
print "graph_info ".$graphsRef->{sid_listeners}->{config}->{info}."\n";
# Print the Data Value Info
foreach my $dsrc (@{$graphsRef->{sid_listeners}->{datasrc}}) {
while ( my ($key, $value) = each (%{$dsrc})) {
next if ($key eq 'name');
next if ($key eq 'xmlkey');
print "$dsrc->{name}.$key $value\n";
}
}
}
print "multigraph shoutcast2_listeners\n";
print "graph_title ".$graphsRef->{listeners}->{config}->{title}."\n";
print "graph_args ".$graphsRef->{listeners}->{config}->{args}."\n";
print "graph_vlabel ".$graphsRef->{listeners}->{config}->{vlabel}."\n";
print "graph_category ".$graphsRef->{listeners}->{config}->{category}."\n";
print "graph_info ".$graphsRef->{listeners}->{config}->{info}."\n";
# Print the Data Value Info
foreach my $dsrc (@{$graphsRef->{listeners}->{datasrc}}) {
while ( my ($key, $value) = each (%{$dsrc})) {
next if ($key eq 'name');
print "$dsrc->{name}.$key $value\n";
}
}
return;
}
sub check_autoconf {
my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port);
if ($returnBit == 0) {
# $adminRef returned a string, we'll just print it out.
print "no (error response: $adminRef)\n";
} else {
print "yes\n";
}
return;
}
sub fetch_sid_data {
my ($sid) = (@_);
my $url = 'http://'.$host.':'.$port.'/stats?sid='.$sid;
my $response = $ua->get($url);
if ($response->is_success) {
my $returnRef = XMLin($response->decoded_content);
return (1, $returnRef);
} else {
return (0, $response->status_line);
}
}
sub fetch_admin_data {
my $url = 'http://'.$host.':'.$port.'/admin.cgi?sid=1&mode=viewxml&page=6';
my $response = $ua->get($url);
if ($response->is_success) {
my $returnRef = XMLin($response->decoded_content);
if (($returnRef->{STREAMCONFIGS}->{TOTALCONFIGS} > 0) && (defined($returnRef->{STREAMCONFIGS}->{STREAMCONFIG}))) {
return (1, $returnRef);
} else {
return (0, 'Unable to Detect any Stream Configurations');
}
} else {
return (0, $response->status_line);
}
}