sensu-plugins/sensu-plugins-process-checks

View on GitHub
bin/check-threads-count.rb

Summary

Maintainability
A
0 mins
Test Coverage
#! /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