Perl/Net::SNMP:脚本太慢,需要优化
Perl/Net::SNMP:脚本太慢,需要优化,perl,optimization,snmp,Perl,Optimization,Snmp,我想优化我的perl脚本,因为它显示有关网络的信息有点慢。 我不知道有什么可以改变或改进以提高脚本执行。 我操纵了几个散列,以得到:macadd,index,等等。。。我觉得有点重,但别无选择。 此外,我做了很多SNMP请求,错误处理可能不是很好。 我复制/粘贴脚本及其模块。 提前感谢您阅读我的代码 它接受args: 接口名称(例如FastEthernet0/9或FastEthernet0/1…) 主机名:交换机的ip地址 社区(通常=公共) 希望这是可以理解的 #!/usr/bin/perl
我想优化我的perl脚本,因为它显示有关网络的信息有点慢。
我不知道有什么可以改变或改进以提高脚本执行。
我操纵了几个散列,以得到:macadd,index,等等。。。我觉得有点重,但别无选择。
此外,我做了很多SNMP请求,错误处理可能不是很好。
我复制/粘贴脚本及其模块。
提前感谢您阅读我的代码 它接受args:
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use SnmpUtil;
use AdresseMac;
use Net::SNMP;
use Net::SNMP::Interfaces;
my $ifname;
my $hostname;
my $community;
my $version = 1;
GetOptions( "ifname=s" => \$ifname,
"host=s" => \$hostname,
"community=s" => \$community,
"protocol:s" => \$version);
my $interfaces = Net::SNMP::Interfaces->new(Hostname => $hostname, Community => $community);
my $inter = $interfaces->interface($ifname);
#Get interface $ifname
my $ifindex = $inter->index();
#Vitesse
my $vitesse = $inter->ifHighSpeed();
#Alias
my $ifalias = $inter->ifAlias();
#Seek for VLANs
my $vlan_trouve;
#Listing all VLANS
my $vmVlan = "1.3.6.1.4.1.9.9.68.1.2.2.1.2"; #OID of vlan table
my $vlans = SnmpUtil->new($hostname, $community);
my %vl = $vlans->requeteTable($vmVlan);
$vlans->deconnexion();
#Get the good VLAN corresponding to index interface
$vlan_trouve = $vl{$ifindex};
#Listing : port VLAN <-> @mac
my $dot1dTpFdbAddress = "1.3.6.1.2.1.17.4.3.1.1";
my $dot = SnmpUtil->new($hostname, $community."@".$vlan_trouve);
my %dot1address = $dot->requeteTable($dot1dTpFdbAddress);
#Listing : numPortBridge <-> port VLAN
my $dot1dTpFdbPort = "1.3.6.1.2.1.17.4.3.1.2";
my %portdot = reverse($dot->requeteTable($dot1dTpFdbPort));
#Listing : num Port bridge <-> ID port switch
my $dot1dBasePortIfIndex = "1.3.6.1.2.1.17.1.4.1.2";
my %dotindex = reverse($dot->requeteTable($dot1dBasePortIfIndex));
#Duplex (auto, half or full)
my $oid_cisco_duplex = "1.3.6.1.2.1.10.7.2.1.19.".$ifindex;
my $duplex = $dot->requete($oid_cisco_duplex);
if ($duplex==1) {
$duplex= "Auto";
}
elsif ($duplex==2) {
$duplex = "Half";
}
elsif ($duplex==3) {
$duplex= "Full";
}
#Close connection
$dot->deconnexion();
#Go back up, to find mac add
my $numportbridge = $dotindex{$ifindex};
if (!defined($numportbridge)) {
print "Erreur : $ifindex not found in list : num Port bridge <-> ID port switch\n";
exit 2;
}
my $portVlan = $portdot{$numportbridge};
if (!defined($portVlan)) {
print "Erreur : $numportbridge not found in list : numPortBridge <-> ports du VLAN\n";
exit 3;
}
my $add = uc($dot1address{$portVlan});
if (!defined($add)) {
print "Erreur : $portVlan not found in list : ports du VLAN <-> \@mac\n";
exit 4;
}
$add =~ s/^0X//g;
printf "<b>Port : $ifname</b><br/>Index $ifindex on VLAN : $vlan_trouve<br/>\@mac : $add<br/>Speed=$vitesse Mbps Alias=$ifalias<br/>Duplex: $duplex\n";
AdresseMac.pm模块是无用的,它只是将dec转换为十六进制,反之亦然
谢谢你的帮助,对发现优化的人的巨大奖励;)
PS:忘了说,我在cisco switch 2960上工作。您可能不喜欢这个答案,但NetSNMP支持使用C绑定编写的perl模块(称为SNMP)而不是在Net::SNMP中完成的全套perl模块实现的原因之一是C绑定速度明显更快。Giovanni Marzot编写了NetSNMP C-binding绑定的初始实现,他测量C/perl绑定实现的速度比全perl版本快10倍。如果您开始进入经过身份验证/加密的SNMPv3,那么它会变得更快。然而,我不知道这是否是你问题的根源。只是一个数据点。perl分析器会真正让您知道 需要考虑的另一点是:如果要查询大量主机,请考虑构建代码,以便可以使用异步请求和使用SNMPv2c的GetBulk请求一次发送多个查询。这两种优化也将大大提高速度 更新了每个请求的链接:
- Net SNMP:和下载:
- NetSNMP工具包附带了它的perl模块。使用--with perl模块配置网络SNMP
- Net SNMP的perl常见问题解答:
- 稍微过时的手册页:
请注意,Net SNMP有一个您可能感兴趣的gettable()函数,它可以进行大量优化。您可能不喜欢这个答案,但这是Net SNMP支持perl模块(称为SNMP)的原因之一使用C绑定而不是在Net::SNMP中完成的all-in-perl模块实现编写的C绑定速度要快得多。Giovanni Marzot编写了NetSNMP C-binding绑定的初始实现,他测量C/perl绑定实现的速度比全perl版本快10倍。如果您开始进入经过身份验证/加密的SNMPv3,那么它会变得更快。然而,我不知道这是否是你问题的根源。只是一个数据点。perl分析器会真正让您知道 需要考虑的另一点是:如果要查询大量主机,请考虑构建代码,以便可以使用异步请求和使用SNMPv2c的GetBulk请求一次发送多个查询。这两种优化也将大大提高速度 更新了每个请求的链接:
- Net SNMP:和下载:
- NetSNMP工具包附带了它的perl模块。使用--with perl模块配置网络SNMP
- Net SNMP的perl常见问题解答:
- 稍微过时的手册页:
请注意,Net SNMP有一个您可能感兴趣的gettable()函数,它可以进行大量优化。好的,谢谢您的帖子,我只使用SNMP v1,他们不想使用较新版本的SNMP。您是否有一些链接可用于在Perl中使用更快的SNMP库?好的,谢谢您的帖子,我只使用SNMP v1,他们不想使用更新版本的SNMP。您是否有一些链接可以与Perl一起使用更快的SNMP库?
#!/usr/bin/perl
use strict;
use warnings;
use Net::SNMP;
package SnmpUtil;
our ($session, $error);
sub new {
my ($classe, $hostname, $community) = @_;
my $this = {
"hostname" => $hostname,
"community" => $community
};
bless($this, $classe);
$this->{connexion} = $this->connexion;
return $this;
}
sub connexion {
my ($this) = @_;
($session, $error) = Net::SNMP->session(
-hostname => $this->{hostname},
-community => $this->{community},
-version => "1",
-timeout => 3,
);
request_error_connexion() if (!defined($session));
}
sub request_error_connexion {
my ($this) = @_;
print "Erreur : can't connect to host\n";
print "Erreur : $error\n";
if ($error =~ /The argument "-community" is unknown/)
{
# protocol SNMP version 3 not working
exit 3; # code ret final = 3*256 = 768
}
else
{
exit 1; # code retour final = 1*256 = 256
}
}
sub request_error {
my ($this) = @_;
print "Error : no answer from host\n";
printf "Erreur : %s\n",$session->error;
if ($session->error =~ /No response from remote host/)
{
#host ok, bad community or host refuse connection
$session->close;
exit 2; # code retour final = 2*256 = 512
}
else
{
#can not find table
$session->close;
exit 4; # code retour final = 4*256 = 1024
}
}
sub requeteTable {
my ($this, $oid) = @_;
my $result = $session->get_table( -baseoid => $oid );
request_error() if (!defined($result));
my %tab = ();
foreach my $i (Net::SNMP::oid_lex_sort(keys %{$result})) {
my $index = $i;
$index =~ s/$oid.//;
$tab{ $index } = $result->{$i};
#print $index."--".$result->{$i}."\n";
}
return %tab;
}
sub requete {
my ($this, $oid) = @_;
my $result = $session->get_request($oid);
request_error() if (!defined($result));
return $result->{$oid};
}
sub deconnexion {
my ($this) = @_;
$session->close();
}
1;