#!/usr/bin/env perl #=============================================================================== # DESCRIPTION: Icinga2 / Nagios Check for chrony time sync status and offset # # OPTIONS: -h : Help # -w [warning threshold in seconds] # -c [critical threshold in seconds] # # REQUIREMENTS: Chrony, perl version 5.10.1+ # # AUTHOR: Dennis Ullrich (request@decstasy.de) # # BUGS ETC: https://github.com/Decstasy/check_chrony # # LICENSE: GPL v3 (GNU General Public License, Version 3) # see https://www.gnu.org/licenses/gpl-3.0.txt #=============================================================================== use 5.10.1; use strict; use warnings; use utf8; use Getopt::Std; # # Variables # my $chronyDaemonName = "chronyd"; my $leapOk = "Normal"; my $rc = 3; my $msg= ""; my $perfdata = ""; # # Subroutines # sub help { print "check_chrony [options] -w [warning threshold in seconds] -c [critical threshold in seconds] e.g.: check_chrony -w 0.6 -c 2\n"; exit(3); } # Script exit with Nagios / Icinga typical output sub _exit { my ( $return, $line ) = @_; my @state = ( "OK", "WARNING", "CRITICAL", "UNKNOWN" ); print "$state[$return]: $line\n"; exit( $return ); } # Checks if a process with $_[0] as name exists sub proc_exists { my $PID = `ps -C $_[0] -o pid=`; if ( ${^CHILD_ERROR_NATIVE} == 0 ){ return 1; } return 0; } # # Options # my %options=(); getopts( "hw:c:", \%options ); # Check input if ( keys %options == 0 || defined $options{h} ){ &help; } for my $key ( keys %options ){ if ( $options{$key} !~ /^[\d\.]+$/ ){ &_exit( 3, "Value of option -$key is not a valid number!" ); } } # # Check chrony process # &_exit( 2, "$chronyDaemonName is not running!" ) if not &proc_exists( $chronyDaemonName ); # # Get tracking data # my $chronyOutput = `chronyc tracking`; &_exit( 3, "Chronyc tracking command failed!" ) if ${^CHILD_ERROR_NATIVE} != 0; my ( $offset, $dir ) = $chronyOutput =~ /(?:System\stime)[^\d]+([\d\.]+)(?:.*?)(fast|slow)/; my ( $leap ) = $chronyOutput =~ /(?:Leap)[^\:]+(?::\s+)([\w\h]+)/; # # Check stuff # # Check offset if ( $offset >= $options{"c"} ){ $rc = 2; # Critical } elsif ( $offset >= $options{"w"} ){ $rc = 1; # Warning } else { $rc = 0; # Ok } # Prepare offset performace data $offset = $dir =~ "slow" ? "-$offset" : "+$offset"; $msg = sprintf( "Time offset of %+.9f seconds to reference.", $offset); $perfdata = sprintf( "|offset=%.9fs;%.9f;%.9f", ${offset}, $options{'w'}, $options{'c'}); # Check leap if( $leap !~ $leapOk ){ &_exit( 2, "Chrony leap status \"$leap\" is not equal to \"$leapOk\"! $msg $perfdata" ); } # # Return stuff # &_exit($rc, "$msg $perfdata");