bin/check-nginx-status.rb
#! /usr/bin/env ruby
# frozen_string_literal: true
#
# check-nginx-status
#
# DESCRIPTION:
# Sensu Check that fetches Nginx Status
#
# OUTPUT:
# plain text
#
# PLATFORMS:
# Linux
#
# DEPENDENCIES:
# gem: sensu-plugin
#
# USAGE:
# You need to enable nginx status
# https://easyengine.io/tutorials/nginx/status-page/
# check-nginx-status.rb --help
#
# NOTES:
#
# LICENSE:
# Adapted from official metrics-nginx plugin (Pete Shima <me@peteshima.com>)
# Magic Online http://www.magic.fr @2016 - hanynowsky@gmail.com
# Released under the same terms as Sensu (the MIT license); see LICENSE for details.
# Last Modified October 2016
#
require 'net/https'
require 'uri'
require 'socket'
require 'sensu-plugin/check/cli'
#
# Nginx Status Check
#
class CheckNginxStatus < Sensu::Plugin::Check::CLI
option :url,
short: '-u URL',
long: '--url URL',
description: 'Full URL to nginx status page, example: https://yoursite.com/nginx_status This ignores ALL other options'
option :hostname,
short: '-h HOSTNAME',
long: '--host HOSTNAME', description: 'Nginx hostname', default: 'localhost'
option :port,
short: '-p PORT',
long: '--port PORT',
description: 'Nginx port',
default: '80'
option :activecon,
short: '-a ACTIVE_CONNECTION_THRESHOLD',
long: '--activecon ACTIVE_CONNECTION_THRESHOLD',
description: 'Active connections threshold',
default: 300
option :waitingreq,
short: '-w WAITING_REQUESTS_THRESHOLD',
long: '--waitingreq WAITING_REQUESTS_THRESHOLD',
description: 'Waiting requests threshold',
default: 30
option :path,
short: '-q STATUSPATH',
long: '--statspath STATUSPATH',
description: 'Path to your stub status module',
default: 'nginx_status'
option :hostheader,
long: '--hostheader HOSTHEADER',
description: 'Set the Host header to this string'
#
# Acquire Nginx Status
#
def statutor
found = false
attempts = 0
begin
until found || attempts >= 10
attempts += 1
if config[:url]
uri = URI.parse(config[:url])
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == 'https'
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = Net::HTTP::Get.new(uri.request_uri)
if config[:hostheader]
request['Host'] = config[:hostheader]
end
response = http.request(request)
if response.code == '200'
found = true
elsif !response.header['location'].nil?
config[:url] = response.header['location']
end
else
response = Net::HTTP.start(config[:hostname], config[:port]) do |connection|
request = Net::HTTP::Get.new("/#{config[:path]}")
request['Host'] = config[:hostheader] if config[:hostheader]
connection.request(request)
end
end
return response
end
rescue StandardError => e
unknown "Could not fetch Nginx status | #{e.message}"
end
end
#
# Main function
#
def run
code = statutor
#### Metrics
code.body.split(/\r?\n/).each do |line|
if line =~ /^Active connections:\s+(\d+)/
connections = line.match(/^Active connections:\s+(\d+)/).to_a
if connections[1].to_i > config[:activecon].to_i
warning "Active connections: #{connections[1]}"
end
end
if line =~ /^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/
queue = line.match(/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/).to_a
warning "Waiting requests: #{queue[3]}" if queue[3].to_i > config[:waitingreq].to_i
end
end
#####
ok 'Nginx is Alive and healthy' if code.code.to_i == 200
warning 'Nginx Status endpoint is mis-configured' if code.code.to_i == 301
critical 'Nginx is Down'
end
end