Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Perl and SNMP (or how to create a custom SNMP agent.)

by PyrexKidd (Monk)
on May 24, 2011 at 17:16 UTC ( [id://906535]=perlquestion: print w/replies, xml ) Need Help??

PyrexKidd has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,


I beleive my question is more of an SNMPd question than a perl question, though I have been unable to find the answer on my own, or on more general linux forums; I am asking here in a desparate hope someone has done before what I am atempting to do now.

My goal: Create a custom SMTP monitor that returns the results of `exim -bpc` to my SNMP monitor. I would like to create an agent that responds to request to a cusom OID. That being said, another solution has been proposed to set a cron job to dump the return value of `exim -bpc` to a log file then have an snmp agent watch the log file. The second solution though less preferred seems like it would be 'easier'... what do you think?

here's what I've got so far:

#!/usr/bin/perl # place this in a .pl file, and then in your snmpd.conf file put: # perl do '/path/to/file.pl'; use NetSNMP::agent; my $agent; sub myhandler { my ($handler, $registration_info, $request_info, $requests) = @_; my $request; $request->setValue(ASN_OCTET_STRING, "hello\n"); } $agent = new NetSNMP::agent( 'Name' => 'my_agent_name', ); $agent->register( "my_agent_name", ".1.3.6.1.4.1.8072.9999.9999.9999", \&myhandler ); $agent->main_loop();

This is essentially the example in the documentation on CPAN.
When I attempt to run this from the command line I receive the error:

Warning: no access control information configured. It's unlikely this agent can serve any useful purpose in this state. Run "snmpconf -g basic_setup" to help you configure the my_agent_name.conf file for this agent.

this is highly confusing as running this command does not provide the ability to configure a agent.conf file, nor am I able to find any documentation on agent.conf files. Perhaps I am not googling for this correctly (SNMP agent.conf file, directives, configuration), I would greatly appreciate any hints on where to find this documentation.

additionally when run from a perl do /foo/test_agent.pl directive it causes snmpd to hang (become unresponsive). (either when started via init/services or from the commandline via snmpd -f)

Then I've tried registering the agent itself via my_agent_name .1.3.6.1.4.1.8072.9999.9999.9999 /root/snmp/test_agent.pl which appears to have no affect on functionality. (this directive I pulled out of the SNMP::Server::Logtail docs. (realizing this is a hail mary, I figured it couldn't hurt my dev box to wave a dead chicken...)

I really feel like I am just missing a simple piece of this puzzle... no matter how simple it seems to be the obsticle that is blocking my progress... If any one can even poing me in the general direction I'm sure it would help me get the wheels moving again.

Replies are listed 'Best First'.
Re: Perl and SNMP (or how to create a custom SNMP agent.)
by PyrexKidd (Monk) on May 24, 2011 at 21:24 UTC

    UPDATE

    Ok, I borrowed from the tutorial and came up with the following code

    #!/usr/bin/perl # # for this to work place this file in: /usr/share/snmp/exim_queue_mo +nitor.pl # insert the following line in /usr/share/snmp/snmpd.conf # perl do "/usr/share/snmp/exim_queue_monitor.pl # use strict; use warnings; # Global Vars: our $agent; # Private vars my $regat = '.1.3.6.1.4.1.8072.9999.9999'; my $running; # set to 1 to get extra debugging information my $debugging = 1; # if we're not embedded, this will get auto-set below to 1 my $subagent = 0; BEGIN { print STDERR "starting exim_queue_monitor.pl\n"; } use NetSNMP::OID (':all'); use NetSNMP::agent (':all'); use NetSNMP::ASN (':all'); print STDERR "exim_queue_monitor.pl loaded ok\n"; # where we are going to hook onto my $regoid = new NetSNMP::OID($regat); print STDERR "registering at ",$regoid,"\n" if $debugging; # we register ourselves with the master agent we're embedded in. The # global $agent variable is how we do this: $agent->register('exim_queue_monitor',$regoid, \&exim_queue_monitor); # processes system command and updates request obj. sub process_mail_queue{ my $request = shift; my $queue_len = `exim -bpc`; chomp $queue_len; print STDERR " -> queue length = $queue_len\n" if $debugging; $request->setValue(ASN_INTEGER, $queue_len); } ###################################################################### # define a handler for incoming SNMP requests for our part of the OID +tree. # This subroutine will get called for all # requests within the OID space under the registration OID made above. # however, in its current form, this will -only- return # for requests to our full OID sub exim_queue_monitor { my ($handler, $registration_info, $request_info, $requests) = @_; my $request; #debug messages do { print STDERR "refs: ",join(", ", ref($handler), ref($registrat +ion_info), ref($request_info), ref($requests)),"\n"; print STDERR "processing a request of type " . $request_info-> +getMode() . "\n"; } if $debugging; for($request = $requests; $request; $request = $request->next()) { my $oid = $request->getOID(); print STDERR " processing request of $oid\n" if $debugging; if ($request_info->getMode() == MODE_GET) { # if the requested oid is equals to ours, then return the +data if ($oid == new NetSNMP::OID($regat . ".1.2.1")) { process_mail_queue $request; } } elsif ($request_info->getMode() == MODE_GETNEXT) { # if the requested oid is equals to ours, then return the +data if ($oid == new NetSNMP::OID($regat . ".1.2.1")) { process_mail_queue $request; } } }# end for loop print STDERR " finished processing\n" if $debugging; }

    Great, works locally... But not remotely... Any thoughts?
    Thanks in advance

Re: Perl and SNMP (or how to create a custom SNMP agent.)
by pklausner (Scribe) on May 25, 2011 at 10:20 UTC
    The S in SNMP is a joke. But for your problem, the Net-SNMP agent offers an easy way out. It supports remote query of custom parameters aka scripts using the pass-through extensions of its UCD MIB under .1.3.6.1.4.1.2021... Assuming exim -bpc is no CPU hog, you are set with a simple wrapper returning OID, type (string/integer/counter) and the output value. If it is expensive to run, maybe a simple caching layer between invocations would do it.

    Update: Now I see your example and properly recollect the snmpd.conf options. You can write:

    exec   exim_output_ucd /usr/bin/exim -bpc
    extend exim_output_ns  /usr/bin/exim -bpc
    pass   .1.3.6.1.4.1.55555.1 /usr/local/bin/exim_wrapper
    
    To pull the results of old UCD exec, walk .1.3.6.1.4.1.2021.8 For the newer Net-SNMP extend, walk .1.3.6.1.4.1.8072.1.3.2 Both return string output, which may not work well with a snmp poller for graphing. To create a proper gauge at .1.3.6.1.4.1.55555.1, make a /usr/local/bin/exim_wrapper like:
    #!/bin/sh
    
    case "$1" in
    -g)     echo ".1.3.6.1.4.1.55555.1"  # you are enterprise 55555
            echo "gauge"
            exec exim -bps
            ;;
    esac
    
    _______________________________

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://906535]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2024-04-24 23:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found