6 use Data::Dump qw(dump);
8 my $dir = 'public/json/monitor/printers/';
9 $dir = "/tmp/printers-" unless -d $dir;
13 my ( $ip, $json ) = @_;
14 my $path = $dir . $ip;
15 open(my $fh, '>', $path) || die "$path: $!";
16 print $fh encode_json $json;
18 warn "# $path ", -s $path, " bytes\n";
22 my ($ss,$mm,$hh,$d,$m,$y) = localtime(time);
23 return sprintf "%04d-%02d-%02dT%02d:%02d:%02d", $y+1900, $m, $d, $hh, $mm, $ss;
26 my $log_path = join('.', $dir . (split(/T/,iso_datetime,2))[0], 'json');
27 open(my $log, '>>', $log_path) || die "$log_path: $!";
29 my $community = 'public';
39 @printers = @ARGV if @ARGV;
42 info iso.3.6.1.2.1.1.1.0
43 hostname iso.3.6.1.2.1.43.5.1.1.16.1
44 serial iso.3.6.1.2.1.43.5.1.1.17.1
45 pages iso.3.6.1.2.1.43.10.2.1.4.1.1
46 @message iso.3.6.1.2.1.43.18.1.1.8
47 @consumable.name iso.3.6.1.2.1.43.11.1.1.6.1
48 @consumable.max iso.3.6.1.2.1.43.11.1.1.8.1
49 @consumable.curr iso.3.6.1.2.1.43.11.1.1.9.1
50 @tray.dim_x iso.3.6.1.2.1.43.8.2.1.4.1
51 @tray.dim_y iso.3.6.1.2.1.43.8.2.1.5.1
52 @tray.max iso.3.6.1.2.1.43.8.2.1.9.1
53 @tray.capacity iso.3.6.1.2.1.43.8.2.1.10.1
54 @tray.name iso.3.6.1.2.1.43.8.2.1.13.1
60 my ( $session, $oid2name ) = @_;
62 my $ip = $session->hostname;
64 if ( ! defined $session->var_bind_list ) {
65 warn "ERROR: $ip ", $session->error, "\n";
71 warn "# $ip var_bind_list ", dump( $session->var_bind_list );
72 my $results = $session->var_bind_list;
73 $response->{$ip}->{ip} ||= $ip;
74 $response->{$ip}->{utime} ||= time();
75 # oid_lex_sort would be wonderfull to use here, but it doesn't work
76 foreach my $r_oid ( sort {
77 my ($af,$bf) = ($a,$b);
78 $af =~ s{\.(\d+)$}{sprintf("%03d",$1)}eg;
79 $bf =~ s{\.(\d+)$}{sprintf("%03d",$1)}eg;
82 my $var = $results->{$r_oid};
84 substr($r_oid,0,length($_)) eq $_
85 } keys %$oid2name)[0] || die "no name for $r_oid in ",dump($oid2name);
86 my $name = $oid2name->{$oid};
87 if ( $name =~ m{^\@} ) {
88 my $no_prefix = $name;
89 $no_prefix =~ s{^\@}{};
90 push @{ $response->{$ip}->{ $no_prefix } }, $var;
92 $response->{$ip}->{ $name } = $var;
96 warn "## $ip response ",dump($response->{$ip});
99 foreach my $host ( @printers ) {
101 my ( $snmp, $err ) = Net::SNMP->session(
104 -community => $community,
111 warn "ERROR: $host $err\n";
118 while ( my ($name,$oid) = each %vars ) {
119 warn "# $name $oid\n";
121 if ( $name =~ m/^\@/ ) {
126 $oid2name->{$oid} = $name;
128 $snmp->get_request( -varbindlist => [ @vars ], -callback => [ \&columns_cb, $oid2name ] );
129 $snmp->get_entries( -columns => [ @columns ], -callback => [ \&columns_cb, $oid2name ] );
133 warn "# dispatch requests for ",dump(@printers);
136 foreach my $ip ( keys %$response ) {
138 my $status = $response->{$ip};
139 foreach my $group ( grep { /\w+\.\w+/ } keys %$status ) {
140 my ( $prefix,$name ) = split(/\./,$group,2);
141 if ( ref $status->{$group} eq 'ARRAY' ) { # some consumables are non-repeatable on low-end devices
142 foreach my $i ( 0 .. $#{ $status->{$group} } ) {
143 $status->{$prefix}->[$i]->{$name} = $status->{$group}->[$i];
146 $status->{$prefix}->[0]->{$name} = $status->{$group};
148 delete $status->{$group};
151 print "$ip ",dump($status);
152 save_json $ip => $response->{$ip};
153 print $log encode_json($response->{$ip}),"\n";
157 warn "# log $log_path ", -s $log_path, " bytes\n";