Re: snmptrapd with attached perl script eats all memory

"michael kapelko" <[email protected]>
Newsgroups gmane.network.net-snmp.user
Message-ID <[email protected]>
I use net-snmp-5.4.1 on CentOS release 4.4 (Final)

# uname -a
Linux zond2 2.6.9-42.ELsmp #1 SMP Tue Aug 15 10:35:26 BST 2006 x86_64
x86_64 x86_64 GNU/Linux


And my perl script is:

#!/usr/bin/perl

# This module must be registered in the `snmptrapd.conf' this way:
#   perl do "/path/to/catchTraps.pl"
# To make `snmptrapd' accept traps, you must add the following:
#   authCommunity log,execute,net monitor
# to the `snmptrapd.conf'

use strict;
use warnings;
# Autoflush
use FileHandle;

# =====================================
# CONFIGURATION
# =====================================

# Path to log directory where trap files go WITH ENDING SLASH!!!
(/usr/, not /usr)
my $logDir = "/root/traps/";

# =====================================
# MAIN
# =====================================

# Extension of trap files
my $extension = '.traplog';
# Must be set to zero when first run
my $curLogFile = 0;
# OIDs of traps we catch
my $oidMAC = '.1.3.6.1.4.1.43.0.85';
my $oidLinkUp = '.1.3.6.1.6.3.1.1.5.4';
my $oidLinkDown = '.1.3.6.1.6.3.1.1.5.3';
# OIDs inside PDU we get
my $oidMACValuePart = '.1.3.6.1.4.1.43.10.22.2.1.4.1.';
my $oidPortPart = '.1.3.6.1.2.1.2.2.1.1.';
my $oidAdmStatPart = '.1.3.6.1.2.1.2.2.1.7.';
my $oidOprStatPart = '.1.3.6.1.2.1.2.2.1.8.';
# Register to snmptrapd
NetSNMP::TrapReceiver::register("all", \&customReceiver) ||
  warn "failed to register custom perl trap handler\n";
print STDERR "Loaded custom perl snmptrapd handler\n";

sub customReceiver {
    my @pdu = @{$_[1]};
    my($typeName, $mac, $port, $macState, $ip, $admStat, $oprStat);
    # Get info from PDU
    foreach my $line (@pdu) {
        my $oid = $line->[0];
        my $value = $line->[1];
        if($value =~ /^OID: $oidMAC/) {
            $typeName = "mac";
        }
        elsif($value =~ /^OID: $oidLinkUp/ or $value =~ /^OID: $oidLinkDown/) {
            $typeName = "linkupdown";
        }
        elsif($oid =~ /$oidMACValuePart(\d+)\.(\d+\.\d+\.\d+\.\d+.\d+\.\d+)/) {
            $port = $1;
            $mac = $2;
            $macState = $value;
            $macState =~ s/^INTEGER: (\d+)/$1/;
        }
        elsif($value =~ /^IpAddress: (\d+\.\d+\.\d+\.\d+)/) {
            $ip = $1;
        }
        elsif($oid =~ /$oidPortPart(\d+)/) {
            # 3Com switch port number begins with 101, not 1, so we subtract 100
            $port = $1 - 100;
        }
        elsif($oid =~ /$oidAdmStatPart/) {
            $admStat = $value;
            $admStat =~ s/^INTEGER: (\d+)/$1/;
        }
        elsif($oid =~ /$oidOprStatPart/) {
            $oprStat = $value;
            $oprStat =~ s/^INTEGER: (\d+)/$1/;
        }
    }
    #print "type: $typeName ip: $ip port: $port mac: $mac macState:
$macState admStat: $admStat oprStat: $oprStat\n";
    if(($typeName eq "mac") and ($macState == 1) and $ip and $port and $mac) {
        my $output = join("\t", $ip, $port, $typeName, $mac);
        logRotateToFile($curLogFile, $logDir, $extension, $output);
    }
    elsif(($typeName eq "linkupdown") and $ip and $port and $admStat
and $oprStat) {
        my $output = join("\t", $ip, $port, $typeName, $admStat, $oprStat);
        logRotateToFile($curLogFile, $logDir, $extension, $output);
    }
}

# Log-rotate
# \param curLogFile
# \param logDir
# \param extension
# \param Message
sub logRotateToFile {
    # We MUST use $_[0] instead of new variable to change global
curLogFile value
    my $logDir = $_[1];
    my $extension = $_[2];
    my $message = $_[3];
    my $curLocalTime = strftime("%Y-%m-%d %H:%M:%S", localtime());
    # File name = minutes passed since 1970-01-01 00:00
    # We multiply by 60 to get UNIX time in seconds again, but within
minute ranges
    my $fileName = int(time() / 60) * 60;
    # Rotate log file if necessary
    if($fileName ne $_[0]) {
        my $rootPt = $logDir . $_[0] . $extension;
        # For the first run we do not rotate files
        if($_[0] ne "0") {
            # Close file
            close(LOGFILE);
            # Rename it
            rename("${rootPt}.tmp", $rootPt);
        }
        # Now open new file and make it current
        $_[0] = $fileName;
        $rootPt = $logDir . $_[0] . $extension;
        open(LOGFILE, ">>${rootPt}.tmp") or die "Could not open file: $!";
        # Flush to file when printing, skip buffering
        LOGFILE->autoflush(1);
    }
    print LOGFILE "$curLocalTime\t$message\n";
}

I can only suspect my rotation logger to cause memory leak, but I
can't see anything wrong with that.
Thanks.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.