Code

Fix for regex input of '|', being output causing problems with Nagios' parsing of
[nagiosplug.git] / contrib / mrtgext.pl
1 #!/usr/bin/perl -w
2 #
3 #  mrtgext.pl  v0.3
4 #    (c)2000 Cliff Woolley, Washington and Lee University
5 #    jwoolley@wlu.edu
6 #
7 #  A UNIX counterpart to Jim Drews' MRTG Extension for netware servers
8 #  Mimics output of mrtgext.nlm using output of various standard UNIX
9 #  programs (df, uptime, and uname)
10 #
11 #  Dependencies:  I make some assumptions about the output format of
12 #  your df and uptime commands.  If you have nonstandard outputs for
13 #  any of these, either pick a different command that gives more
14 #  standard output or modify the script below.  Example: use /usr/bin/bdf
15 #  on HP-UX instead of /usr/bin/df, because bdf follows the output format
16 #  I expect while df does not.  This was written on Linux and tested on
17 #  HP-UX 10.20 (with changes to the subroutines at the bottom of the
18 #  program to reflect HP's command parameters); similar tweaking could
19 #  well be required to port this to other platforms.  If you get it
20 #  working on your platform, please send me any changes you had to
21 #  make so I can try to incorporate them.
22 #
23 #
24 #  Following is what I expect the programs' outputs to look like:
25 #  
26 #  ======= df ========
27 #  Filesystem           1k-blocks      Used Available Use% Mounted on
28 #  /dev/sda1              1014696    352708    609612  37% /
29 #  /dev/sda2              2262544    586712   1559048  27% /apps
30 #  /dev/sda3              4062912    566544   3286604  15% /share
31 #  /dev/sr0                651758    651758         0 100% /cdrom
32 #  ===================
33 #
34 #  ===== uptime ======
35 #  3:17pm  up 15 days,  4:40,  5 users,  load average: 0.12, 0.26, 0.33
36 #  ===================
37 #
39 ###############################################################
40 #  Configuration section
41 ###############################################################
43 $dfcmd          = "/bin/df 2>/dev/null";
44 $uptimecmd      = "/usr/bin/uptime";
45 %customcmds     = ( "PROCS"    => "numprocesses",
46                     "ZOMBIES"  => "numzombies",
47                     "MEMFREE"  => "memfree",
48                     "SWAPUSED" => "swapused",
49                     "TCPCONNS" => "tcpconns",
50                     "CLIENTS"  => "ipclients" );
51                            # These are functions that you can
52                            # define and customize for your system.
53                            # You probably need to change the provided
54                            # subroutines to work on your system (if
55                            # not Linux).
57 $rootfsnickname = "root";  # this is necessary as a kludge to
58                            # better match the netware behavior.
59                            # if you already have a _filesystem_
60                            # mounted as /root, then you'll need
61                            # to change this to something else
62 $DEBUG          = 0;
63 $recvtimeout    = 30;
66 ###############################################################
67 #  Program section
68 ###############################################################
70 require 5.004;
72 use Sys::Hostname;
75 $DEBUG = $ARGV[0] unless ($DEBUG);
76 $SIG{'ALRM'} = sub { exit 1; };
78 # some things never change
79 $hostname = hostname;
82 if ( $DEBUG ) {
83     $| = 1;
84     print scalar localtime,": mrtgext.pl started\n";
85 }
87 # timeout period 
88 alarm($recvtimeout);
89 my $items = <STDIN>;
90 alarm(0);
92 $items =~ s/[\r\n]//g;
93 ( $DEBUG ) && print scalar localtime,": request: \"$items\"\n";
94 my @items = split (/\s+/,"$items");
95 ( $DEBUG ) && print scalar localtime,": ",scalar @items," item(s) to process\n";
97 my $uptime = `$uptimecmd`;
98 my @df     = grep {/^\//} `$dfcmd`;
100 my $processed = 1;
102 foreach $_ (@items) {
103     ( $DEBUG ) && print scalar localtime,": processing item #$processed: \"$_\"\n";
104     $_ = uc; #convert $_ to upper case
105     if    ( /^UTIL1$/ ) {
106         $uptime =~ /load average: ([^,]+),/;
107         print $1 * 100,"\n";
108     }
109     elsif ( /^UTIL5$/ ) {
110         $uptime =~ /load average: [^,]+, ([^,]+)/;
111         print $1 * 100,"\n";
112     }
113     elsif ( /^UTIL15$/ ) {
114         $uptime =~ /load average: [^,]+, [^,]+, ([^,]+)/;
115         print $1 * 100,"\n";
116     }
117     elsif ( /^CONNECT$/ ) {
118         $uptime =~ /(\d+) users?,/;
119         print "$1\n";
120     }
121     elsif ( /^NAME$/ ) {
122         print "$hostname\n";
123     }
124     elsif ( /^UPTIME$/ ) {
125         $uptime =~ /up (.*),\s+\d+\s+users?,/;
126         print "$1\n";
127     }
128     elsif ( /^VOLUMES$/ ) {
129         foreach $dfline (@df) {
130             my $volname = (split(/\s+/, "$dfline"))[5];
131             $volname =~ s/^\/$/$rootfsnickname/;
132             $volname =~ s/^\///;
133             $volname =~ s/\//_/g;
134             print "$volname\n";
135         }
136     }
137     elsif ( /^VF(\w*)$/ ) {
138         my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
139         foreach $dfline (@df) {
140             my @dfline = split(/\s+/, "$dfline");
141             if ($dfline[5] =~ /^\/?$volname$/i ) {
142                 print (($dfline[1]-$dfline[2]) * 1024,"\n");
143                 goto done;
144             }
145         }
146         ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
147         print "-1\n";
148     }
149     elsif ( /^VU(\w*)$/ ) {
150         my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
151         foreach $dfline (@df) {
152             my @dfline = split(/\s+/, "$dfline");
153             if ($dfline[5] =~ /^\/?$volname$/i ) {
154                 print ($dfline[2] * 1024,"\n");
155                 goto done;
156             }
157         }
158         ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
159         print "-1\n";
160     }
161     elsif ( /^VS(\w*)$/ ) {
162         my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
163         foreach $dfline (@df) {
164             my @dfline = split(/\s+/, "$dfline");
165             if ($dfline[5] =~ /^\/?$volname$/i ) {
166                 print ($dfline[1] * 1024,"\n");
167                 goto done;
168             }
169         }
170         ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
171         print "-1\n";
172     }
173     elsif ( /^VKF(\w*)$/ ) {
174         my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
175         foreach $dfline (@df) {
176             my @dfline = split(/\s+/, "$dfline");
177             if ($dfline[5] =~ /^\/?$volname$/i ) {
178                 print (($dfline[1]-$dfline[2]),"\n");
179                 goto done;
180             }
181         }
182         ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
183         print "-1\n";
184     }
185     elsif ( /^VKU(\w*)$/ ) {
186         my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
187         foreach $dfline (@df) {
188             my @dfline = split(/\s+/, "$dfline");
189             if ($dfline[5] =~ /^\/?$volname$/i ) {
190                 print ($dfline[2],"\n");
191                 goto done;
192             }
193         }
194         ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
195         print "-1\n";
196     }
197     elsif ( /^VKS(\w*)$/ ) {
198         my $volname = ("$1" eq uc("$rootfsnickname")) ? "/" : "$1";
199         foreach $dfline (@df) {
200             my @dfline = split(/\s+/, "$dfline");
201             if ($dfline[5] =~ /^\/?$volname$/i ) {
202                 print ($dfline[1],"\n");
203                 goto done;
204             }
205         }
206         ( $DEBUG ) && print scalar localtime,": ERROR: volume not found.\n";
207         print "-1\n";
208     }
209     elsif ( /^ZERO$/ ) {
210         print "0\n";
211     }
212     elsif (exists( $customcmds{"$_"} )) {
213         my $cmdsub = "$customcmds{$_}";
214         print &$cmdsub."\n";
215     }
216     else {
217         print "-1\n";
218     }
219     done: $processed++;
221 ( $DEBUG ) && print scalar localtime,": done.\n";
224 ###############################################################
225 #  CUSTOMIZED PROCEDURES
226 ###############################################################
228 sub numprocesses {
230     my $num = `/bin/ps -eaf | /usr/bin/tail -n +2 | /usr/bin/wc -l`;
231     chomp ($num);
232     $num =~ s/\s+//g;
234     $num;
237 sub numzombies {
239     my $num = `/bin/ps -afx | /usr/bin/awk '{print \$3}' | /usr/bin/grep Z | /usr/bin/tail -n +2 | /usr/bin/wc -l`;
240     chomp ($num);
241     $num =~ s/\s+//g;
243     $num;
246 sub tcpconns {
248     my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/wc -l`;
249     chomp ($num);
250     $num =~ s/\s+//g;
252     $num;
255 sub ipclients {
257     my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/awk '{print \$5}' | /bin/cut -d : -f 1 | /usr/bin/sort -nu | /usr/bin/wc -l`;
258     chomp ($num);
259     $num =~ s/\s+//g;
261     $num;
264 sub memfree {
266     open( FP, "/proc/meminfo" );
267     my @meminfo = <FP>;
268     close(FP);
270     #         total:    used:    free:  shared: buffers:  cached:
271     # Mem:  994615296 592801792 401813504 91193344 423313408 93118464
272     # Swap: 204791808        0 204791808
273     my ($total,$free,$buffers,$cache) = (split(/ +/,$meminfo[1]))[1,3,5,6];
274     
275     int(($free+$buffers+$cache)/$total*100);
278 sub swapused {
280     open( FP, "/proc/meminfo" );
281     my @meminfo = <FP>;
282     close(FP);
284     #         total:    used:    free:  shared: buffers:  cached:
285     # Mem:  994615296 592424960 402190336 89821184 423313408 93077504
286     # Swap: 204791808        0 204791808
288     my ($total,$used) = (split(/ +/,$meminfo[2]))[1,2];
289     
290     int($used/$total*100);