Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add munin monitoring plugin #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
284 changes: 284 additions & 0 deletions contrib/monitoring/munin/djabberd_
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
#!/usr/bin/perl -w
#
# Copyright (C) 2012 Dominik Schulz <[email protected]>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Script to monitor DJabberd servers.
# Mostly an adaptation of Guillaume Blairon's mogliefsd_activity script.
#
# Usage:
# ln -s /usr/share/munin/plugins/djabberd \
# /etc/munin/plugins/
#
# Configuration variables:
#
# host (default: '127.0.0.1')
# port (default: '5200')
#
# Parameters:
#
# config (required)
# autoconf (optional - only used by munin-config)
#
#%# family=auto
#%# capabilities=autoconf

use strict;
use warnings;
use IO::Socket::INET6;

my $djabberd_host = $ENV{host} || '127.0.0.1';
my $djabberd_port = $ENV{port} || 5200;
my $mode = undef;
my $mode_name = undef;

# mapping mode to command from which we get the information
my $mode_ref = {
'connections' => {
'cmd' => 'stats',
'title' => 'DJabberd Connections',
'vlabel' => 'connections',
'fields' => {
'connections' => {
'key' => 'connections',
'label' => 'Connections',
'description' => 'Number of current connections',
'draw' => 'LINE1',
'type' => 'GAUGE',
},
'users' => {
'key' => 'users',
'label' => 'Users',
'description' => 'Number of connected users',
'draw' => 'LINE1',
'type' => 'GAUGE',
},
},
},
'memory' => {
'cmd' => 'stats',
'title' => 'DJabberd Memory Statistics',
'vlabel' => 'Bytes',
'fields' => {
'mem_total' => {
'key' => 'mem_total',
'label' => '',
'description' => 'Total memory used by DJabberd',
'draw' => 'LINE1',
'type' => 'GAUGE',
'filter' => \&kb2bytes,
},
'mem_connections' => {
'key' => 'mem_connections',
'label' => '',
'description' => 'Memory used for handling connections',
'draw' => 'LINE1',
'type' => 'GAUGE',
'filter' => \&kb2bytes,
},
'mem_per_connection' => {
'key' => 'mem_per_connection',
'label' => '',
'description' => 'Memory used per connection',
'draw' => 'LINE1',
'type' => 'GAUGE',
'filter' => \&kb2bytes,
},
}
},
'latency' => {
'cmd' => 'latency',
'title' => 'DJabberd Latency Statistics',
'vlabel' => 'reqs.',
'fields' => {
'dotzerozerozerofive' => {
'key' => '-0.0005',
'label' => 'lt. 0.0005',
'description' => 'Requests handled in lt. 0.0005s',
'draw' => 'AREA',
'type' => 'COUNTER',
},
'dotzerozeroone' => {
'key' => '-0.001',
'label' => 'lt. 0.001',
'description' => 'Requests handled int lt. 0.001s',
'draw' => 'STACK',
'type' => 'COUNTER',
},
'dotzerozerotwo' => {
'key' => '-0.002',
'label' => 'lt. 0.002',
'description' => 'Requests handled int lt. 0.002s',
'draw' => 'STACK',
'type' => 'COUNTER',
},
'dotzerozerofive' => {
'key' => '-0.005',
'label' => 'lt. 0.005',
'description' => 'Requests handled int lt. 0.005s',
'draw' => 'STACK',
'type' => 'COUNTER',
},
'dotzeroone' => {
'key' => '-0.01',
'label' => 'lt. 0.01',
'description' => 'Requests handled int lt. 0.01s',
'draw' => 'STACK',
'type' => 'COUNTER',
},
'dotzerotwo' => {
'key' => '-0.02',
'label' => 'lt. 0.02',
'description' => 'Requests handled int lt. 0.02s',
'draw' => 'STACK',
'type' => 'COUNTER',
},
}
},
'counters' => {
'cmd' => 'counters',
'title' => 'DJabberd Counters',
'vlabel' => 'msgs.',
'fields' => {
'clientin_djabberd_iq' => { 'key' => 'ClientIn:DJabberd::IQ', 'type' => 'COUNTER', },
'clientin_djabberd_message' => { 'key' => 'ClientIn:DJabberd::Message', 'type' => 'COUNTER', },
'clientin_djabberd_presence' => { 'key' => 'ClientIn:DJabberd::Presence', 'type' => 'COUNTER', },
'clientin_djabberd_stanza_sasl' => { 'key' => 'ClientIn:DJabberd::Stanza::SASL', 'type' => 'COUNTER', },
'clientin_djabberd_stanza_starttls' => { 'key' => 'ClientIn:DJabberd::Stanza::StartTLS', 'type' => 'COUNTER', },
'iniq_get_info_query' => { 'key' => 'InIQ:get-{http://jabber.org/protocol/disco#info}query', 'type' => 'COUNTER', },
'iniq_get_items_query' => { 'key' => 'InIQ:get-{http://jabber.org/protocol/disco#items}query', 'type' => 'COUNTER', },
'iniq_get_roster_query' => { 'key' => 'InIQ:get-{jabber:iq:roster}query', 'type' => 'COUNTER', },
'iniq_get_bind' => { 'key' => 'InIQ:set-{urn:ietf:params:xml:ns:xmpp-bind}bind', 'type' => 'COUNTER', },
'iniq_get_session' => { 'key' => 'InIQ:set-{urn:ietf:params:xml:ns:xmpp-session}session', 'type' => 'COUNTER', },
'serverin_djabberd_stanza_dialback_result' => { 'key' => 'ServerIn:DJabberd::Stanza::DialbackResult', 'type' => 'COUNTER', },
'serverin_djabberd_stanza_dialback_verify' => { 'key' => 'ServerIn:DJabberd::Stanza::DialbackVerify', 'type' => 'COUNTER', },
'auth_success' => { 'key' => 'auth_success', 'type' => 'COUNTER', },
'c2s_message' => { 'key' => 'c2s-Message', 'type' => 'COUNTER', },
'c2s_presence' => { 'key' => 'c2s-Presence', 'type' => 'COUNTER', },
'connect' => { 'key' => 'connect', 'type' => 'COUNTER', },
'deliver_local' => { 'key' => 'deliver_local', 'type' => 'COUNTER', },
'deliver_s2s' => { 'key' => 'deliver_s2s', 'type' => 'COUNTER', },
'disconnect' => { 'key' => 'disconnect', 'type' => 'COUNTER', },
},
},
};

# Determine the running mode
if ( $0 =~ m/djabberd_(.*)$/ && $mode_ref->{$1} ) {
$mode_name = $1;
$mode = $mode_ref->{$mode_name};
}
else {
print STDERR "ERROR: Unknown mode '$mode'. Exiting.\n";
exit -1;
}

if ( $ARGV[0] && $ARGV[0] eq 'suggest' ) {
print join( "\n", keys %$mode_ref );

exit 0;
}
elsif ( $ARGV[0] && $ARGV[0] eq "autoconf" ) {
my $result_ref = &query_djabberd( $djabberd_host, $djabberd_port, $mode );

if ($result_ref) {
print "yes\n";
}
else {
print "no\n";
}

exit 0;
}
elsif ( $ARGV[0] and $ARGV[0] eq "config" ) {
print "graph_title " . $mode->{'title'} . "\n";
print "graph_vlabel " . $mode->{'vlabel'} . "\n";
print "graph_args -l 0\n";
print "graph_category DJabberd\n";
foreach my $field_name ( keys %{ $mode->{'fields'} } ) {
my $label = $mode->{'fields'}->{$field_name}->{'label'} || $field_name;
my $desc = $mode->{'fields'}->{$field_name}->{'description'} || $mode->{'fields'}->{$field_name}->{'key'};
my $draw = $mode->{'fields'}->{$field_name}->{'draw'} || 'LINE1';
my $type = $mode->{'fields'}->{$field_name}->{'type'} || 'COUNTER';

print $field_name. '.label ' . $label . "\n";
print $field_name. '.description ' . $desc . "\n";
print $field_name. '.draw ' . $draw . "\n";
print $field_name. '.type ' . $type . "\n";
}

exit 0;
}
else {
my $result_ref = &query_djabberd( $djabberd_host, $djabberd_port, $mode );

foreach my $field_name ( keys %{ $mode->{'fields'} } ) {
my $key = $mode->{'fields'}->{$field_name}->{'key'};
if ( defined( $result_ref->{$key} ) ) { # check for definedness, may well be zero (false for perl)
my $value = $result_ref->{$key};
# if there is a filter defined for this key apply it now
if(exists($mode->{'fields'}->{$field_name}->{'filter'}) && ref($mode->{'fields'}->{$field_name}->{'filter'}) eq 'CODE') {
$value = &{$mode->{'fields'}->{$field_name}->{'filter'}}($value);
}
print $field_name. ".value " . $value . "\n";
}
}
}

sub query_djabberd {
my ( $host, $port, $mode ) = @_;

my $conn = IO::Socket::INET6->new(
PeerAddr => $host,
PeerPort => $port,
Proto => 'tcp',
Timeout => 5,
) or die($!);

my $request = $mode->{'cmd'} . "\n";

$conn->syswrite( $request, length($request) );

my @lines = ();
while ( my $line = $conn->getline() ) {
if ( $line =~ /^\./ ) {
last;
}
push( @lines, $line );
}
close($conn);

my $result_ref = {};
foreach my $line (@lines) {
my ( $key, $value, $unit ) = split /\s+/, $line;
if ( $key && $value ) {
$result_ref->{$key} = $value;
}
}

return $result_ref;
}

# transform kb => bytes
sub kb2bytes {
my $num = shift;

if($num && $num =~ m/^\d+$/) {
$num *= 1024;
}

return $num;
}