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

Hi perl monks, I wrote a script to perform the following task. It grabs the ACKs lines from the dhcp log file using tail. It takes the ip of the recently connected device and performs a snmp query. Then it will append this info to a plain text record. So far it is working, here is the code:
#!/usr/bin/perl -w use strict; use File::Tail; use Cwd qw(); my $path = Cwd::cwd(); my $community = 'public'; my $snmp_bsid = '.1.3.6.1.4.1.2700.1.1.11.0'; my $bsid; my $file = File::Tail->new( name =>'/var/log/messages', interval => 1, maxinterval => 1, resetafter=> 5, ); while (defined(my $line=$file->read)) { print $line,"\n"; if ($line =~ /^(.*) dns02cor dhcpd: DHCPACK on ([0-9\. +]+) to ([[:xdigit:]:]+).* ([0-9\.]+)/) { write_register($1,$2,$3); } } sub write_register { my ($date,$client_ip,$client_imsi) = @_; $output=qx(snmpget -v2c -t1 -c $community $client_ip $snmp_bsid 2> +&1); my @result=split(/:/,$output); if ($result[3]){ $bsid=$result[3]; $bsid=~s/ //g; $bsid=~s/\n//g; } system 'echo "'.$date.','.$client_ip.','.$client_imsi.','.$bsi +d.'," >>'.$path.'/register_list.txt'; } 1;
The weird thing is when I list the output register: Take a look: Apr 12 20:56:54,186.183.101.72,77:10:00:02:06:85,77777851CFC7106,
Apr 12 20:57:06,186.183.104.175,77:10:00:03:38:56,,
Apr 12 20:57:08,186.183.106.13,77:10:00:01:92:00,77777851CFC8901,
Apr 12 20:57:11,186.183.101.196,77:10:00:01:99:35,,
Apr 12 20:57:11,186.183.105.204,77:10:00:01:93:30,,77777851CFC9A02,

As you can see there are some empty bsid fields,but if I manually execute the snmpget query from the command line to those ips, I can bring the value without any problem. I would like to know if you have some suggestion for me in order to improve my scrip. I also think that due to the ACKs rate (4 or 5 per secs)I should consider implementing some fork technique ... well. I hope to hear your opinions, Regards, Leandro.

Replies are listed 'Best First'.
Re: snmpget is missing some values
by NetWallah (Canon) on Apr 13, 2016 at 04:53 UTC
    I do not think 4 to 5 SNMP queries per second would cause any problems.

    I think you need to focus on handling error conditions. Specifically, since you are collecting the STDERR as well as STDOUT from the SNMPGET command, you should print that info out any time you fail to get the BSID. That way, you could track the pattern of error messages, or mis-parsing you may be doing.

    A couple of other minor nits -:
    * Do you really need to print each line of /var/log/messages ?
    * You are using "System echo" to do printing. Perl is perfectly capable of appending to a file.
    * Consider using a database (like SQLite) to store the information you collect.

            This is not an optical illusion, it just looks like one.

      Thanks for your feedback; so:
      1_ forget the print line ... it was suposed to be commented.
      2_ I thought that doing "echo" sould be faster or have better performance ... isn't it ?
      3_ I considered using a db but ... why will be better ? it would contain only a single table on it? would you explain ? Thanks!!!
        Re: "echo" vs. local print: "echo" is invoking an external command (New process), opening a file, and appending to it.
        Doing that in perl would avoid the "process creation", and command parsing overhead (Probably nanoseconds, so no big deal). But, being a perl bigot, I'd prefer seeing it in perl.
        open my $log, ">>", "$path/register_list.txt" or die "Cannot append:$! +"; print $log join( ",",$date,$client_ip,$client_imsi,$bsid),"\n"; close $log;
        Re: Using a Database:
        You could, potentially , have a BSID table, annd a CLIENT table, in addition to the log line,to track items. Dates would be better organized, and searching and filtering is easy to do.

        I have a simple cgi application that presents the contents of a Sqlite DB, to a web page, enabling queries. This is why I would prefer a database.

                This is not an optical illusion, it just looks like one.