2012-02-26 13:16:43 +01:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
#
|
|
|
|
# Copyright (C) 2012 Dominik Schulz <dominik.schulz@gauner.org>
|
|
|
|
#
|
|
|
|
# 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/djabberd_{connections,memory,latency,counters}
|
|
|
|
#
|
|
|
|
# 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;
|
|
|
|
|
|
|
|
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', },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
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";
|
2017-02-22 18:11:54 +01:00
|
|
|
print "graph_category chat\n";
|
2012-02-26 13:16:43 +01:00
|
|
|
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::INET::->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;
|
|
|
|
}
|