SNMP Library for EventMachine¶ ↑
Summary¶ ↑
This gem extends Ruby-SNMP to use the asynchronous EventMachine library for added performance and scalability. This allows code to scale monitoring applications to access a very high number of devices without the need for complex asynchronous I/O handling.
Features¶ ↑
The library currently supports:
-
SNMP v1 and v2
-
SNMP Get, GetNext, Set, and Walk requests. For SNMPv2 clients, GetBulk and WalkBulk
-
Ability to query/set/walk multiple OIDs in parallel.
-
For Ruby 1.9 and above, fiber support to streamline asychronous code
Future revisions of this library may support:
-
Ability to act as an SNMP agent, responding to external queries.
There are no plans to support SNMP v3 or the parsing of MIB files.
Options¶ ↑
You may set the following options:
SNMP4EM::Manager.new( :version => :SNMPv2c, :host => "127.0.0.1", :port => 161, :community => "public", # Shorthand for setting both :community_ro and :community_rw :community_ro => "public", :community_rw => "public", :fiber => false, :timeout => 1, :retries => 3 # Can also be specified as an array of individual timeouts # For instance, [0.5, 1, 2.5] would send three requests with increasing timeout values )
These options may also be passed to an individual query method, for instance:
snmp = SNMP4EM::Manager.new(...) snmp.get(OID, :retries => 2, :timeout => 1)
And when receiving traps:
SNMP4EM::NotificationManager.new( :host => "127.0.0.1", # Local interface on which to listen for traps. By default, localhost only! :port => 161 # Port on which to listen for traps. )
Backwards compatibility¶ ↑
Version 1.0.0 tweaks the return values of a few functions. Please test code thoroughly before upgrading to 1.0.0 in production!
Running tests¶ ↑
This library now includes a full suite of functional tests. They communicate with an SNMP daemon running on the localhost. The library comes with the necessary configuration, but it’s much easier to fire up the provided rake task (‘rake server`), running in a separate terminal window, before running `rspec`. This works fine on a Mac OS X machine using homebrew (`brew install net-snmp`).
Acknowledgements¶ ↑
-
The SNMP packet processing is handled by the Ruby-SNMP library, by David Halliday
-
EventMachine, by Francis Cianfrocca and Aman Gupta
-
All the helpful folks on the Freenode #eventmachine channel
Examples¶ ↑
A few definitions:
OID_SYSTEM = "1.3.6.1.2.1.1" OID_SYSNAME = "1.3.6.1.2.1.1.5.0" OID_SYSLOCATION = "1.3.6.1.2.1.1.6.0"
A simple SNMP-GET:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") request = snmp.get([OID_SYSNAME, OID_SYSLOCATION]) request.callback do |response| puts "System name = #{response[OID_SYSNAME]}" puts "System location = #{response[OID_SYSLOCATION]}" end request.errback do |error| puts "GET got error #{error}" end }
A simple SNMP-GETNEXT:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") request = snmp.getnext(OID_SYSNAME) request.callback do |response| r = response[OID_SYSNAME] puts "The next OID is #{r[0]}, the next value is #{r[1]}" end request.errback do |error| puts "GETNEXT got error #{error}" end }
A simple SNMP-SET:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") request = snmp.set({OID_SYSNAME => "My System Name", OID_SYSLOCATION => "My System Location"}) request.callback do |response| if (response[OID_SYSNAME] == true) puts "System name set successful" else puts "System name set unsuccessful: #{response[OID_SYSNAME]}" end if (response[OID_SYSLOCATION] == true) puts "System location set successful" else puts "System location set unsuccessful: #{response[OID_SYSLOCATION]}" end end request.errback do |error| puts "SET got error #{error}" end }
A simple SNMP-WALK:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") request = snmp.walk(OID_SYSTEM) request.callback do |response| response[OID_SYSTEM].each do |oid, value| puts "#{oid} = #{value}" end end request.errback do |error| puts "WALK got error #{error}" end }
A simple SNMP-BULKWALK:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") request = snmp.bulkwalk(OID_SYSTEM) request.callback do |response| response[OID_SYSTEM].each do |oid, value| puts "#{oid} = #{value}" end end request.errback do |error| puts "BULK-WALK got error #{error}" end }
A simple SNMP-GET-BULK:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") request = snmp.getbulk(OID_SYSTEM) request.callback do |response| response[OID_SYSTEM].each do |oid, value| puts "#{oid} = #{value}" end end request.errback do |error| puts "GET-BULK got error #{error}" end }
Handling traps:
EM.run { manager = SNMP4EM::NotificationManager.new manager.on_trap do |trap| if trap.is_a? SNMP::SNMPv1_Trap puts "Got a SNMPv1_Trap" elsif trap.is_a? SNMP::SNMPv2_Trap puts "Got a SNMPv2_Trap" end end }
Fiber Support¶ ↑
If your Ruby supports it, you can pass enable fibers, either per-manager or per-request. This unwinds much of the complexity in writing event-driven code. Instead of receiving an object on which to hang callbacks, the current fiber will be suspended until the response is available. If an error occurs, it will be returned as a SNMP::RequestTimeout. Unfortunately, there is no way to raise this error, you are responsible for manually checking whether the returned object is an error or not.
For example:
EM.run { snmp = SNMP4EM::Manager.new(:host => "192.168.1.1") f = Fiber.new do response = snmp.get([OID_SYSNAME, OID_SYSLOCATION]) if response.is_a? SNMP::RequestTimeout puts "Uh oh!" else puts "System name = #{response[OID_SYSNAME]}" puts "System location = #{response[OID_SYSLOCATION]}" end end }
Change Log¶ ↑
Version 1.1.5:
-
Fix memory leak (#10), many thanks to paddor
Version 1.1.5:
-
Fix an error when constructing a GetBulkRequest when using version >= 1.3.1 of the SNMP gem
Version 1.1.2:
-
Changed timeout error handling. We now raise a SNMP::RequestTimeout instead of a StandardError.
Version 1.1.0:
-
Fiber support
Version 1.0.2:
-
Ability to specify timeouts as an array of timeout values. Inspired by github.com/calmh/node-snmp-native.
Version 1.0.1:
-
Requests resulting in an error now return nil unless return_raw is enabled
Version 1.0.0:
-
Added SNMPv2 BULKWALK support
-
Added ability to receive SNMP traps / informs
-
Added functional tests (finally!)
-
Moved documentation to Yard
-
Lots of code cleanup
Version 0.2.1:
-
Code cleanups, speed boosts
Version 0.2.0:
-
Added support for SNMPv2, including GET-BULK operations
Version 0.1.0:
-
Initial deployment, ability to run get/getnext/set/walk requests in parallel
Credits¶ ↑
Author: Norman Elton normelton@gmail.com