File Coverage

blib/lib/Log/Dispatch/SNMP.pm
Criterion Covered Total %
statement 45 52 86.5
branch 5 10 50.0
condition 1 3 33.3
subroutine 11 12 91.6
pod 2 2 100.0
total 64 79 81.0


line stmt bran cond sub pod time code
1             ########################################
2             package Log::Dispatch::SNMP;
3 2     2   53065 use Log::Dispatch::Output;
  2         34756  
  2         56  
4 2     2   20 use base qw( Log::Dispatch::Output );
  2         3  
  2         131  
5             ########################################
6 2     2   11 use strict;
  2         10  
  2         56  
7 2     2   12 use warnings;
  2         2  
  2         67  
8              
9 2     2   5020 use Net::SNMP qw(:asn1);
  2         309194  
  2         833  
10 2     2   23 use Params::Validate qw(validate SCALAR);
  2         6  
  2         160  
11 2     2   13 use Carp qw(carp croak); #TODO: option to warn or die or do nothing on errors
  2         4  
  2         1518  
12              
13             our $VERSION = '0.02';
14              
15             sub new {
16 8     8 1 9945 my $proto = shift;
17 8   33     42 my $class = ref $proto || $proto;
18              
19             # new versions of Log::Dispatch may complain about unknown options,
20             # so we take our options out of the equation (err.. hash)
21 8         30 my %parameters = @_;
22 8         12 my %snmp_parameters = ();
23 8         14 foreach my $key (qw(ManagementHostTrapListenPort
24             ManagementHost
25             EnterpriseOID
26             LocalIPAddress
27             LocalTrapSendPort
28             GenericTrapType
29             SpecificTrapType
30             ApplicationTrapOID
31             CommunityString
32             )
33             ) {
34 72 100       147 if (exists $parameters{$key}) {
35 39         60 $snmp_parameters{$key} = $parameters{$key};
36 39         54 delete $parameters{$key};
37             }
38             }
39              
40 8         25 my $self = bless {}, $class;
41              
42 8         37 $self->_basic_init(%parameters);
43 7         626 $self->_set_snmp_parameters(%snmp_parameters);
44 2         8 $self->_start_snmp_session();
45            
46 2         15 return $self;
47             }
48              
49             sub _set_snmp_parameters {
50 7     7   10 my $self = shift;
51              
52             # validate user supplied parameters
53 7         1544 my %p = validate (@_, {
54             'ManagementHostTrapListenPort' => { type => SCALAR,
55             default => 162,
56             },
57             'ManagementHost' => { type => SCALAR },
58             'EnterpriseOID' => { type => SCALAR },
59             'LocalIPAddress' => { type => SCALAR },
60             'LocalTrapSendPort' => { type => SCALAR,
61             default => 161,
62             },
63             'GenericTrapType' => { type => SCALAR,
64             default => 6,
65             },
66             'SpecificTrapType' => { type => SCALAR },
67             'ApplicationTrapOID' => { type => SCALAR },
68             'CommunityString' => { type => SCALAR,
69             default => 'public',
70             },
71             });
72            
73             # put everything in the actual object
74 2         25 foreach (keys %p) {
75 18         35 $self->{$_} = $p{$_};
76             }
77             }
78              
79             sub _start_snmp_session {
80 2     2   4 my $self = shift;
81 2         3 my $error = '';
82            
83 2         30 ($self->{'session'}, $error) =
84             Net::SNMP->session(
85             -hostname => $self->{'ManagementHost'},
86             -port => $self->{'ManagementHostTrapListenPort'},
87             -version => 'snmpv1', #TODO: make this configurable
88             -community => $self->{'CommunityString'},
89             -nonblocking => 0, #TODO: make this configurable
90             -domain => 'udp4', #TODO: make this configurable
91             );
92 2 50       37968 croak "error starting SNMP session: $error\n"
93             unless $self->{'session'};
94             }
95              
96             sub log_message {
97 0     0 1 0 my $self = shift;
98 0         0 my %p = @_;
99              
100             #TODO: This check is probably not necessary
101             # or could be just plain wrong
102 0 0       0 $self->_start_snmp_session()
103             unless $self->{'session'};
104            
105             # first trio is always the EOID
106 0         0 my @varbindlist = (
107             $self->{'EnterpriseOID'},
108             OBJECT_IDENTIFIER,
109             $self->{'EnterpriseOID'},
110             );
111            
112             # then we put the message itself on the varbind.
113             # this is separate in order to easen the future
114             # (planned) integration with a special Layout
115             # "SnmpDelimitedConversionPatternLayout" for Log4perl.
116 0         0 push @varbindlist, $self->{'ApplicationTrapOID'},
117             OCTET_STRING,
118             $p{'message'}
119             ;
120            
121 0 0       0 if ( ! $self->{'session'}->trap(
122             -enterprise => $self->{'EnterpriseOID'},
123             -generictrap => $self->{'GenericTrapType'},
124             -specifictrap => $self->{'SpecificTrapType'},
125             -varbindlist => \@varbindlist,
126             )
127             ) {
128 0         0 carp 'Error sending trap: ' . $self->{'session'}->error() . "\n";
129             }
130             }
131              
132             sub DESTROY {
133 8     8   3429 my $self = shift;
134 8 100       47 if ($self->{'session'}) {
135 2         8 $self->{'session'}->close();
136             }
137             }
138              
139             42;
140             __END__