use single get_request and one get_entries per host
[snmp-json.git] / printer-multi.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use SNMP::Multi;
6 use Data::Dump qw(dump);
7
8 use JSON;
9 sub save_json {
10         my ( $path, $json ) = @_;
11         $path = "json/$path";
12         open(my $fh, '>', $path);
13         print $fh encode_json $json;
14         close($fh);
15         warn "# $path ", -s $path, " bytes\n";
16 }
17
18 my $debug = $ENV{DEBUG} || 0; 
19
20 my $community = 'public';
21 my @printers = qw(
22 10.60.0.20
23
24 10.60.3.15
25 10.60.3.17
26
27 10.60.3.19
28 10.60.3.21
29
30 10.60.3.23
31 10.60.3.25
32
33 10.60.3.27
34 10.60.3.29
35
36 10.60.3.31
37 10.60.3.33
38
39 10.60.3.35
40 10.60.3.37
41 );
42
43 @printers = @ARGV if @ARGV;
44
45 # remove final .1 since we are using bulkwalk to get values!
46 my %vars = qw[
47 info                            iso.3.6.1.2.1.1.1.0
48 name                            iso.3.6.1.2.1.43.5.1.1.16.1
49 serial                          iso.3.6.1.2.1.43.5.1.1.17.1
50 pages                           iso.3.6.1.2.1.43.10.2.1.4.1
51 @message                        iso.3.6.1.2.1.43.18.1.1.8
52 @consumable_name        iso.3.6.1.2.1.43.11.1.1.6.1
53 @consumable_max         iso.3.6.1.2.1.43.11.1.1.8.1
54 @consumable_curr        iso.3.6.1.2.1.43.11.1.1.9.1
55 @tray_max                       iso.3.6.1.2.1.43.8.2.1.9.1
56 @tray_capacity          iso.3.6.1.2.1.43.8.2.1.10.1
57 @tray_name                      iso.3.6.1.2.1.43.8.2.1.13.1
58 @tray_dim_x                     iso.3.6.1.2.1.43.8.2.1.4.1
59 @tray_dim_y                     iso.3.6.1.2.1.43.8.2.1.5.1
60 ];
61
62 my $oid2name;
63 my @vars;
64 while ( my ($name,$oid) = each %vars ) {
65         $oid =~ s/\.[0-1]$// if $name !~ /^\@/;
66         push @vars, [ $oid ];
67         $oid2name->{$oid} = $name;
68 }
69 my @oids = sort { length $a <=> length $b } keys %$oid2name;
70 warn "# vars = ",dump(@vars) if $debug;
71
72 my $sm = SNMP::Multi->new(
73         Method    => 'bulkwalk',
74         Community => $community,
75         Requests  => SNMP::Multi::VarReq->new(
76                 hosts => [ @printers ],
77                 vars  => [ @vars ],
78     ),
79         Timeout     => 1,
80         Retries     => 0,
81 ) or die $SNMP::Multi::error;
82
83 warn "# working on: ", join(' ', @printers),$/;
84
85 my $resp = $sm->execute() or die $sm->error();
86
87 my $collected;
88
89 foreach my $host ( $resp->hosts ) {
90         my $status;
91
92         foreach my $result ( $host->results ) {
93                 if ( $result->error ) {
94                         warn "ERROR: $host ", $result->error;
95                         next;
96                 }
97
98                 warn "## result = ", dump($result) if $debug;
99
100                 foreach my $v ( $result->varlists ) {
101                         foreach my $i ( @$v ) {
102                                 my ( $oid, undef, $val, $fmt ) = @$i;
103                                 if ( my $name = $oid2name->{$oid} ) {
104                                         $status->{$name} = $val;
105                                 } else {
106                                         my $oid_base;
107                                         foreach ( @oids ) {
108                                                 my $oid_part = substr($oid,0,length($_));
109                                                 if ( $oid_part eq $_ ) {
110                                                         $oid_base = $oid_part;
111                                                         last;
112                                                 }
113                                         }
114
115                                         my $name = $oid2name->{$oid_base} || die "no name for $oid in ",dump( $oid2name );
116                                         if ( $name =~ s/^\@// ) {
117                                                 push @{ $status->{$name} }, $val;
118                                         } else {
119                                                 $status->{$name} = $val;
120                                         }
121                                 }
122                         }
123                 }
124
125         }
126
127         foreach my $group ( grep { /\w+_\w+/ } keys %$status ) {
128                 my ( $prefix,$name ) = split(/_/,$group,2);
129                 foreach my $i ( 0 .. $#{ $status->{$group} } ) {
130                         $status->{$prefix}->[$i]->{$name} = $status->{$group}->[$i];
131                 }
132                 delete $status->{$group};
133         }
134
135         print "$host = ",dump($status);
136         save_json $host => $status;
137         $collected->{$host} = $status;
138 }
139
140 # generate json
141 my $json;
142 foreach my $ip ( sort keys %$collected ) {
143         my $status = $collected->{$ip};
144         $status->{ip} = $ip;    
145         push @$json, $status;
146 }
147 save_json 'printers' => $json;
148