bin/check-threads-count.rb
#! /usr/bin/env ruby
#
# check-threads-count.rb
#
# DESCRIPTION:
# Counts the number of threads running on the system and alerts if that number is greater than the warning or critical values.
# The default warning and critical count thresholds come from the ~32000 thread limit in older Linux kernels.
#
# OUTPUT:
# check
#
# PLATFORMS:
# Linux, Windows
#
# DEPENDENCIES:
# gem: sensu-plugin
# gem: sys-proctable
#
# USAGE:
# The check will return an UNKNOWN if the sys-proctable version is not new enough to support it.
#
# NOTES:
# sys-proctable > 0.9.5 is required for counting threads
#
# LICENSE:
# Copyright (c) 2015 Contegix LLC
# Richard Chatteron richard.chatterton@contegix.com
# Released under the same terms as Sensu (the MIT license); see LICENSE
# for details.
#
require 'sensu-plugin/check/cli'
require 'sys/proctable'
#
# Check Threads Count
#
class ThreadsCount < Sensu::Plugin::Check::CLI
option :warn,
description: 'Produce a warning if the total number of threads is greater than this value.',
short: '-w WARN',
default: 30_000,
proc: proc(&:to_i)
option :crit,
description: 'Produce a critical if the total number of threads is greater than this value.',
short: '-c CRIT',
default: 32_000,
proc: proc(&:to_i)
# Takes a value to be tested as an integer. If a new Integer instance cannot be created from it, return 1.
# See the comments on get_process_threads() for why 1 is returned.
def test_int(i)
Integer(i)
rescue TypeError
1
rescue ArgumentError
1
rescue StandardError
1
end
# Takes a process struct from Sys::ProcTable.ps() as an argument
# Attempts to use the Linux thread count field :nlwp first, then tries the Windows field :thread_count.
# Returns the number of processes in those fields.
# Otherwise, returns 1 as all processes are assumed to have at least one thread.
def get_process_threads(p)
if p.respond_to?(:nlwp)
test_int(p.nlwp)
elsif p.respond_to?(:thread_count)
test_int(p.thread_count)
else
1
end
end
def count_threads
ps_table = Sys::ProcTable.ps
ps_table.reduce(0) do |sum, p|
sum + get_process_threads(p)
end
end
# Main function
def run
threads = count_threads
critical "#{threads} threads running, over threshold #{config[:crit]}" if threads > config[:crit]
warning "#{threads} threads running, over threshold #{config[:warn]}" if threads > config[:warn]
ok "#{threads} threads running"
end
end