Files
vicinoc_1-X/icinga2/plugins/check_ast_chans.pl
T

167 lines
6.1 KiB
Perl

#!/usr/bin/perl
# check_ast_chans.pl - Icinga plugin to check total asterisk channel usage
#
# Copyright (C) 2018 James Pearson <jamesp@vicidial.com> LICENSE: AGPLv2
#
### All my lovely little modules
use warnings;
use Net::Telnet ();
use Getopt::Long;
# Nagios specific
use lib "/usr/lib/nagios/plugins";
our $TIMEOUT;
our %ERRORS;
eval 'use utils qw(%ERRORS $TIMEOUT)';
if ($@) {
$TIMEOUT = 30;
%ERRORS = ('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
}
my $version='1.0';
### Set-up some useful defaults
$DB=0;
$channel_warn = 0;
$channel_crit = 0;
$asterisk_host = "127.0.0.1";
$asterisk_port = "5038";
$asterisk_user = "cron";
$asterisk_pass = "1234";
$timeout = 3;
$return_code = 3; # By default, our return state is unknown unless specifically set otherwise
$return_perf_data = 0;
$max_chan_ct=450;
$min_chan_ct=0;
sub debugoutput {
# I got tired of repeating this code snippet, so this gives debug output, with optional critical die
my $debugline = shift;
my $debugdie = 0;
$debugdie = shift;
if ($DB==1 and $debugdie==0) {
# We are just giving output, nothing more
print "$debugline\n";
} elsif ($DB==1 and $debugdie==1) {
# Evidently it was a critical error, so we die on output
die("$debugline\n");
}
}
sub usage {
print "\n\nAsterisk channel monitoring through AMI for Nagios/Icinga\n\n";
print "allowed run time options:\n";
print " [-H $asterisk_host] = Asterisk Host or IP\n";
print " [-U $asterisk_user] = AMI Username\n";
print " [-P $asterisk_pass] = AMI Password\n";
print " [-p $asterisk_port] = AMI port\n";
print " [-w $channel_warn] = Warning Level, none if not specified\n";
print " [-c $channel_crit] = Critical Level, none if not specified\n";
print " [-t $timeout] = Timeout to wait for AMI connection\n";
print " [-f] = Return performance data\n";
print " [--debug] = Debug Output for testing\n";
print " [--help] = This help screen\n";
exit $ERRORS{'UNKNOWN'};
}
Getopt::Long::Configure('bundling', 'no_ignore_case');
GetOptions(
'host|H=s' => \$asterisk_host,
'user|U=s' => \$asterisk_user,
'pass|P=s' => \$asterisk_pass,
'port|p=i' => \$asterisk_port,
'warn|w=i' => \$channel_warn,
'crit|c=i' => \$channel_crit,
'timeout|t=i' => \$timeout,
'f' => \$return_perf_data,
'debug' => \$DB,
'help' => sub { &usage(); },
);
if ($channel_warn>0 or $channel_crit>0 ) {
if ($channel_warn==0 or $channel_crit==0) {
print "Warning and Critical must both be specified!\n";
exit $ERRORS{'UNKNOWN'};
}
if ($channel_warn > $channel_crit) {
print "Critical level must be higher then Warning level!\n";
exit $ERRORS{'UNKNOWN'};
}
}
if ($DB==1) {
print "\n\nAsterisk channel monitoring through AMI for Nagios/Icinga\n\n";
print "\n----- DEBUG -----\n\n";
print " Host: $asterisk_host\n";
print " User: $asterisk_user\n";
print " Pass: $asterisk_pass\n";
print " Port: $asterisk_port\n";
print " Time: $timeout\n";
if ($channel_warn>0 or $channel_crit>0) {
print " Warn: $channel_warn\n";
print " Crit: $channel_crit\n";
} else {
print " Not checking for warn/crit\n";
}
if ($return_perf_data==1) { print " Perf: Enabled\n";}
}
# Lets login
$t = new Net::Telnet (Port => $asterisk_port,
Timeout => $timeout,
Prompt => '/.*[\$%#>] $/',
Output_record_separator => '',
Errmode => 'return' );
#$fh = $t->dump_log("$telnetlog"); # uncomment for telnet log
# Login to the AMI and get our channel list
$t->open("$asterisk_host");
if ($t->errmsg) { print "Could not connect to Asterisk!\n"; exit $ERRORS{'UNKNOWN'}; }
$t->waitfor('/[0123]\n$/'); # print login
if ($t->errmsg) { print "Login Prompt not Received!\n"; exit $ERRORS{'UNKNOWN'}; }
$t->print("Action: Login\nUsername: $asterisk_user\nSecret: $asterisk_pass\n\n");
if ($t->errmsg) { print "Login Information Incorrect!\n"; exit $ERRORS{'UNKNOWN'}; }
$t->waitfor('/Authentication accepted/'); # waitfor auth accepted
if ($t->errmsg) { print "Command not Accepted!\n"; exit $ERRORS{'UNKNOWN'};}
@list_channels = $t->cmd(String => "Action: Status\n\n", Prompt => '/Event: StatusComplete.*/');
$t->print("Action: Logoff\n\n");
$t->close;
# Now loop through the channel listing and figure out what we got
$test_zap_count=0;
$test_iax_count=0;
$test_local_count=0;
$test_sip_count=0;
$active_channels = 0;
$s=0;
foreach(@list_channels) {
if ($list_channels[$s] =~ /^Channel: SIP/) {$test_sip_count++; $active_channels++; debugoutput("Found SIP Channel",0);}
if ($list_channels[$s] =~ /^Channel: Local/) {$test_local_count++; $active_channels++; debugoutput("Found Local Channel",0);}
if ($list_channels[$s] =~ /^Channel: IAX2/) {$test_iax_count++; $active_channels++; debugoutput("Found IAX Channel",0);}
if ($list_channels[$s] =~ /^Channel: ZAP/) {$test_zap_count++; $active_channels++; debugoutput("Found ZAP/DAHDI Channel",0);}
if ($list_channels[$s] =~ /^Channel: DAHDI/) {$test_zap_count++; $active_channels++; debugoutput("Found ZAP/DAHDI Channel",0);}
#debugoutput("Channel Line: $list_channels[$s]",0)
$s++;
}
$return_string = "Active: $active_channels , SIP: $test_sip_count , IAX: $test_iax_count , ZAP/DAH: $test_zap_count, Local: $test_local_count";
debugoutput("Init Channel Return String: $return_string",0);
# Do our crit/warning checking and perfdata processing
if ($s>0) { $return_code=0; } # Basically, if we had any output then we got a channel listing, even if no channels
if ($channel_warn>0 && $active_channels>$channel_warn) { $return_code=1;}
if ($channel_crit>0 && $active_channels>$channel_crit) { $return_code=2;}
if ($return_perf_data==1) {
if ($channel_warn > 0) {
$return_string = $return_string . " | astchannels=$active_channels;$channel_warn;$channel_crit;$min_chan_ct;$max_chan_ct";
} else {
$return_string = $return_string . " | channels=$active_channels";
}
debugoutput("Perf Channel Return String: $return_string",0);
}
if ($return_code==0) { $return_string = "OK : " . $return_string; print "$return_string\n"; exit $ERRORS{'OK'};}
if ($return_code==1) { $return_string = "WARNING : " . $return_string; print "$return_string\n"; exit $ERRORS{'WARNING'};}
if ($return_code==2) { $return_string = "CRITICAL : " . $return_string; print "$return_string\n"; exit $ERRORS{'CRITICAL'};}