summaryrefslogtreecommitdiffstats
path: root/contrib/check_sybase
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/check_sybase')
-rwxr-xr-xcontrib/check_sybase332
1 files changed, 332 insertions, 0 deletions
diff --git a/contrib/check_sybase b/contrib/check_sybase
new file mode 100755
index 0000000..20b4a30
--- /dev/null
+++ b/contrib/check_sybase
@@ -0,0 +1,332 @@
1#!/usr/bin/perl -w
2# check_sybase
3# A nagios plugin that connects to a Sybase database and checks free space.
4#
5# Copyright 2004 Simon Bellwood, NetMan Network Management and IT Services GmbH
6# Portions Copyright 2001 Michael Peppler.
7# License: GPL
8#
9# Bugs and feedback to simon.bellwood@nospam.net-man.at
10# Latest version available from:
11# http://www.net-man.at/software/check_sybase-LATEST.zip
12#
13# Revision history:
14# 0.1 01-OCT-2004 Initial version.
15# 0.2 08-NOV-2004 Initial release.
16my $VERSION = "0.2";
17
18use strict;
19use DBI;
20use Getopt::Long;
21use lib "/usr/local/nagios/libexec";
22use utils qw(%ERRORS &print_revision &support &usage $TIMEOUT);
23
24
25my $PROGNAME = "check_sybase";
26my $DEFAULT_CHECKTYPE = "FREESPACE";
27my $DEFAULT_WARNING = "25";
28my $DEFAULT_CRITICAL = "10";
29
30my ($user, $pass, $dbsvr, $dbname, $config, $checktype, $warn, $crit, $timeout,
31 $help, $version);
32
33my $options_okay = GetOptions(
34 "U|user=s" => \$user,
35 "P|pass:s" => \$pass, # ":" means optional
36 "S|dbsvr=s" => \$dbsvr,
37 "D|dbname=s" => \$dbname,
38 "config=s" => \$config,
39 "checktype=s" => \$checktype,
40 "w|warning=i" => \$warn,
41 "c|critical=i" => \$crit,
42 "t|timeout=i" => \$timeout,
43 "h|help" => \$help,
44 "V|version" => \$version
45);
46
47
48if (! $options_okay) # Bad option passed
49{
50 &help;
51 &nunk("Bad command line option passed!");
52}
53
54# Use defaults, if needed
55$warn = $warn || $DEFAULT_WARNING;
56$crit = $crit || $DEFAULT_CRITICAL;
57$checktype = $checktype || $DEFAULT_CHECKTYPE;
58$timeout = $timeout || $TIMEOUT;
59
60if ($help)
61{
62 &help;
63 &nok;
64}
65
66if ($version)
67{
68 print_revision($PROGNAME,"\$Revision$VERSION \$");
69 &nok;
70}
71
72if ($config) # Read any of "user", "pass", "dbsvr", "dbname" from config file
73{
74 &read_config;
75}
76
77# Some more descriptive syntax checks
78my $syntax_error;
79$syntax_error .= "No dbsvr given! " unless $dbsvr;
80$syntax_error .= "No dbname given! " unless $dbname;
81$syntax_error .= "No user given! " unless $user;
82$syntax_error .= "Bad checktype given!"
83 unless $checktype =~ m/^CONNECT|FREESPACE$/;
84&nunk($syntax_error) if $syntax_error;
85
86
87# Just in case of problems, let's not hang Nagios
88$SIG{'ALRM'} = sub {
89 &nunk("Timeout: no response from dbsvr $dbsvr within $timeout seconds");
90};
91alarm($timeout);
92
93
94# Decide on what we are checking
95if ($checktype eq "CONNECT")
96{
97 &connect;
98}
99elsif ($checktype eq "FREESPACE")
100{
101 &check_space;
102}
103
104my $dbh;
105my $is_connected;
106sub connect
107{
108 $dbh = DBI->connect("dbi:Sybase:server=$dbsvr;database=$dbname",
109 $user, $pass)
110 or &ncrit("Could not connect to '$dbname' on '$dbsvr'");
111
112 # Report success for a check of type CONNECT
113 &nok("Connect okay") if $checktype ne "FREESPACE";
114}
115
116sub disconnect
117{
118 $dbh->disconnect if $is_connected;
119 $is_connected = 0;
120}
121
122sub check_space
123{
124 &connect;
125
126 # Most of this sub based on Michael Peppler's check-space.pl
127
128 $dbh->{syb_do_proc_status} = 1;
129
130 my $dbinfo;
131
132 # First check space in the database
133 my $sth = $dbh->prepare("sp_spaceused")
134 or &nunk("Failed to call sp_spaceused on '$dbsvr'");
135 $sth->execute
136 or &nunk("Failed to call sp_spaceused on '$dbsvr'");
137 do {
138 while(my $d = $sth->fetch)
139 {
140 if($d->[0] =~ /$dbname/)
141 {
142 # Grab "database_size"
143 $d->[1] =~ s/[^\d.]//g;
144 $dbinfo->{size} = $d->[1];
145 }
146 else
147 {
148 foreach (@$d)
149 {
150 s/\D//g;
151 }
152
153 # Grab "reserved", "data", "index"
154 $dbinfo->{reserved} = $d->[0] / 1024;
155 $dbinfo->{data} = $d->[1] / 1024;
156 $dbinfo->{index} = $d->[2] / 1024;
157 }
158 }
159 } while($sth->{syb_more_results});
160
161 # Get the actual device usage from sp_helpdb to get the free log space
162 $sth = $dbh->prepare("sp_helpdb $dbname")
163 or &nunk("Failed to call sp_helpdb $dbname on '$dbsvr'");
164 $sth->execute
165 or &nunk("Failed to call sp_helpdb $dbname on '$dbsvr'");
166 do {
167 while(my $d = $sth->fetch)
168 {
169 # Look for "usage" column with value "log only"
170 if($d->[2] && $d->[2] =~ /log only/)
171 {
172 # Grab "size", add it to our log size
173 $d->[1] =~ s/[^\d\.]//g;
174 $dbinfo->{log} += $d->[1];
175 }
176
177 # Look for "device fragments" column with "log only"
178 # followed by a number.
179 if($d->[0] =~ /log only .* (\d+)/)
180 {
181 $dbinfo->{logfree} = $1 / 1024;
182 }
183 }
184 } while($sth->{syb_more_results});
185
186 # Subtract the log size from the database size
187 $dbinfo->{size} -= $dbinfo->{log};
188
189 # The "reserved" space is free for use by the table that freed it, so
190 # it is not truly free space. To be safe, our calculation ignores it.
191 my $free = ($dbinfo->{size} - $dbinfo->{reserved}) / $dbinfo->{size};
192 $free = sprintf("%.2f", $free*100);
193
194
195 if ($free < $crit)
196 {
197 &ncrit("Free space is $free%! (critical threshold is $crit%)");
198 }
199
200 if ($free < $warn)
201 {
202 &nwarn("Free space is $free%! (warning threshold is $warn%)");
203 }
204
205
206 &nok("Free space within thresholds ($free% free)");
207}
208
209sub read_config
210{
211 open (CONFIG, "<$config")
212 or &nunk("Failed to open config file '$config': $!");
213 while (<CONFIG>)
214 {
215 chomp;
216 next if m/^#/; # skip comments
217 next if m/^$/; # skip blanks
218
219 # Each case-insensitive argument can be followed by an optional
220 # colon, then must be followed by whitespace and the value.
221 # Options in the config file override those given on the
222 # command line, but don't rely on this!
223
224 if (m/USER:?\s+(\S+)/i)
225 {
226 $user = $1;
227 }
228 elsif (m/PASS:?\s+(\S+)/i)
229 {
230 $pass = $1;
231 }
232 elsif (m/DBSVR:?\s+(\S+)/i)
233 {
234 $dbsvr = $1;
235 }
236 elsif (m/DBNAME:?\s+(\S+)/i)
237 {
238 $dbname = $1;
239 }
240 else
241 {
242 &nunk("Invalid line $. in config file '$config'");
243 }
244 }
245 close (CONFIG);
246}
247
248sub help
249{
250 print <<_HELP_;
251Usage: $PROGNAME OPTIONS
252A nagios plugin that connects to a Sybase database and checks free space.
253
254Mandatory arguments to long options are mandatory for short options too.
255 -U, --user Username to connect to database.
256 -P, --pass Password to connect to database.
257 -S, --dbsvr Database server (as in the interfaces file).
258 -D, --dbname Database name to check.
259 --config=FILE Config file (see SECURITY below)
260 --checktype=TYPE Type of check to run (see TYPEs below)
261 -w, --warning Warning threshold, in percent (default 25)
262 -c, --critical Critical threshold, in percent (default 10)
263 -t, --timeout Timeout value, in seconds (default 30)
264 -h, --help This help message
265 -V, --version Version information
266
267Examples:
268 $PROGNAME -U sa -P secret -S bigbox -D orders
269 $PROGNAME --config=/secure/nagios-sybase.cfg --checktype=CONNECT
270
271TYPEs
272 There are two types of checks you can run:
273 --checktype=CONNECT
274 Checks just the connection to the database.
275 --checktype=FREESPACE
276 (Default) Checks both the connection to the database and the free space.
277
278SECURITY - Using a config file
279 Since a "ps ax" will reveal your database username and password, you can
280 instead specify them in a config file. Pass the config file with --config.
281 The format of the file is:
282 USER value
283 PASS value
284 You can also specify a DBSVR and DBNAME in the file. Comments (#) and blank
285 lines are ignored. Use whitespace to separate argument and value.
286_HELP_
287
288}
289
290
291
292# Some wrappers..
293
294# Returns code 0, OK
295sub nok
296{
297 my $msg = shift;
298 print "OK: $msg\n" if $msg;
299
300 &disconnect;
301 exit $ERRORS{OK};
302}
303
304# Returns code 1, Warning
305sub nwarn
306{
307 my $msg = shift;
308 print "WARNING: $msg\n";
309
310 &disconnect;
311 exit $ERRORS{WARNING};
312}
313
314# Returns code 2, Critical
315sub ncrit
316{
317 my $msg = shift;
318 print "CRITICAL: $msg\n";
319
320 &disconnect;
321 exit $ERRORS{CRITICAL};
322}
323
324# Returns code 3, Unknown
325sub nunk
326{
327 my $msg = shift;
328 print "ERROR: $msg\n";
329
330 &disconnect;
331 exit $ERRORS{UNKNOWN};
332}