Subversion Repositories DevTools

Rev

Rev 5793 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5398 dpurdie 1
#! /usr/bin/perl
2
########################################################################
3
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
4
#
5
# Module name   : blatNagios.pl
6
# Module type   : Nagios Plug in
7
# Compiler(s)   : Perl
8
# Environment(s): jats
9
#
10
# Description   : A Nagios plugin to interface to BLAT data
11
#                 This is a simple stand alone Perl Program
12
#                 It does not require the JATS environment
13
#
14
# Usage         : See POD at the end of this file
15
#
16
#......................................................................#
17
 
18
 
19
require 5.008_002;
20
use strict;
21
use warnings;
22
use Pod::Usage;
23
use Getopt::Long;
24
use File::Basename;
25
use Data::Dumper;
26
use File::Spec::Functions;
27
use FindBin;                                    # Determine the current directory
28
 
29
#
30
#   Globals
31
#
32
my $VERSION = "1.0.0";                      # Update this
33
my $opt_verbose = 1;
34
my $opt_help = 0;
35
my $opt_target;
36
my $opt_rundir = 'run';
37
my @opt_data;
5399 dpurdie 38
my @opt_text;
5404 dpurdie 39
my @opt_warn;
5398 dpurdie 40
my %stats;
41
my $exitMsg = "OK";
5399 dpurdie 42
my @exitMsgTxt;
5398 dpurdie 43
my @perfData;
5404 dpurdie 44
my $setWarning;
45
my $setCritical;
5398 dpurdie 46
 
47
#-------------------------------------------------------------------------------
48
# Function        : Main Entry
49
#
50
# Description     :
51
#
52
# Inputs          :
53
#
54
# Returns         :
55
#
56
my $result = GetOptions (
57
                "help:+"        => \$opt_help,          # flag, multiple use allowed
58
                "manual:3"      => \$opt_help,          # flag
59
                "verbose:+"     => \$opt_verbose,       # flag
60
                "target=s"      => \$opt_target,        # String
61
                "rundir=s"      => \$opt_rundir,        # String
5399 dpurdie 62
                "data=s"        => sub{push @opt_data, split(/\s*,\s*/,$_[1])},          # Strings
63
                "text=s"        => sub{push @opt_text, split(/\s*,\s*/,$_[1])},          # Strings
5404 dpurdie 64
                "warn=s"        => sub{push @opt_warn, split(/\s*,\s*/,$_[1])},          # Strings
5398 dpurdie 65
                );
66
 
67
#
68
#   Process help and manual options
69
#
70
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
71
pod2usage(-verbose => 1)  if ($opt_help == 2 );
6475 dpurdie 72
pod2usage(-verbose => 1)  if ($opt_help > 2);
5398 dpurdie 73
 
74
# Validate options
75
Error ("Target machine not specified") unless ($opt_target);
76
 
77
# Determine the 'run' directory
78
unless ($opt_rundir =~ m~^/~)
79
{
80
    $opt_rundir = catdir($FindBin::Bin , $opt_rundir);
81
}
82
Error ("Rundir not found: $opt_rundir") unless -d $opt_rundir;
83
 
84
#
85
# See if the named BLAT target is running
86
#   It must have a PID pid file
87
#
88
Error('BLAT daemon not running') unless testPid('blat');
89
Error('Transfer daemon not running') unless testPid($opt_target);
90
 
91
#
92
# Read in the statistics file
93
#   Format is is key:data
94
# 
95
my $statsFile = catfile( $opt_rundir, $opt_target . '.stats');
96
Warning('No Statistics available') unless -f $statsFile;
97
open my $fh, $statsFile || Error("Cannot read statistics");
98
while (<$fh>)
99
{
100
    m~(.*):(.*)~;
101
    $stats{lc($1)} = $2;
102
}
5404 dpurdie 103
close $fh;
5398 dpurdie 104
 
105
#
106
#   Determine the Nagios State. Will be CRITICAL if
107
#       state is NOT OK
108
#       timeStamp is more than 5 minutes old
109
#       
110
unless (defined $stats{state} && $stats{state} eq 'OK')
111
{
5404 dpurdie 112
    $setCritical = 1;
5398 dpurdie 113
    $exitMsg = $stats{state} || 'Unknown state' ;
114
}
115
 
116
my $dataAge = time() - $stats{timestamp};
117
if ($dataAge > (10 * 60))
118
{
5404 dpurdie 119
    $setCritical = 1;
5398 dpurdie 120
    $exitMsg = 'Data too old(Secs):' . $dataAge;
121
}
122
 
123
#
5404 dpurdie 124
#   Insert Text data - not perf data.
5399 dpurdie 125
#   This will be displayed as a part of the output
126
#
127
foreach my $item (@opt_text)
128
{
129
    push @exitMsgTxt, $item . '=' . getDataItem($item); 
130
}
131
#
5398 dpurdie 132
#   Insert the required performance data
133
#   
5399 dpurdie 134
foreach my $item (@opt_data)
5398 dpurdie 135
{
5399 dpurdie 136
    push @perfData, $item . '=' . getDataItem($item); 
5398 dpurdie 137
}
138
 
139
#
5404 dpurdie 140
#   Process warning thresholds
141
#
142
foreach my $item (@opt_warn)
143
{
144
    my ($Name, $warn, $critical) = split(/:/, $item);
145
    my $name = lc $Name;
146
    my $isCritical;
147
    if (exists $stats{$name})
148
    {
149
        my $value = int($stats{$name});
150
        if (defined $critical)
151
        {
6475 dpurdie 152
            if (compareValues($value, $critical ))
5404 dpurdie 153
            {
154
                $isCritical = 1;
155
                $setCritical = 1;
156
                push @exitMsgTxt, $Name . ' is Critical'; 
157
 
158
            }
159
        }
160
        if (! $isCritical)
161
        {
162
            if (defined $warn )
163
            {
6475 dpurdie 164
                if (compareValues($value, $warn ))
5404 dpurdie 165
                {
166
                    $setWarning = 1;
167
                    push @exitMsgTxt, $Name . ' is Warning'; 
168
                }
169
            }
170
            else
171
            {
172
                push @exitMsgTxt, "$item bad format";
173
                $setWarning = 1; 
174
            }
175
        }
176
    }
177
    else
178
    {
179
        push @exitMsgTxt, "$Name not known";
180
        $setWarning = 1; 
181
    }
182
}
183
 
184
#
5398 dpurdie 185
# Prepare the output
5399 dpurdie 186
#   STATUS, Status Text, Performance Data
5398 dpurdie 187
# 
188
print($exitMsg);
5404 dpurdie 189
print (' - ',join(', ', @exitMsgTxt)) if (@exitMsgTxt);
5399 dpurdie 190
print ('|',join('; ', @perfData), ';') if (@perfData);
5398 dpurdie 191
print("\n");
5404 dpurdie 192
exit 2 if $setCritical;
193
exit 1 if $setWarning;
194
exit 0;
5398 dpurdie 195
 
196
#-------------------------------------------------------------------------------
6475 dpurdie 197
# Function        : expandSuffix 
198
#
199
# Description     : Convert text like 10Gb to a number 10000000000 
200
#                   Also removes '_' added to aid readability
201
#                   Support KB, MB, GB, TB and is case insensitive
202
#                   
203
#
204
# Inputs          : $text   - Test to convert
205
#
206
# Returns         : Converted number
207
#                   Will generate error
208
#
209
sub expandSuffix
210
{
211
    my ($text) = @_;
212
    my $number;
213
    $text =~ s~_~~g;
214
 
215
    if ($text =~ m~(\d+)T$~i) {
216
        $number = int($1) * 1000000000000;
217
    } elsif ($text =~ m~(\d+)G$~i) {
218
        $number = int($1) * 1000000000 ;
219
    } elsif ($text =~ m~(\d+)M$~i) {
220
        $number = int($1) * 1000000 ;
221
    } elsif ($text =~ m~(\d+)K$~i) {
222
        $number = int($1) * 1000 ;
223
    } elsif ($text =~ m~(\d+)$~i) {
224
        $number = int($1);
225
    } else {
226
        Error ("Number: $text not valid");
227
    }
228
    return $number;
229
}
230
 
231
#-------------------------------------------------------------------------------
232
# Function        : compareValues
233
#
234
# Description     : Compares two values
235
#
236
# Inputs          : $value          - Data from the machine
237
#                   $limit          - User limit
238
#                                     If '-' then sense of comparison is reversed 
239
#
240
# Returns         : True: value exceeds limit ( unless - ) 
241
#
242
sub compareValues
243
{
244
    my ($value, $limit) = @_;
245
    my $reverse = 0;
246
    if ( $limit =~ m~-(.*)~) {
247
        $reverse = 1;
248
        $limit = $1;
249
    }
250
    $limit = expandSuffix($limit);
251
    if ($reverse) {
252
        return $value < $limit
253
    } else {
254
        return $value > $limit
255
    }
256
}
257
 
258
 
259
#-------------------------------------------------------------------------------
5399 dpurdie 260
# Function        : getDataItem 
261
#
262
# Description     : Get an item of statistical data 
263
#
264
# Inputs          : $name       - Name of the item to get 
265
#
266
# Returns         : The value of the item or the text 'Unknown'
267
#
268
sub getDataItem
269
{
270
    my ($name) = @_;
271
    $name = lc $name;
272
    return 'Unknown' unless exists $stats{$name};
273
    return $stats{$name}; 
274
}
275
 
276
 
277
#-------------------------------------------------------------------------------
5398 dpurdie 278
# Function        : testPid 
279
#
280
# Description     : See if a PID exists    
281
#
282
# Inputs          : $name               - Name of pid file to examine
283
#
284
# Returns         : TRUE - looks OK
285
#
286
sub testPid
287
{
288
    my ($name) = @_;
289
    my $pidfile = catfile( $opt_rundir, $name . '.pid');
5399 dpurdie 290
    open (my $fh, $pidfile) || return 0;
5398 dpurdie 291
    my ($pid) = <$fh>;
292
    close $fh;
293
 
294
    if (defined $pid)
295
    {
296
        chomp $pid;
297
        $pid = int $pid;
298
        if ($pid > 0 )
299
        {
300
            # Brute force - unix specific check
301
            return 1 if -d catdir( '/proc', $pid);
302
        }
303
    }
304
    return 0;
305
}
306
 
307
 
308
#-------------------------------------------------------------------------------
309
# Function        : Error 
310
#
311
# Description     : Report an error to Nagios
312
#                   Returns an UNKNOWN exit code for Nagios
313
#
314
# Inputs          : Error string
315
#
316
# Returns         : Does not return
317
#
318
 
319
sub Error
320
{
321
    print("ERROR: @_\n");
322
    exit 3;
323
}
324
 
325
#-------------------------------------------------------------------------------
326
# Function        : Warning 
327
#
328
# Description     : Report an warning to Nagios
329
#                   Returns an WARNING exit code for Nagios
330
#
331
# Inputs          : Error string
332
#
333
# Returns         : Does not return
334
#
335
 
336
sub Warning
337
{
338
    print("Warning: @_\n");
339
    exit 1;
340
}
341
 
342
 
343
#-------------------------------------------------------------------------------
344
#   Documentation
345
#
346
 
347
=pod
348
 
349
=head1
350
 
351
blatNagios - Nagios Plugin for BLAT
352
 
353
=head1 SYNOPSIS
354
 
355
 blatNagios.pl [options]
356
 
357
 Options:
358
    -help              - brief help message
359
    -help -help        - Detailed help message
360
    -man               - Full documentation
361
    -target=name       - Target Machine name
362
    -rundir=path       - Alternate run directory
5399 dpurdie 363
    -data=item         - Data item to report as performance data. Multiple allowed
364
    -text=item         - Data item to report as text. Multiple allowed
5404 dpurdie 365
    -warn=item:vw:vc   - Report warnings for item. Multiple allowed
5398 dpurdie 366
 
367
=head1 OPTIONS
368
 
369
=over 8
370
 
371
=item B<-help>
372
 
373
Print a brief help message and exits.
374
 
375
=item B<-help -help>
376
 
377
Print a detailed help message with an explanation for each option.
378
 
379
=item B<-man>
380
 
381
Prints the manual page and exits.
382
 
383
=item B<-target=name>
384
 
385
The name of the target BLAT server. This will be used to locate the PID and STATS files
386
 
387
=item B<-rundir=path>
388
 
389
The path to the 'run' directory in which the targets PID and STATS files are stored.
390
 
391
If a relative path is provided, then it is relative to this script.
392
 
393
The default value if 'run'.
394
 
395
=item B<-data=item>
396
 
397
One or more data items to be returned as a part of the performance data.
398
 
399
Multiple items are comma seperated. The argument may be used more than once.
400
 
5399 dpurdie 401
=item B<-text=item>
402
 
403
One or more data items to be returned as a part of the text message.
404
 
405
Multiple items are comma seperated. The argument may be used more than once.
406
 
5404 dpurdie 407
=item B<-warn=item:vw:vc>
408
 
409
Report a Nagios error state if the value of the named item exceeds the specified value.
410
 
411
vw is the warning threshold. vc is the critical threshold.
412
 
6475 dpurdie 413
The warning and critical thresholds must be numeric with optional multipliers of K, M, G or T.
414
 
5404 dpurdie 415
Multiple items are comma seperated. The argument may be used more than once.
416
 
5398 dpurdie 417
=back
418
 
419
=head1 EXAMPLE
420
 
6475 dpurdie 421
perl blatNagios.pl -target=auawsaarc001 -data=txCount,delCount -data=linkErrors -warn=txCount:40:50  -w=Target.avail:15GB:10GB
5398 dpurdie 422
 
423
=cut
424