class Arborist::Monitor::SNMP::Disk
Disk
capacity checks.
Sets all configured mounts with their current usage percentage in an attribute named “mounts”.
Constants
- ACCESS_READONLY
- ACCESS_READWRITE
Access mode meanings
- ALERT_READONLY
Don't alert if a mount is readonly by default.
- STORAGE_NET_SNMP
OIDS required to pull disk information from net-snmp.
- STORAGE_WINDOWS
OIDS required to pull disk information from Windows.
- WARN_AT
The fallback warning capacity.
- WINDOWS_DEVICES
The OID that matches a local windows hard disk.
Public Class Methods
Return the properties used by this monitor.
# File lib/arborist/monitor/snmp/disk.rb, line 81 def self::node_properties used_properties = USED_PROPERTIES.dup used_properties << :mounts return used_properties end
Class run
creates a new instance and immediately runs it.
# File lib/arborist/monitor/snmp/disk.rb, line 90 def self::run( nodes ) return new.run( nodes ) end
Public Instance Methods
Perform the monitoring checks.
Arborist::Monitor::SNMP#run
# File lib/arborist/monitor/snmp/disk.rb, line 97 def run( nodes ) super do |host, snmp| self.gather_disks( host, snmp ) end end
Protected Instance Methods
Return a single regexp for the 'include' or 'exclude' section of resource node's config
, or nil if nonexistent.
# File lib/arborist/monitor/snmp/disk.rb, line 169 def format_mounts( config, section ) list = config[ section ] || return mounts = Array( list ).map{|m| Regexp.new(m) } return Regexp.union( mounts ) end
Collect mount point usage for host
from an existing (and open) snmp
connection.
# File lib/arborist/monitor/snmp/disk.rb, line 111 def gather_disks( host, snmp ) current_mounts = self.system =~ /windows\s+/i ? self.windows_disks( snmp ) : self.unix_disks( snmp ) config = self.identifiers[ host ].last['config'] || {} warn_at = config[ 'warn_at' ] || self.class.warn_at alert_readonly = config[ 'alert_readonly' ] || self.class.alert_readonly self.log.debug self.identifiers[ host ] includes = self.format_mounts( config, 'include' ) || self.class.include excludes = self.format_mounts( config, 'exclude' ) || self.class.exclude current_mounts.reject! do |path, data| path = path.to_s excludes.match( path ) || ( includes && ! includes.match( path ) ) end errors = [] warnings = [] current_mounts.each_pair do |path, data| warn = if warn_at.is_a?( Hash ) warn_at[ path ] || self.class.warn_at else warn_at end readonly = alert_readonly.is_a?( Hash ) ? alert_readonly[ path ] : alert_readonly self.log.debug "%s:%s -> %p, warn at %d" % [ host, path, data, warn ] if data[ :capacity ] >= warn.to_i if data[ :capacity ] >= 100 errors << "%s at %d%% capacity" % [ path, data[ :capacity ] ] else warnings << "%s at %d%% capacity" % [ path, data[ :capacity ] ] end end if readonly && data[ :accessmode ] == ACCESS_READONLY errors << "%s is mounted read-only." % [ path ] end end # Remove any past mounts that configuration exclusions should # now omit. mounts = self.identifiers[ host ].last[ 'mounts' ] || {} mounts.keys.each{|k| mounts[k] = nil } mounts.merge!( current_mounts ) self.results[ host ] = { mounts: mounts } self.results[ host ][ :error ] = errors.join(', ') unless errors.empty? self.results[ host ][ :warning ] = warnings.join(', ') unless warnings.empty? end
Fetch information for Unix/MacOS systems.
# File lib/arborist/monitor/snmp/disk.rb, line 206 def unix_disks( snmp ) paths = snmp.walk( oid: STORAGE_NET_SNMP[:path] ).each_with_object( [] ) do |(_, value), acc| acc << value end capacities = snmp.walk( oid: STORAGE_NET_SNMP[:percent] ).each_with_object( [] ) do |(_, value), acc| acc << value end accessmodes = snmp.walk( oid: STORAGE_NET_SNMP[:access] ).each_with_object( [] ) do |(_, value), acc| acc << value end pairs = paths.each_with_object( {} ).with_index do |(p, acc), idx| acc[p] = { capacity: capacities[idx], accessmode: accessmodes[idx] } end return pairs end
Fetch information for Windows systems.
# File lib/arborist/monitor/snmp/disk.rb, line 178 def windows_disks( snmp ) paths = snmp.walk( oid: STORAGE_WINDOWS[:path] ).each_with_object( [] ) do |(_, value), acc| acc << value end types = snmp.walk( oid: STORAGE_WINDOWS[:type] ).each_with_object( [] ) do |(_, value), acc| acc << WINDOWS_DEVICES.include?( value ) end totals = snmp.walk( oid: STORAGE_WINDOWS[:total] ).each_with_object( [] ) do |(_, value), acc| acc << value end used = snmp.walk( oid: STORAGE_WINDOWS[:used] ).each_with_object( [] ) do |(_, value), acc| acc << value end disks = {} paths.each_with_index do |path, idx| next if totals[ idx ].zero? next unless types[ idx ] disks[ path ] ||= {} disks[ path ][ :capacity ] = (( used[idx].to_f / totals[idx] ) * 100).round( 1 ) end return disks end