#!/usr/bin/perl -w # -*- cperl -*- =head1 NAME asterisk - Multigraph-capable plugin to monitor Asterisk =head1 NOTES This plugin will produce multiple graphs showing: - total number of active channels (replaces asterisk_channels), together with breakdown of specific channel types (replaces asterisk_channelstypes); - the number of messages in all voicemail boxes (replaces asterisk_voicemail); - DEPRECATED: the number of active MeetMe conferences and users connected to them (replace asterisk_meetme and asterisk_meetmeusers, respectively); - the number of active ConfBridge conferences (e.g. non-empty ones) and users connected to them - the number of active channels for a given codec, for both SIP and IAX2 channels (replaces asterisk_sipchannels and asterisk_codecs). =head1 CONFIGURATION The following configuration parameters are used by this plugin [asterisk] env.host - hostname to connect to env.port - port number to connect to env.username - username used for authentication env.secret - secret used for authentication env.channels - The channel types to look for env.codecsx - List of codec IDs (hexadecimal values) env.codecs - List of codecs names, matching codecsx order env.enable_meetme - Set to 1 to enable graphs for the MeetMe application env.enable_confbridge - Set to 1 to enable graphs for the ConfBridge application The "username" and "secret" parameters are mandatory, and have no defaults. =head2 DEFAULT CONFIGURATION [asterisk] env.host 127.0.0.1 env.port 5038 env.channels Zap IAX2 SIP env.codecsx 0x2 0x4 0x8 env.codecs gsm ulaw alaw env.enable_meetme 0 env.enable_confbridge 1 =head2 WILDCARD CONFIGURATION It's possible to use the plugin in a virtual-node capacity, in which case the host configuration will default to the hostname following the underscore: [asterisk_someserver] env.host someserver env.port 5038 =head1 AUTHOR Copyright (C) 2005-2006 Rodolphe Quiédeville Copyright (C) 2012 Diego Elio Pettenò =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf =cut use strict; use Munin::Plugin; use IO::Socket; # See the following and its subpages for change history in the AMI protocol: # https://wiki.asterisk.org/wiki/display/AST/Asterisk+Manager+Interface+%28AMI%29+Changes sub asterisk_command { my ($socket, $command) = @_; my $line, my $reply; $socket->print("Action: command\nCommand: $command\n\n"); # Response: (Error|Follows|Success) $line = $socket->getline; if ($line !~ /^Response: Success\r?\n$/) { while ( $line = $socket->getline and $line !~ /^\r?\n$/ ) { print STDERR "COMMAND: Ignoring unwanted line: $line" if $Munin::Plugin::DEBUG; } return undef; } # Message: Command output follows $line = $socket->getline; print STDERR "COMMAND got response: $line" if $Munin::Plugin::DEBUG; # Until we get the --END COMMAND-- marker, it's the command's output. while ( $line = $socket->getline and $line =~ /^Output:/ ) { print STDERR "COMMAND: got response: $line" if $Munin::Plugin::DEBUG; # Don't keep the "Output: " part of the response substr($line, 0, 8, ''); $reply .= $line; } return $reply; } $0 =~ /asterisk(?:_(.+))$/; my $hostname = $1; my $peeraddr = $ENV{'host'} || $hostname || '127.0.0.1'; my $peerport = $ENV{'port'} || '5038'; my $username = $ENV{'username'}; my $secret = $ENV{'secret'}; my @CHANNELS = exists $ENV{'channels'} ? split ' ',$ENV{'channels'} : qw(Zap IAX2 SIP); my @CODECS = exists $ENV{'codecs'} ? split ' ',$ENV{'codecs'} : qw(gsm ulaw alaw); my @CODECSX = exists $ENV{'codecsx'} ? split ' ',$ENV{'codecsx'} : qw(0x2 0x4 0x8); my $meetme_enabled = $ENV{'enable_meetme'} || '0'; my $confbridge_enabled = $ENV{'enable_confbridge'} || '1'; my $line, my $error; my $socket = new IO::Socket::INET(PeerAddr => $peeraddr, PeerPort => $peerport, Proto => 'tcp') or $error = "Could not create socket: $!"; if ( $socket ) { # This will consume the "Asterisk Call Manager" welcome line. $socket->getline; $socket->print("Action: login\nUsername: $username\nSecret: $secret\nEvents: off\n\n"); my $response_status = $socket->getline; if ( $response_status !~ /^Response: Success\r?\n$/ ) { my $response_message = $socket->getline; $response_message =~ s/Message: (.*)\r?\n/$1/; $error = "Asterisk authentication error: " . $response_message; } while ( $line = $socket->getline and $line !~ /^\r?\n$/ ) {} } if ( $ARGV[0] and $ARGV[0] eq 'autoconf' ) { if ( $error ) { print "no ($error)\n"; } else { print "yes\n"; } exit 0; } elsif ( $ARGV[0] and $ARGV[0] eq 'config' ) { print "host_name $hostname" if $hostname; print <close(); my $active_channels = 'U'; $active_channels = $1 if $channels_response =~ /\n([0-9]+) active channels?/; print <