use Net::SNMP;
use Data::Dump qw(dump);
+my $dir = 'public/json/monitor/printers/';
+$dir = "/tmp/printers-" unless -d $dir;
+
+use JSON;
+sub save_json {
+ my ( $ip, $json ) = @_;
+ my $path = $dir . $ip;
+ open(my $fh, '>', $path) || die "$path: $!";
+ print $fh encode_json $json;
+ close($fh);
+ warn "# $path ", -s $path, " bytes\n";
+}
+
+sub iso_datetime {
+ my ($ss,$mm,$hh,$d,$m,$y) = localtime(time);
+ return sprintf "%04d-%02d-%02dT%02d:%02d:%02d", $y+1900, $m, $d, $hh, $mm, $ss;
+}
+
+my $log_path = join('.', $dir . (split(/T/,iso_datetime,2))[0], 'json');
+open(my $log, '>>', $log_path) || die "$log_path: $!";
+
my $community = 'public';
my @printers = qw(
10.60.0.20
serial iso.3.6.1.2.1.43.5.1.1.17.1
pages iso.3.6.1.2.1.43.10.2.1.4.1
@message iso.3.6.1.2.1.43.18.1.1.8
-@consumable_name iso.3.6.1.2.1.43.11.1.1.6.1
-@consumable_max iso.3.6.1.2.1.43.11.1.1.8.1
-@consumable_curr iso.3.6.1.2.1.43.11.1.1.9.1
-@tray_dim_x iso.3.6.1.2.1.43.8.2.1.4.1
-@tray_dim_y iso.3.6.1.2.1.43.8.2.1.5.1
-@tray_max iso.3.6.1.2.1.43.8.2.1.9.1
-@tray_capacity iso.3.6.1.2.1.43.8.2.1.10.1
-@tray_name iso.3.6.1.2.1.43.8.2.1.13.1
+@consumable.name iso.3.6.1.2.1.43.11.1.1.6.1
+@consumable.max iso.3.6.1.2.1.43.11.1.1.8.1
+@consumable.curr iso.3.6.1.2.1.43.11.1.1.9.1
+@tray.dim_x iso.3.6.1.2.1.43.8.2.1.4.1
+@tray.dim_y iso.3.6.1.2.1.43.8.2.1.5.1
+@tray.max iso.3.6.1.2.1.43.8.2.1.9.1
+@tray.capacity iso.3.6.1.2.1.43.8.2.1.10.1
+@tray.name iso.3.6.1.2.1.43.8.2.1.13.1
];
our $response;
sub columns_cb {
- my ( $session, $oid, $name ) = @_;
+ my ( $session, $oid2name ) = @_;
+
+ my $ip = $session->hostname;
if ( ! defined $session->var_bind_list ) {
- warn "ERROR: ",$session->hostname, " $oid $name ", $session->error, "\n";
+ warn "ERROR: $ip ", $session->error, "\n";
warn dump($session);
return;
}
- warn "# $oid $name var_bind_list ", dump( $session->var_bind_list );
+ warn "# $ip var_bind_list ", dump( $session->var_bind_list );
my $results = $session->var_bind_list;
+ $response->{$ip} = { ip => $ip, utime => time() };
+ # oid_lex_sort would be wonderfull to use here, but it doesn't work
foreach my $r_oid ( sort {
my ($af,$bf) = ($a,$b);
$af =~ s{\.(\d+)$}{sprintf("%03d",$1)}eg;
$af cmp $bf
} keys %$results ) {
my $var = $results->{$r_oid};
+ my $oid = (grep {
+ substr($r_oid,0,length($_)) eq $_
+ } keys %$oid2name)[0] || die "no name for $r_oid in ",dump($oid2name);
+ my $name = $oid2name->{$oid};
+warn "++ $oid $name $var\n";
if ( $name =~ m{^\@} ) {
my $no_prefix = $name;
$no_prefix =~ s{^\@}{};
- push @{ $response->{ $session->hostname }->{ $no_prefix } }, $var;
+ push @{ $response->{$ip}->{ $no_prefix } }, $var;
} else {
- $response->{ $session->hostname }->{ $name } = $var;
+ $response->{$ip}->{ $name } = $var;
}
}
+
+ warn "## $ip response ",dump($response->{$ip});
+ save_json $ip => $response->{$ip};
+ print $log encode_json($response->{$ip}),"\n";
}
foreach my $host ( @printers ) {
next;
}
+ my @columns;
+ my @vars;
+ my $oid2name;
while ( my ($name,$oid) = each %vars ) {
warn "# $name $oid\n";
$oid =~ s{^iso}{.1};
if ( $name =~ m/^\@/ ) {
- $snmp->get_entries( -columns => [ $oid ], -callback => [ \&columns_cb, $oid, $name ] );
+ push @columns, $oid;
} else {
- $snmp->get_request( -varbindlist => [ $oid ], -callback => [ \&columns_cb, $oid, $name ] );
+ push @vars, $oid;
}
+ $oid2name->{$oid} = $name;
}
+ $snmp->get_request( -varbindlist => [ @vars ], -callback => [ \&columns_cb, $oid2name ] );
+ $snmp->get_entries( -columns => [ @columns ], -callback => [ \&columns_cb, $oid2name ] );
}
warn "# dispatch requests for ",dump(@printers);
snmp_dispatcher;
-print dump($response);
+foreach my $ip ( keys %$response ) {
+
+ my $status = $response->{$ip};
+ foreach my $group ( grep { /\w+\.\w+/ } keys %$status ) {
+ my ( $prefix,$name ) = split(/\./,$group,2);
+ if ( ref $status->{$group} eq 'ARRAY' ) { # some consumables are non-repeatable on low-end devices
+ foreach my $i ( 0 .. $#{ $status->{$group} } ) {
+ $status->{$prefix}->[$i]->{$name} = $status->{$group}->[$i];
+ }
+ } else {
+ $status->{$prefix}->[0]->{$name} = $status->{$group};
+ }
+ delete $status->{$group};
+ }
+
+ print "$ip ",dump($status);
+}
+
+close($log);
+warn "# log $log_path ", -s $log_path, " bytes\n";
+