bin/check-ntp.rb
#! /usr/bin/env ruby
# frozen_string_literal: true
#
# check-ntp
#
# DESCRIPTION:
#
# OUTPUT:
# plain text
#
# PLATFORMS:
# Linux
#
# DEPENDENCIES:
# gem: sensu-plugin
#
# USAGE:
#
# NOTES:
# warning and critical values are offsets in milliseconds.
#
# LICENSE:
# Copyright 2012 Sonian, Inc <chefs@sonian.net>
# Released under the same terms as Sensu (the MIT license); see LICENSE
# for details.
#
# Stratum Levels
# 1: Primary reference (e.g., calibrated atomic clock, radio clock, etc...)
# 2-15: Secondary reference (via NTP, calculated as the stratum of your system peer plus one)
# 16: Unsynchronized
# 17-255: Reserved
#
# Source Field Status Codes
# http://doc.ntp.org/current-stable/decode.html
require 'sensu-plugin/check/cli'
class CheckNTP < Sensu::Plugin::Check::CLI
option :warn,
short: '-w WARN',
proc: proc(&:to_f),
default: 10
option :crit,
short: '-c CRIT',
proc: proc(&:to_f),
default: 100
option :stratum,
short: '-s STRATUM',
description: 'check that stratum meets or exceeds desired value',
proc: proc(&:to_i),
default: 15
option :unsynced_status,
short: '-u CODE',
description: 'If ntp_status is unsynced (that is, not yet connected to or disconnected from ntp), what should the response be.',
proc: proc(&:downcase),
default: 'unknown'
def run
begin
output = `ntpq -c "rv 0 stratum,offset" 127.0.0.1`.split("\n").find { |line| line.start_with?('stratum') }
stratum = output.split(',')[0].split('=')[1].strip.to_i
offset = output.split(',')[1].split('=')[1].strip.to_f
source_field_status = config[:unsynced_status] == 'ok' ? 6 : /status=[0-9a-f]([0-9])[0-9a-f]{2}/.match(`ntpq -c "rv 0" 127.0.0.1`)[1].to_i
rescue StandardError
unknown 'NTP command Failed'
end
if source_field_status.zero?
case config[:unsynced_status]
when 'warn'
warning 'NTP state unsynced'
when 'crit'
critical 'NTP state unsynced'
when 'unknown'
unknown 'NTP state unsynced'
end
end
if stratum > 15
critical 'NTP not synced'
elsif stratum > config[:stratum]
critical "NTP stratum (#{stratum}) above limit (#{config[:stratum]})"
end
message = "NTP offset by #{offset.abs}ms"
critical message if offset >= config[:crit] || offset <= -config[:crit]
warning message if offset >= config[:warn] || offset <= -config[:warn]
ok message
end
end