Created
July 30, 2015 10:26
-
-
Save hanynowsky/ba58b80401a3f171b05c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'snmp' | |
#include SNMP | |
require 'logger' | |
require 'sensu-plugin/check/cli' | |
# Author: Hanynowsky | |
# Usage: | |
# - : Performs some SNMP Checks | |
# Example: check-cisco-snmp -k uptime -h sw998.myinfra.net -C my_snmp_com | |
# Requirements: libsmi | |
# WARNING: Tested only in CentOS 6.6 | |
# IMPORTANT: in order to smidump to work, copy special mibs to /usr/share/mibs/site/ | |
class CheckSNMP < Sensu::Plugin::Check::CLI | |
option :host, | |
short: '-h host', | |
default: '127.0.0.1' | |
option :community, | |
short: '-C snmp community', | |
default: 'public' | |
option :snmp_version, | |
short: '-v version', | |
description: 'SNMP version to use (SNMPv1, SNMPv2c (default))', | |
default: 'SNMPv2c' | |
option :comparison, | |
short: '-o comparison operator', | |
description: 'Operator used to compare data with warning/critial values. Can be set to "le" (<=), "ge" (>=).', | |
default: 'ge' | |
option :timeout, | |
short: '-t timeout (seconds)', | |
default: '2' | |
option :check, | |
short: '-k check', | |
description: 'Check to perform: cpu | memory | power | uptime | traffic | interfaces', | |
default: 'interfaces' | |
option :debug, | |
short: '-d debug SNMP output', | |
boolean: false | |
begin | |
def trapper() | |
# TODO: Not yet Finished | |
log = Logger.new(STDOUT) | |
m = SNMP::TrapListener.new do |manager| | |
manager.on_trap_default do |trap| | |
log.info trap.inspect | |
end | |
end | |
m.join | |
end | |
def check_power_supply(is_power_supply_down, is_power_supply_warning) | |
if is_power_supply_down | |
critical "Power Supply Down" | |
elsif is_power_supply_warning | |
warning "Power Supply is in warning mode" | |
else | |
ok "Power Supply is OK" | |
end | |
end | |
def check_cpu_usage(cpu_usage) | |
case cpu_usage | |
when 85..94 | |
warning "Total CPU Usage: #{cpu_usage}%" | |
when 95..100 | |
critical "Total CPU Usage: #{cpu_usage}%" | |
else | |
ok "CPU USAGE is OK: #{cpu_usage}" | |
end | |
end | |
def check_free_memory(memfree, memused) | |
free_memory = (memfree * 100) / (memused + memfree) | |
case free_memory | |
when 11..15 | |
warning "Free Memory: #{free_memory}%" | |
when 0..10 | |
critical "Free Memory #{free_memory}%" | |
else | |
ok "Free Memory #{free_memory}%" | |
end | |
end | |
def check_is_ifs_down(if_count, if_oper) | |
# Interface down: 2 and up = 1. If all interfaces are down, then switch is down | |
if if_count * 2 == if_oper | |
is_device_down = true | |
critical "All interfaces down #{if_oper}/#{if_count}" | |
else | |
ok "Interfaces up-ratio #{if_oper}/#{if_count}" | |
end | |
end | |
def check_total_traffic(in_sum, out_sum) | |
total_traffic = in_sum + out_sum | |
if total_traffic < 1 | |
critical "Total Traffic is #{total_traffic}" | |
else | |
ok "Total Traffic is #{total_traffic}" | |
end | |
end | |
def check_uptime(uptime) | |
if uptime < 1 | |
critical "Uptime #{uptime}" | |
else | |
ok "Uptime #{uptime}" | |
end | |
end | |
def run() | |
log = Logger.new(STDOUT) | |
mibpath = "/usr/share/snmp/mibs" | |
if !File.directory?("#{mibpath}") | |
log.error "Aborting: #{mibpath} does not exist" | |
exit | |
end | |
mibs = Array.new | |
mib_modules = ["SNMPv2-SMI", "SNMPv2-MIB", "IANAifType-MIB", "IF-MIB", "CISCO-PROCESS-MIB", "CISCO-QOS-PIB-MIB", "CISCO-SMI" ,"CISCO-TC", "CISCO-MEMORY-POOL-MIB", "CISCO-ENVMON-MIB"] | |
#mibs.push("SNMPv2-TC") # This would likely fail but not fatal. Included in RFC | |
#mibs.push("SNMPv2-CONF") # This would likely fail but not fatal. RFC | |
mib_modules.each do |e| | |
mibs.push(e) | |
end | |
SNMP::MIB.list_imported(regex=/.*/).each do |mib| | |
mibs.each do |mymib| | |
if "#{mib}".eql?("#{mymib}") | |
if config[:debug] | |
log.info "Already loaded : #{mymib}" | |
end | |
mibs.delete("#{mymib}") | |
end | |
end | |
end | |
mibs.each do |element| | |
if !element.nil? | |
if config[:debug] | |
log.info "Importing #{element}" | |
end | |
begin | |
SNMP::MIB.import_module("#{mibpath}/#{element}.txt") | |
rescue | |
SNMP::MIB.import_module("#{mibpath}/#{element}") | |
end | |
end | |
end | |
def is_numeric?(obj) | |
obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true | |
end | |
is_device_down = false | |
in_sum = 0 | |
out_sum = 0 | |
if_count = 0 | |
if_oper = 0 | |
uptime = -1 | |
memused = 0 | |
memfree = 0 | |
cpu_usage = 0 | |
ciscoMemoryPoolUsed = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.48.1.1.1.5") | |
ciscoMemoryPoolFree = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.48.1.1.1.6") | |
sysUptimeInstance = SNMP::ObjectId.new("1.3.6.1.2.1.1.3.0") | |
cpmCPUTotal5minRev = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.109.1.1.1.1.8") | |
ciscoEnvMonSupplyState = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.13.1.5.1.3") | |
host = "#{config[:host]}" | |
community = "#{config[:community]}" | |
version = config[:snmp_version] | |
timeout = config[:timeout].to_i | |
is_power_supply_down = false | |
is_power_supply_warning = false | |
SNMP::Manager.open(:MibModules => mib_modules, :host => host, :community => community, :version => version.to_sym, :timeout => timeout) do |manager| | |
manager.walk(["ifIndex", "ifDescr","ifHCInOctets", "ifHCOutOctets", "ifOperStatus"]) do |index, descr, inoctets, outoctets, ifoperstatus| | |
if is_numeric? "#{inoctets.value}" or inoctets.value.kind_of? Integer | |
if config[:debug] | |
log.info "#{index.value} #{descr.value} #{inoctets.value} #{outoctets.value} #{ifoperstatus.value}" | |
end | |
in_sum = in_sum + inoctets.value.to_i | |
out_sum = out_sum + outoctets.value.to_i | |
if_count = if_count + 1 | |
if_oper = if_oper + "#{ifoperstatus.value}".to_i | |
end | |
end | |
response = manager.get([sysUptimeInstance]) | |
response.each_varbind do |vb| | |
uptime = vb.value.to_i | |
end | |
manager.walk(ciscoMemoryPoolUsed) do |vb| | |
memused += vb.value | |
end | |
manager.walk(ciscoMemoryPoolFree) do |vb| | |
memfree += vb.value | |
end | |
manager.walk(cpmCPUTotal5minRev) do |vb| | |
cpu_usage += vb.value | |
end | |
manager.walk(ciscoEnvMonSupplyState) do |vb| | |
if vb == 3 or vb == 4 | |
is_power_supply_down = true | |
break | |
end | |
if vb == 2 | |
is_power_supply_warning = true | |
break | |
end | |
end | |
end | |
case "#{config[:check]}" | |
when "uptime" | |
check_uptime(uptime) | |
when "power" | |
check_power_supply(is_power_supply_down, is_power_supply_warning) | |
when "interfaces" | |
check_is_ifs_down(if_count, if_oper) | |
when "cpu" | |
check_cpu_usage(cpu_usage) | |
when "memory" | |
check_free_memory(memfree, memused) | |
when "traffic" | |
check_total_traffic(in_sum, out_sum) | |
else | |
check_is_ifs_down(if_count, if_oper) | |
end | |
rescue SNMP::RequestTimeout | |
warning "TIMEOUT ERROR: not responding" | |
rescue SocketError | |
warning "Unknown Host #{config[:host]}" | |
rescue SNMP::MIB::ModuleNotLoadedError | |
warning "Module Import error" | |
rescue => e | |
warning "Unknown error Occured #{e.inspect}" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment