diff options
Diffstat (limited to 'contrib/mrtgext.pl')
-rw-r--r-- | contrib/mrtgext.pl | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/contrib/mrtgext.pl b/contrib/mrtgext.pl new file mode 100644 index 0000000..b9e9f6b --- /dev/null +++ b/contrib/mrtgext.pl | |||
@@ -0,0 +1,291 @@ | |||
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 | # | ||
38 | |||
39 | ############################################################### | ||
40 | # Configuration section | ||
41 | ############################################################### | ||
42 | |||
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). | ||
56 | |||
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; | ||
64 | |||
65 | |||
66 | ############################################################### | ||
67 | # Program section | ||
68 | ############################################################### | ||
69 | |||
70 | require 5.004; | ||
71 | |||
72 | use Sys::Hostname; | ||
73 | |||
74 | |||
75 | $DEBUG = $ARGV[0] unless ($DEBUG); | ||
76 | $SIG{'ALRM'} = sub { exit 1; }; | ||
77 | |||
78 | # some things never change | ||
79 | $hostname = hostname; | ||
80 | |||
81 | |||
82 | if ( $DEBUG ) { | ||
83 | $| = 1; | ||
84 | print scalar localtime,": mrtgext.pl started\n"; | ||
85 | } | ||
86 | |||
87 | # timeout period | ||
88 | alarm($recvtimeout); | ||
89 | my $items = <STDIN>; | ||
90 | alarm(0); | ||
91 | |||
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"; | ||
96 | |||
97 | my $uptime = `$uptimecmd`; | ||
98 | my @df = grep {/^\//} `$dfcmd`; | ||
99 | |||
100 | my $processed = 1; | ||
101 | |||
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++; | ||
220 | } | ||
221 | ( $DEBUG ) && print scalar localtime,": done.\n"; | ||
222 | |||
223 | |||
224 | ############################################################### | ||
225 | # CUSTOMIZED PROCEDURES | ||
226 | ############################################################### | ||
227 | |||
228 | sub numprocesses { | ||
229 | |||
230 | my $num = `/bin/ps -eaf | /usr/bin/tail -n +2 | /usr/bin/wc -l`; | ||
231 | chomp ($num); | ||
232 | $num =~ s/\s+//g; | ||
233 | |||
234 | $num; | ||
235 | } | ||
236 | |||
237 | sub numzombies { | ||
238 | |||
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; | ||
242 | |||
243 | $num; | ||
244 | } | ||
245 | |||
246 | sub tcpconns { | ||
247 | |||
248 | my $num = `/bin/netstat -nt | /usr/bin/tail -n +3 | /usr/bin/wc -l`; | ||
249 | chomp ($num); | ||
250 | $num =~ s/\s+//g; | ||
251 | |||
252 | $num; | ||
253 | } | ||
254 | |||
255 | sub ipclients { | ||
256 | |||
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; | ||
260 | |||
261 | $num; | ||
262 | } | ||
263 | |||
264 | sub memfree { | ||
265 | |||
266 | open( FP, "/proc/meminfo" ); | ||
267 | my @meminfo = <FP>; | ||
268 | close(FP); | ||
269 | |||
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); | ||
276 | } | ||
277 | |||
278 | sub swapused { | ||
279 | |||
280 | open( FP, "/proc/meminfo" ); | ||
281 | my @meminfo = <FP>; | ||
282 | close(FP); | ||
283 | |||
284 | # total: used: free: shared: buffers: cached: | ||
285 | # Mem: 994615296 592424960 402190336 89821184 423313408 93077504 | ||
286 | # Swap: 204791808 0 204791808 | ||
287 | |||
288 | my ($total,$used) = (split(/ +/,$meminfo[2]))[1,2]; | ||
289 | |||
290 | int($used/$total*100); | ||
291 | } | ||