📄 data.pm
字号:
package Cisco::Accounting::Data;## ----------------------------------------------------------------------------------------------## Cisco::Accounting::Data#### $Id: Data.pm 119 2007-08-18 21:36:42Z mwallraf $## $Author: mwallraf $## $Date: 2007-08-18 23:36:42 +0200 (Sat, 18 Aug 2007) $#### This program is free software; you can redistribute it and/or## modify it under the same terms as Perl itself.## ----------------------------------------------------------------------------------------------$VERSION = "1.00";use strict;use warnings;use Carp;#use Data::Dumper;my $DEBUG = 0;# $data = reference to @output of the telnet command "show ip accounting"sub new { my ($this) = shift; my (%parms) = @_; my $class = ref($this) || $this; my $self = {}; bless($self, $class); $self->{'headers'} = [ 'source', 'destination', 'lastPollBytes', 'lastPollPackets', 'totalBytes', 'totalPakcets', 'polls' ]; $self->{'data'} = {}; # "src-dest" -> [ source, destination, lastPollBytes, lastPollPackets, totalBytes, totalPakcets, polls ] $self->{'stats'}->{'totalpolls'} = 0; $self->{'stats'}->{'totalbytes'} = 0; $self->{'stats'}->{'totalpackets'} = 0; $self->{'stats'}->{'totalpolledlines'} = 0; $self->{'stats'}->{'totalskippedlines'} = 0; $self->{'stats'}->{'uniquehostpairs'} = 0; $self->{'stats'}->{'starttime'} = ''; # starttime of the first poll $self->{'stats'}->{'lastpolltime'} = ''; # time last poll has run $self->{'keep_history'} = (defined($parms{'keep_history'}))?($parms{'keep_history'}):(1); # keep summarized historical data for each poll $self->{'historical'} = {}; # {'timestamp'} -> { 'totalBytes' -> '', 'totalPackets' -> '', 'hostPairs' -> ''} &_init($class); return($self);} # end sub new# initialization : set up logging sub _init { my $class=shift; ## enable debugging if needed $SIG{'__WARN__'} = sub { carp($_[0]) } if ($DEBUG > 0);}## parse telnet data output into $self->{'data'} output# data should always be in format : / *source *destination *packets *bytes */#sub parse { my ($self) = shift; my ($acct_data) = shift; # reference to array of output lines my ($row); my ($src, $dst, $packets, $bytes); ## update last poll time $self->{'stats'}->{'lastpolltime'} = time(); $self->{'stats'}->{'starttime'} = time() unless ($self->{'stats'}->{'starttime'}); foreach $row (@{$acct_data}) { eval { ($src, $dst, $packets, $bytes) = &_parse_row($row); }; ## update historical data if needed ## in case there's no data, still update poll time to historical data if (!defined($self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}) && $self->{'keep_history'}) { $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'hostPairs'} = 0; $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'totalBytes'} = 0; $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'totalPackets'} = 0; } ## skip row if we didn't find what we expected (src, dst, packets, bytes) if ($@) { $self->{'stats'}->{'totalskippedlines'}++; if ($DEBUG > 0) { carp("skipping row : " . $@); } next; } ## update the statistics, if the source-destination combination already exists ## then add the new data to existing if (exists $self->{'data'}->{"$src-$dst"}) { $self->{'data'}->{"$src-$dst"}->{'lastPollBytes'} = $bytes; $self->{'data'}->{"$src-$dst"}->{'lastPollPackets'} = $packets; $self->{'data'}->{"$src-$dst"}->{'totalBytes'} += $bytes; $self->{'data'}->{"$src-$dst"}->{'totalPackets'} += $packets; $self->{'data'}->{"$src-$dst"}->{'polls'} ++; } ## if this is the first time we see this host pair then initialize stats else { $self->{'data'}->{"$src-$dst"}->{'source'} = $src; $self->{'data'}->{"$src-$dst"}->{'destination'} = $dst; $self->{'data'}->{"$src-$dst"}->{'lastPollBytes'} = $bytes; $self->{'data'}->{"$src-$dst"}->{'lastPollPackets'} = $packets; $self->{'data'}->{"$src-$dst"}->{'totalBytes'} = $bytes; $self->{'data'}->{"$src-$dst"}->{'totalPackets'} = $packets; $self->{'data'}->{"$src-$dst"}->{'polls'} = 1; $self->{'stats'}->{'uniquehostpairs'} ++; } # ## update historical data if needed if ($self->{'keep_history'}) {# if (defined($self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}})) { $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'hostPairs'}++; $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'totalBytes'} += $bytes; $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'totalPackets'} += $packets; # }# else {# $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'hostPairs'} = 1;# $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'totalBytes'} = $bytes; # $self->{'historical'}->{$self->{'stats'}->{'lastpolltime'}}->{'totalPackets'} = $packets; # } } ## update global statistics $self->{'stats'}->{'totalbytes'} += $bytes; $self->{'stats'}->{'totalpackets'} += $packets; $self->{'stats'}->{'totalpolledlines'} ++; } ## update stats $self->{'stats'}->{'totalpolls'} ++; return $self->{'data'};}#### parses a single row of data, returns array of (source, destination, packets, bytes)## dies otherwise##sub _parse_row() { my ($row) = shift; my (@cols); ## remove leading and trailing spaces, eol characters ## split row in columns delimited by spaces $row =~ s/^ *(.*)[ \n]*$/$1/; @cols = split(/ +/,$row); ## die unless we've got 4 columns if ((scalar @cols) < 4) { croak("skip row, we need 4 columns (\"$row\")"); } ## validate each column, make sure it contains the correct data eval { map { &_validate_column('column' => $_, 'ip' => 1); } ($cols[0], $cols[1]); # these columns should contain ip addresses map { &_validate_column('column' => $_, 'ip' => 0); } ($cols[2], $cols[3]); # these columns should contain positive number }; if ($@) { croak("skip row, invalid column format : " . $@); } ## everything is ok, we got (source, destination, packets, bytes) return @cols;}#### validate a single column## parameters = column => $col, ip => 0|1##sub _validate_column() { my (%parms) = @_; my $column = $parms{'column'}; my $is_ip = $parms{'ip'} || 0; if (!$column) { croak("column does not contain a value ($column)"); } ## check if it's an ip address if ($is_ip > 0) { unless ($column =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/) { croak("expecting ip address but not found in column \"$column\""); } } ## check if it's a positive number else { unless ($column =~ /^[0-9]+$/) { croak("expecting positive number but not found in column \"$column\""); } }}#### returns reference to array with the default headers for the columns##sub get_headers() { my ($self) = shift; return $self->{'headers'};}#### return reference to output hash, hash contains reference to array of columns##sub get_data() { my ($self) = shift; return $self->{'data'};}#### return reference to hash with statistics##sub get_stats() { my ($self) = shift; return $self->{'stats'};}#### return reference to hash with statistics##sub get_history() { my ($self) = shift; return $self->{'historical'};}sub get_total_polls() { my ($self) = shift; return $self->{'stats'}->{'totalpolls'};}sub get_total_polled_lines() { my ($self) = shift; return $self->{'stats'}->{'totalpolledlines'};}sub get_total_bytes() { my ($self) = shift; return $self->{'stats'}->{'totalbytes'};}sub get_total_packets() { my ($self) = shift; return $self->{'stats'}->{'totalpackets'};}sub get_last_poll_time() { my ($self) = shift; return $self->{'stats'}->{'lastpolltime'};}sub get_first_poll_time() { my ($self) = shift; return $self->{'stats'}->{'starttime'};}1;__END__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -