diff options
Diffstat (limited to 'plugins-scripts/check_ntp.pl')
-rwxr-xr-x | plugins-scripts/check_ntp.pl | 196 |
1 files changed, 134 insertions, 62 deletions
diff --git a/plugins-scripts/check_ntp.pl b/plugins-scripts/check_ntp.pl index 560a8775..5a3c44d2 100755 --- a/plugins-scripts/check_ntp.pl +++ b/plugins-scripts/check_ntp.pl | |||
@@ -58,8 +58,8 @@ require 5.004; | |||
58 | use POSIX; | 58 | use POSIX; |
59 | use strict; | 59 | use strict; |
60 | use Getopt::Long; | 60 | use Getopt::Long; |
61 | use vars qw($opt_V $opt_h $opt_H $opt_w $opt_c $verbose $PROGNAME); | 61 | use vars qw($opt_V $opt_h $opt_H $opt_w $opt_c $opt_j $opt_k $verbose $PROGNAME); |
62 | use lib utils.pm ; | 62 | use lib utils.pm; |
63 | use utils qw($TIMEOUT %ERRORS &print_revision &support); | 63 | use utils qw($TIMEOUT %ERRORS &print_revision &support); |
64 | 64 | ||
65 | $PROGNAME="check_ntp"; | 65 | $PROGNAME="check_ntp"; |
@@ -71,13 +71,21 @@ $ENV{'PATH'}=''; | |||
71 | $ENV{'BASH_ENV'}=''; | 71 | $ENV{'BASH_ENV'}=''; |
72 | $ENV{'ENV'}=''; | 72 | $ENV{'ENV'}=''; |
73 | 73 | ||
74 | # defaults in millisec | ||
75 | my $DEFAULT_OFFSET_WARN = 60000; | ||
76 | my $DEFAULT_OFFSET_CRIT = 120000; | ||
77 | my $DEFAULT_JITTER_WARN = 5000; | ||
78 | my $DEFAULT_JITTER_CRIT = 10000; | ||
79 | |||
74 | Getopt::Long::Configure('bundling'); | 80 | Getopt::Long::Configure('bundling'); |
75 | GetOptions | 81 | GetOptions |
76 | ("V" => \$opt_V, "version" => \$opt_V, | 82 | ("V" => \$opt_V, "version" => \$opt_V, |
77 | "h" => \$opt_h, "help" => \$opt_h, | 83 | "h" => \$opt_h, "help" => \$opt_h, |
78 | "v" => \$verbose, "verbose" => \$verbose, | 84 | "v" => \$verbose, "verbose" => \$verbose, |
79 | "w=f" => \$opt_w, "warning=f" => \$opt_w, # offset|adjust warning if above this number | 85 | "w=f" => \$opt_w, "warning=f" => \$opt_w, # offset|adjust warning if above this number |
80 | "c=f" => \$opt_c, "critical=f" => \$opt_c, # offset|adjust critical if above this number | 86 | "c=f" => \$opt_c, "critical=f" => \$opt_c, # offset|adjust critical if above this number |
87 | "j=s" => \$opt_j, "jwarn=s" => \$opt_j, # jitter warning if above this number | ||
88 | "k=s" => \$opt_k, "jcrit=s" => \$opt_k, # jitter critical if above this number | ||
81 | "H=s" => \$opt_H, "hostname=s" => \$opt_H); | 89 | "H=s" => \$opt_H, "hostname=s" => \$opt_H); |
82 | 90 | ||
83 | if ($opt_V) { | 91 | if ($opt_V) { |
@@ -98,36 +106,48 @@ unless ($host) { | |||
98 | exit $ERRORS{'UNKNOWN'}; | 106 | exit $ERRORS{'UNKNOWN'}; |
99 | } | 107 | } |
100 | 108 | ||
101 | ($opt_w) || ($opt_w = 60); | 109 | ($opt_w) || ($opt_w = $DEFAULT_OFFSET_WARN); |
102 | my $warning = $1 if ($opt_w =~ /([0-9.]+)/); | 110 | my $owarn = $1 if ($opt_w =~ /([0-9.]+)/); |
111 | |||
112 | ($opt_c) || ($opt_c = $DEFAULT_OFFSET_CRIT); | ||
113 | my $ocrit = $1 if ($opt_c =~ /([0-9.]+)/); | ||
103 | 114 | ||
104 | ($opt_c) || ($opt_c = 120); | 115 | ($opt_j) || ($opt_j = $DEFAULT_JITTER_WARN); |
105 | my $critical = $1 if ($opt_c =~ /([0-9.]+)/); | 116 | my $jwarn = $1 if ($opt_j =~ /([0-9]+)/); |
106 | 117 | ||
118 | ($opt_k) || ($opt_k = $DEFAULT_JITTER_CRIT); | ||
119 | my $jcrit = $1 if ($opt_k =~ /([0-9]+)/); | ||
107 | 120 | ||
108 | if ($critical < $warning ) { | 121 | if ($ocrit < $owarn ) { |
109 | print "Critical offset should be larger than warning offset\n"; | 122 | print "Critical offset should be larger than warning offset\n"; |
110 | print_usage(); | 123 | print_usage(); |
111 | exit $ERRORS{"UNKNOWN"}; | 124 | exit $ERRORS{"UNKNOWN"}; |
112 | } | 125 | } |
126 | if ($opt_k < $opt_j) { | ||
127 | print "Critical jitter should be larger than warning jitter\n"; | ||
128 | print_usage(); | ||
129 | exit $ERRORS{'UNKNOWN'}; | ||
130 | } | ||
113 | 131 | ||
114 | my $stratum = -1; | 132 | my $stratum = -1; |
115 | my $ignoreret = 0; | 133 | my $ignoreret = 0; |
116 | my $answer = undef; | 134 | my $answer = undef; |
117 | my $offset = undef; | 135 | my $offset = undef; |
136 | my $jitter = undef; | ||
137 | my $syspeer = undef; | ||
138 | my $candidates = 0; | ||
118 | my $msg; # first line of output to print if format is invalid | 139 | my $msg; # first line of output to print if format is invalid |
119 | 140 | ||
120 | my $state = $ERRORS{'UNKNOWN'}; | 141 | my $state = $ERRORS{'UNKNOWN'}; |
121 | my $ntpdate_error = $ERRORS{'UNKNOWN'}; | 142 | my $ntpdate_error = $ERRORS{'UNKNOWN'}; |
122 | my $dispersion_error = $ERRORS{'UNKNOWN'}; | 143 | my $jitter_error = $ERRORS{'UNKNOWN'}; |
123 | 144 | ||
124 | my $key = undef; | 145 | # some systems don't have a proper ntpq (migrated from ntpdc) |
125 | # some systems don't have a proper ntpdc/xntpdc | 146 | my $have_ntpq = undef; |
126 | my $have_ntpdc = undef; | 147 | if ($utils::PATH_TO_NTPQ && -x $utils::PATH_TO_NTPQ ) { |
127 | if ($utils::PATH_TO_NTPDC && -x $utils::PATH_TO_NTPDC ) { | 148 | $have_ntpq = 1; |
128 | $have_ntpdc = 1; | ||
129 | }else{ | 149 | }else{ |
130 | $have_ntpdc = 0; | 150 | $have_ntpq = 0; |
131 | } | 151 | } |
132 | 152 | ||
133 | # Just in case of problems, let's not hang Nagios | 153 | # Just in case of problems, let's not hang Nagios |
@@ -194,28 +214,54 @@ if ( $? && !$ignoreret ) { | |||
194 | 214 | ||
195 | ### | 215 | ### |
196 | ### | 216 | ### |
197 | ### Then scan xntpdc/ntpdc if it exists | 217 | ### Then scan xntpq/ntpq if it exists |
198 | ### and look in the 8th column for dispersion (ntpd v4) or jitter (ntpd v3) | 218 | ### and look in the 11th column for jitter |
199 | ### | 219 | ### |
220 | # Field 1: Tally Code ( Space, 'x','.','-','+','#','*','o') | ||
221 | # Only match for '*' which implies sys.peer | ||
222 | # or 'o' which implies pps.peer | ||
223 | # If both exist, the last one is picked. | ||
224 | # Field 2: address of the remote peer | ||
225 | # Field 3: Refid of the clock (0.0.0.0 if unknown) | ||
226 | # Field 4: stratum (0-15) | ||
227 | # Field 5: Type of the peer: local (l), unicast (u), multicast (m) | ||
228 | # broadcast (b); not sure about multicast/broadcast | ||
229 | # Field 6: last packet receive (in seconds) | ||
230 | # Field 7: polling interval | ||
231 | # Field 8: reachability resgister (octal) | ||
232 | # Field 9: delay | ||
233 | # Field 10: offset | ||
234 | # Field 11: dispersion/jitter | ||
235 | # | ||
200 | 236 | ||
201 | if ($have_ntpdc) { | 237 | if ($have_ntpq) { |
202 | 238 | ||
203 | if ( open(NTPDC,"$utils::PATH_TO_NTPDC -s $host 2>&1 |") ) { | 239 | if ( open(NTPQ,"$utils::PATH_TO_NTPQ -np $host 2>&1 |") ) { |
204 | while (<NTPDC>) { | 240 | while (<NTPQ>) { |
205 | print $_ if ($verbose); | 241 | print $_ if ($verbose); |
206 | if (/([^\s]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)/) { | 242 | # number of candidates on <host> for sys.peer |
207 | if ($8 gt $critical) { | 243 | if (/^(\*|\+|\#|o])/) { |
208 | print "Dispersion_crit = $8 :$critical\n" if ($verbose); | 244 | ++$candidates; |
209 | $dispersion_error = $ERRORS{'CRITICAL'}; | 245 | print "Candiate count= $candidates\n" if ($verbose); |
210 | } elsif ($8 gt $warning ) { | 246 | } |
211 | print "Dispersion_warn = $8 :$warning \n" if ($verbose); | 247 | |
212 | $dispersion_error = $ERRORS{'WARNING'}; | 248 | # match sys.peer or pps.peer |
249 | if (/^(\*|o)([-0-9.\s]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([lumb]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)\s+([-0-9.]+)/) { | ||
250 | $syspeer = $2; | ||
251 | $jitter = $11; | ||
252 | print "match $_ \n" if $verbose; | ||
253 | if ($jitter > $jcrit) { | ||
254 | print "Jitter_crit = $11 :$jcrit\n" if ($verbose); | ||
255 | $jitter_error = $ERRORS{'CRITICAL'}; | ||
256 | } elsif ($jitter > $jwarn ) { | ||
257 | print "Jitter_warn = $11 :$jwarn \n" if ($verbose); | ||
258 | $jitter_error = $ERRORS{'WARNING'}; | ||
213 | } else { | 259 | } else { |
214 | $dispersion_error = $ERRORS{'OK'}; | 260 | $jitter_error = $ERRORS{'OK'}; |
215 | } | 261 | } |
216 | } | 262 | } |
217 | } | 263 | } |
218 | close NTPDC; | 264 | close NTPQ; |
219 | } | 265 | } |
220 | } | 266 | } |
221 | 267 | ||
@@ -229,42 +275,58 @@ if ($ntpdate_error != $ERRORS{'OK'}) { | |||
229 | $answer = $msg . "Server for ntp probably down\n"; | 275 | $answer = $msg . "Server for ntp probably down\n"; |
230 | } | 276 | } |
231 | 277 | ||
232 | if (defined($offset) && abs($offset) > $critical) { | 278 | if (defined($offset) && abs($offset) > $ocrit) { |
233 | $state = $ERRORS{'CRITICAL'}; | 279 | $state = $ERRORS{'CRITICAL'}; |
234 | $answer = "Server Error and time difference $offset seconds greater than +/- $critical sec\n"; | 280 | $answer = "Server Error and offset $offset msec > +/- $ocrit msec\n"; |
235 | } elsif (defined($offset) && abs($offset) > $warning) { | 281 | } elsif (defined($offset) && abs($offset) > $owarn) { |
236 | $answer = "Server error and time difference $offset seconds greater than +/- $warning sec\n"; | 282 | $answer = "Server error and offset $offset msec > +/- $owarn msec\n"; |
283 | } elsif (defined($jitter) && abs($jitter) > $jcrit) { | ||
284 | $answer = "Server error and jitter $jitter msec > +/- $jcrit msec\n"; | ||
285 | } elsif (defined($jitter) && abs($jitter) > $jwarn) { | ||
286 | $answer = "Server error and jitter $jitter msec > +/- $jwarn msec\n"; | ||
237 | } | 287 | } |
238 | 288 | ||
239 | } elsif ($have_ntpdc && $dispersion_error != $ERRORS{'OK'}) { | 289 | } elsif ($have_ntpq && $jitter_error != $ERRORS{'OK'}) { |
240 | $state = $dispersion_error; | 290 | $state = $jitter_error; |
241 | $answer = "Dispersion too high\n"; | 291 | $answer = "Jitter $jitter too high\n"; |
242 | if (defined($offset) && abs($offset) > $critical) { | 292 | if (defined($offset) && abs($offset) > $ocrit) { |
243 | $state = $ERRORS{'CRITICAL'}; | 293 | $state = $ERRORS{'CRITICAL'}; |
244 | $answer = "Dispersion error and time difference $offset seconds greater than +/- $critical sec\n"; | 294 | $answer = "Jitter error and offset $offset msec > +/- $ocrit msec\n"; |
245 | } elsif (defined($offset) && abs($offset) > $warning) { | 295 | } elsif (defined($offset) && abs($offset) > $owarn) { |
246 | $answer = "Dispersion error and time difference $offset seconds greater than +/- $warning sec\n"; | 296 | $answer = "Jitter error and offset $offset msec > +/- $owarn msec\n"; |
297 | } elsif (defined($jitter) && abs($jitter) > $jcrit) { | ||
298 | $answer = "Jitter error and jitter $jitter msec > +/- $jcrit msec\n"; | ||
299 | } elsif (defined($jitter) && abs($jitter) > $jwarn) { | ||
300 | $answer = "Jitter error and jitter $jitter msec > +/- $jwarn msec\n"; | ||
247 | } | 301 | } |
248 | 302 | ||
249 | } else { # no errors from ntpdate or xntpdc | 303 | } else { # no errors from ntpdate or ntpq |
250 | if (defined $offset) { | 304 | if (abs($offset) > $ocrit) { |
251 | if (abs($offset) > $critical) { | 305 | $state = $ERRORS{'CRITICAL'}; |
252 | $state = $ERRORS{'CRITICAL'}; | 306 | $answer = "Offset $offset msec > +/- $ocrit msec, jitter $jitter msec\n"; |
253 | $answer = "Time difference $offset seconds greater than +/- $critical sec\n"; | 307 | } elsif (abs($jitter) > $jcrit ) { |
254 | } elsif (abs($offset) > $warning) { | 308 | $state = $ERRORS{'CRITICAL'}; |
255 | $state = $ERRORS{'WARNING'}; | 309 | $answer = "Jitter $jitter msec> +/- $jcrit msec, offset $offset msec \n"; |
256 | $answer = "Time difference $offset seconds greater than +/- $warning sec\n"; | 310 | } elsif (abs($offset) > $owarn) { |
257 | } elsif (abs($offset) <= $warning) { | 311 | $state = $ERRORS{'WARNING'}; |
258 | $state = $ERRORS{'OK'}; | 312 | $answer = "Offset $offset msec > +/- $owarn msec, jitter $jitter msec\n"; |
259 | $answer = "Time difference $offset seconds\n"; | 313 | } elsif (abs($jitter) > $jwarn ) { |
260 | } | 314 | $state = $ERRORS{'WARNING'}; |
261 | } else { # no offset defined | 315 | $answer = "Jitter $jitter msec> +/- $jwarn msec, offset $offset msec \n"; |
262 | $state = $ERRORS{'UNKNOWN'}; | 316 | |
263 | $answer = "Invalid format returned from ntpdate ($msg)\n"; | 317 | } else { |
318 | $state = $ERRORS{'OK'}; | ||
319 | $answer = "Offset $offset msecs, jitter $jitter msec\n"; | ||
264 | } | 320 | } |
321 | |||
322 | # else { # no offset defined | ||
323 | # $state = $ERRORS{'UNKNOWN'}; | ||
324 | # $answer = "Invalid format returned from ntpdate ($msg)\n"; | ||
325 | # } | ||
326 | |||
265 | } | 327 | } |
266 | 328 | ||
267 | foreach $key (keys %ERRORS) { | 329 | foreach my $key (keys %ERRORS) { |
268 | if ($state==$ERRORS{$key}) { | 330 | if ($state==$ERRORS{$key}) { |
269 | print ("$key: $answer"); | 331 | print ("$key: $answer"); |
270 | last; | 332 | last; |
@@ -272,8 +334,12 @@ foreach $key (keys %ERRORS) { | |||
272 | } | 334 | } |
273 | exit $state; | 335 | exit $state; |
274 | 336 | ||
337 | |||
338 | #### | ||
339 | #### subs | ||
340 | |||
275 | sub print_usage () { | 341 | sub print_usage () { |
276 | print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>] [-v verbose]\n"; | 342 | print "Usage: $PROGNAME -H <host> [-w <warn>] [-c <crit>] [-j <warn>] [-k <crit>] [-v verbose]\n"; |
277 | } | 343 | } |
278 | 344 | ||
279 | sub print_help () { | 345 | sub print_help () { |
@@ -281,10 +347,16 @@ sub print_help () { | |||
281 | print "Copyright (c) 2000 Bo Kersey/Karl DeBisschop\n"; | 347 | print "Copyright (c) 2000 Bo Kersey/Karl DeBisschop\n"; |
282 | print "\n"; | 348 | print "\n"; |
283 | print_usage(); | 349 | print_usage(); |
284 | print "\n"; | 350 | print " |
285 | print "<warn> = Clock offset in seconds at which a warning message will be generated.\n Defaults to 60.\n"; | 351 | Checks the local timestamp offset versus <host> with ntpdate |
286 | print "<crit> = Clock offset in seconds at which a critical message will be generated.\n Defaults to 120.\n\n"; | 352 | Checks the jitter/dispersion of clock signal between <host> and its sys.peer with ntpq\n |
287 | print "The same warning and critical values are used to check against the dispersion \n"; | 353 | -w ( --warning) |
288 | print "column of ntpdc/xntpdc for the host being queried.\n\n"; | 354 | Clock offset in milliseconds at which a warning message will be generated.\n Defaults to $DEFAULT_OFFSET_WARN. |
355 | -c (--critical) | ||
356 | Clock offset in milliseconds at which a critical message will be generated.\n Defaults to $DEFAULT_OFFSET_CRIT. | ||
357 | -j (--jwarn) | ||
358 | Clock jitter in milliseconds at which a warning message will be generated.\n Defaults to $DEFAULT_JITTER_WARN. | ||
359 | -k (--jcrit) | ||
360 | Clock jitter in milliseconds at which a warning message will be generated.\n Defaults to $DEFAULT_JITTER_CRIT.\n"; | ||
289 | support(); | 361 | support(); |
290 | } | 362 | } |