diff options
| -rw-r--r-- | configure.in | 5 | ||||
| -rwxr-xr-x | plugins-scripts/check_ntp.pl | 196 | ||||
| -rw-r--r-- | plugins-scripts/utils.pm.in | 4 |
3 files changed, 141 insertions, 64 deletions
diff --git a/configure.in b/configure.in index 919461c7..f2996525 100644 --- a/configure.in +++ b/configure.in | |||
| @@ -772,9 +772,10 @@ AC_DEFINE_UNQUOTED(PATH_TO_RPCINFO,"$PATH_TO_RPCINFO",[path to rpcinfo binary]) | |||
| 772 | 772 | ||
| 773 | AC_PATH_PROG(PATH_TO_NTPDATE,ntpdate) | 773 | AC_PATH_PROG(PATH_TO_NTPDATE,ntpdate) |
| 774 | AC_PATH_PROGS(PATH_TO_NTPDC,ntpdc xntpdc) | 774 | AC_PATH_PROGS(PATH_TO_NTPDC,ntpdc xntpdc) |
| 775 | if (test -x "$PATH_TO_NTPDATE" || test -x "$PATH_TO_NTPDC") | 775 | AC_PATH_PROGS(PATH_TO_NTPQ,ntpq) |
| 776 | if (test -x "$PATH_TO_NTPDATE" || test -x "$PATH_TO_NTPQ") | ||
| 776 | then | 777 | then |
| 777 | AC_DEFINE_UNQUOTED(PATH_TO_NTPDC,"$PATH_TO_NTPDC",[path to ntpdc binary]) | 778 | AC_DEFINE_UNQUOTED(PATH_TO_NTPQ,"$PATH_TO_NTPQ",[path to ntpq binary]) |
| 778 | AC_DEFINE_UNQUOTED(PATH_TO_NTPDATE,"$PATH_TO_NTPDATE",[path to ntpdate binary]) | 779 | AC_DEFINE_UNQUOTED(PATH_TO_NTPDATE,"$PATH_TO_NTPDATE",[path to ntpdate binary]) |
| 779 | else | 780 | else |
| 780 | echo "** Install NTP programs (http://www.ntp.org) if you want to monitor time synchronization" | 781 | echo "** Install NTP programs (http://www.ntp.org) if you want to monitor time synchronization" |
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 | } |
diff --git a/plugins-scripts/utils.pm.in b/plugins-scripts/utils.pm.in index 05735eb4..8316f9e1 100644 --- a/plugins-scripts/utils.pm.in +++ b/plugins-scripts/utils.pm.in | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | # $Id$ | 2 | # $Id$ |
| 3 | # | 3 | # |
| 4 | # $Log$ | 4 | # $Log$ |
| 5 | # Revision 1.6 2003/02/03 20:29:55 sghosh | ||
| 6 | # change ntpdc to ntpq (Jonathan Rozes,Thomas Schimpke, bug-656237 ) | ||
| 7 | # | ||
| 5 | # Revision 1.5 2002/10/30 05:07:29 sghosh | 8 | # Revision 1.5 2002/10/30 05:07:29 sghosh |
| 6 | # monitor mailq | 9 | # monitor mailq |
| 7 | # | 10 | # |
| @@ -32,6 +35,7 @@ sub is_hostname; | |||
| 32 | $PATH_TO_RPCINFO = "@PATH_TO_RPCINFO@" ; | 35 | $PATH_TO_RPCINFO = "@PATH_TO_RPCINFO@" ; |
| 33 | $PATH_TO_NTPDATE = "@PATH_TO_NTPDATE@" ; | 36 | $PATH_TO_NTPDATE = "@PATH_TO_NTPDATE@" ; |
| 34 | $PATH_TO_NTPDC = "@PATH_TO_NTPDC@" ; | 37 | $PATH_TO_NTPDC = "@PATH_TO_NTPDC@" ; |
| 38 | $PATH_TO_NTPQ = "@PATH_TO_NTPQ@" ; | ||
| 35 | $PATH_TO_LMSTAT = "@PATH_TO_LMSTAT@" ; | 39 | $PATH_TO_LMSTAT = "@PATH_TO_LMSTAT@" ; |
| 36 | $PATH_TO_SMBCLIENT = "@PATH_TO_SMBCLIENT@" ; | 40 | $PATH_TO_SMBCLIENT = "@PATH_TO_SMBCLIENT@" ; |
| 37 | $PATH_TO_MAILQ = "@PATH_TO_MAILQ@"; | 41 | $PATH_TO_MAILQ = "@PATH_TO_MAILQ@"; |
