Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / djabberd / djabberd_ @ e3899a30

Historique | Voir | Annoter | Télécharger (11,1 ko)

1
#!/usr/bin/perl -w
2
#
3
# Copyright (C) 2012 Dominik Schulz <dominik.schulz@gauner.org>
4
#
5
# This program is free software; you can redistribute it and/or
6
# modify it under the terms of the GNU General Public License
7
# as published by the Free Software Foundation; version 2 dated June,
8
# 1991.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
#
19
# Script to monitor DJabberd servers.
20
# Mostly an adaptation of Guillaume Blairon's mogliefsd_activity script.
21
#
22
# Usage:
23
#    ln -s /usr/share/munin/plugins/djabberd_ \
24
#       /etc/munin/plugins/djabberd_{connections,memory,latency,counters}
25
#
26
# Configuration variables:
27
#
28
#    host (default: '127.0.0.1')
29
#    port (default: '5200')
30
#
31
# Parameters:
32
#
33
#    config    (required)
34
#    autoconf  (optional - only used by munin-config)
35
#
36
#%# family=auto
37
#%# capabilities=autoconf
38

    
39
use strict;
40
use warnings;
41
use IO::Socket;
42

    
43
my $djabberd_host = $ENV{host} || "127.0.0.1";
44
my $djabberd_port = $ENV{port} || 5200;
45
my $mode          = undef;
46
my $mode_name     = undef;
47

    
48
# mapping mode to command from which we get the information
49
my $mode_ref = {
50
    'connections' => {
51
        'cmd'    => 'stats',
52
        'title'  => 'DJabberd Connections',
53
        'vlabel' => 'connections',
54
        'fields' => {
55
            'connections' => {
56
                'key'         => 'connections',
57
                'label'       => 'Connections',
58
                'description' => 'Number of current connections',
59
                'draw'        => 'LINE1',
60
                'type'        => 'GAUGE',
61
            },
62
            'users' => {
63
                'key'         => 'users',
64
                'label'       => 'Users',
65
                'description' => 'Number of connected users',
66
                'draw'        => 'LINE1',
67
                'type'        => 'GAUGE',
68
            },
69
        },
70
    },
71
    'memory' => {
72
        'cmd'    => 'stats',
73
        'title'  => 'DJabberd Memory Statistics',
74
        'vlabel' => 'Bytes',
75
        'fields' => {
76
            'mem_total' => {
77
                'key'         => 'mem_total',
78
                'label'       => '',
79
                'description' => 'Total memory used by DJabberd',
80
                'draw'        => 'LINE1',
81
                'type'        => 'GAUGE',
82
                'filter'      => \&kb2bytes,
83
            },
84
            'mem_connections' => {
85
                'key'         => 'mem_connections',
86
                'label'       => '',
87
                'description' => 'Memory used for handling connections',
88
                'draw'        => 'LINE1',
89
                'type'        => 'GAUGE',
90
                'filter'      => \&kb2bytes,
91
            },
92
            'mem_per_connection' => {
93
                'key'         => 'mem_per_connection',
94
                'label'       => '',
95
                'description' => 'Memory used per connection',
96
                'draw'        => 'LINE1',
97
                'type'        => 'GAUGE',
98
                'filter'      => \&kb2bytes,
99
            },
100
        }
101
    },
102
    'latency' => {
103
        'cmd'    => 'latency',
104
        'title'  => 'DJabberd Latency Statistics',
105
        'vlabel' => 'reqs.',
106
        'fields' => {
107
            'dotzerozerozerofive' => {
108
                'key'         => '-0.0005',
109
                'label'       => 'lt. 0.0005',
110
                'description' => 'Requests handled in lt. 0.0005s',
111
                'draw'        => 'AREA',
112
                'type'        => 'COUNTER',
113
            },
114
            'dotzerozeroone' => {
115
                'key'         => '-0.001',
116
                'label'       => 'lt. 0.001',
117
                'description' => 'Requests handled int lt. 0.001s',
118
                'draw'        => 'STACK',
119
                'type'        => 'COUNTER',
120
            },
121
            'dotzerozerotwo' => {
122
                'key'         => '-0.002',
123
                'label'       => 'lt. 0.002',
124
                'description' => 'Requests handled int lt. 0.002s',
125
                'draw'        => 'STACK',
126
                'type'        => 'COUNTER',
127
            },
128
            'dotzerozerofive' => {
129
                'key'         => '-0.005',
130
                'label'       => 'lt. 0.005',
131
                'description' => 'Requests handled int lt. 0.005s',
132
                'draw'        => 'STACK',
133
                'type'        => 'COUNTER',
134
            },
135
            'dotzeroone' => {
136
                'key'         => '-0.01',
137
                'label'       => 'lt. 0.01',
138
                'description' => 'Requests handled int lt. 0.01s',
139
                'draw'        => 'STACK',
140
                'type'        => 'COUNTER',
141
            },
142
            'dotzerotwo' => {
143
                'key'         => '-0.02',
144
                'label'       => 'lt. 0.02',
145
                'description' => 'Requests handled int lt. 0.02s',
146
                'draw'        => 'STACK',
147
                'type'        => 'COUNTER',
148
            },
149
        }
150
    },
151
    'counters' => {
152
        'cmd'    => 'counters',
153
        'title'  => 'DJabberd Counters',
154
        'vlabel' => 'msgs.',
155
        'fields' => {
156
            'clientin_djabberd_iq'                     => { 'key' => 'ClientIn:DJabberd::IQ',                                  'type' => 'COUNTER', },
157
            'clientin_djabberd_message'                => { 'key' => 'ClientIn:DJabberd::Message',                             'type' => 'COUNTER', },
158
            'clientin_djabberd_presence'               => { 'key' => 'ClientIn:DJabberd::Presence',                            'type' => 'COUNTER', },
159
            'clientin_djabberd_stanza_sasl'            => { 'key' => 'ClientIn:DJabberd::Stanza::SASL',                        'type' => 'COUNTER', },
160
            'clientin_djabberd_stanza_starttls'        => { 'key' => 'ClientIn:DJabberd::Stanza::StartTLS',                    'type' => 'COUNTER', },
161
            'iniq_get_info_query'                      => { 'key' => 'InIQ:get-{http://jabber.org/protocol/disco#info}query',  'type' => 'COUNTER', },
162
            'iniq_get_items_query'                     => { 'key' => 'InIQ:get-{http://jabber.org/protocol/disco#items}query', 'type' => 'COUNTER', },
163
            'iniq_get_roster_query'                    => { 'key' => 'InIQ:get-{jabber:iq:roster}query',                       'type' => 'COUNTER', },
164
            'iniq_get_bind'                            => { 'key' => 'InIQ:set-{urn:ietf:params:xml:ns:xmpp-bind}bind',        'type' => 'COUNTER', },
165
            'iniq_get_session'                         => { 'key' => 'InIQ:set-{urn:ietf:params:xml:ns:xmpp-session}session',  'type' => 'COUNTER', },
166
            'serverin_djabberd_stanza_dialback_result' => { 'key' => 'ServerIn:DJabberd::Stanza::DialbackResult',              'type' => 'COUNTER', },
167
            'serverin_djabberd_stanza_dialback_verify' => { 'key' => 'ServerIn:DJabberd::Stanza::DialbackVerify',              'type' => 'COUNTER', },
168
            'auth_success'                             => { 'key' => 'auth_success',                                           'type' => 'COUNTER', },
169
            'c2s_message'                              => { 'key' => 'c2s-Message',                                            'type' => 'COUNTER', },
170
            'c2s_presence'                             => { 'key' => 'c2s-Presence',                                           'type' => 'COUNTER', },
171
            'connect'                                  => { 'key' => 'connect',                                                'type' => 'COUNTER', },
172
            'deliver_local'                            => { 'key' => 'deliver_local',                                          'type' => 'COUNTER', },
173
            'deliver_s2s'                              => { 'key' => 'deliver_s2s',                                            'type' => 'COUNTER', },
174
            'disconnect'                               => { 'key' => 'disconnect',                                             'type' => 'COUNTER', },
175
        },
176
    },
177
};
178

    
179
if ( $0 =~ m/djabberd_(.*)$/ && $mode_ref->{$1} ) {
180
    $mode_name = $1;
181
    $mode      = $mode_ref->{$mode_name};
182
}
183
else {
184
    print STDERR "ERROR: Unknown mode '$mode'. Exiting.\n";
185
    exit -1;
186
}
187

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

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

    
196
    if ($result_ref) {
197
        print "yes\n";
198
    }
199
    else {
200
        print "no\n";
201
    }
202

    
203
    exit 0;
204
}
205
elsif ( $ARGV[0] and $ARGV[0] eq "config" ) {
206
    print "graph_title " . $mode->{'title'} . "\n";
207
    print "graph_vlabel " . $mode->{'vlabel'} . "\n";
208
    print "graph_args -l 0\n";
209
    print "graph_category jabber\n";
210
    foreach my $field_name ( keys %{ $mode->{'fields'} } ) {
211
        my $label = $mode->{'fields'}->{$field_name}->{'label'}       || $field_name;
212
        my $desc  = $mode->{'fields'}->{$field_name}->{'description'} || $mode->{'fields'}->{$field_name}->{'key'};
213
        my $draw  = $mode->{'fields'}->{$field_name}->{'draw'}        || 'LINE1';
214
        my $type  = $mode->{'fields'}->{$field_name}->{'type'}        || 'COUNTER';
215

    
216
        print $field_name. '.label ' . $label . "\n";
217
        print $field_name. '.description ' . $desc . "\n";
218
        print $field_name. '.draw ' . $draw . "\n";
219
        print $field_name. '.type ' . $type . "\n";
220
    }
221

    
222
    exit 0;
223
}
224
else {
225
    my $result_ref = &query_djabberd( $djabberd_host, $djabberd_port, $mode );
226

    
227
    foreach my $field_name ( keys %{ $mode->{'fields'} } ) {
228
        my $key = $mode->{'fields'}->{$field_name}->{'key'};
229
        if ( defined( $result_ref->{$key} ) ) {    # check for definedness, may well be zero (false for perl)
230
            my $value = $result_ref->{$key};
231

    
232
            # if there is a filter defined for this key apply it now
233
            if ( exists( $mode->{'fields'}->{$field_name}->{'filter'} ) && ref( $mode->{'fields'}->{$field_name}->{'filter'} ) eq 'CODE' ) {
234
                $value = &{ $mode->{'fields'}->{$field_name}->{'filter'} }($value);
235
            }
236
            print $field_name. ".value " . $value . "\n";
237
        }
238
    }
239
}
240

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

    
244
    my $conn = IO::Socket::INET::->new(
245
        PeerAddr => $host,
246
        PeerPort => $port,
247
        Proto    => 'tcp',
248
        Timeout  => 5,
249
    ) or die($!);
250

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

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

    
255
    my @lines = ();
256
    while ( my $line = $conn->getline() ) {
257
        if ( $line =~ /^\./ ) {
258
            last;
259
        }
260
        push( @lines, $line );
261
    }
262
    close($conn);
263

    
264
    my $result_ref = {};
265
    foreach my $line (@lines) {
266
        my ( $key, $value, $unit ) = split /\s+/, $line;
267
        if ( $key && $value ) {
268
            $result_ref->{$key} = $value;
269
        }
270
    }
271

    
272
    return $result_ref;
273
}
274

    
275
# transform kb => bytes
276
sub kb2bytes {
277

    
278
    my $num = shift;
279

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

    
284
    return $num;
285
}