You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
5.3 KiB
Perl
163 lines
5.3 KiB
Perl
#!/usr/local/bin/perl -w
|
|
#
|
|
# Papercut health monitoring
|
|
#
|
|
# By Igor V. Gubenko (igubenko@Princeton.EDU), 08/03/2016
|
|
#
|
|
# The program requires the JSON, REST::Client, and Try:Tiny libraries
|
|
# Data::Dumper is for debugging, and is not required for normal operation
|
|
#
|
|
# The program assumes that HTML output is desired. If this is not the case, light modification (commenting out) of HTML markup is needed
|
|
# Nagios requires "escape_html_tags=0" in cgi.cfg for HTML output
|
|
#
|
|
# Released under BSD 2-clause license
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use JSON;
|
|
use REST::Client;
|
|
use Data::Dumper;
|
|
use Try::Tiny;
|
|
|
|
# printserv => hostname or fqdn of the Papercut server
|
|
# apikey => the apikey of Papercut installation
|
|
# what => what to check - any of the keys of %queries below
|
|
# whatarg => unused for now
|
|
my ($printserv, $apikey, $what, $whatarg) = @ARGV;
|
|
my ($respcode, $data);
|
|
|
|
unless (@ARGV > 2) {
|
|
print STDERR "Usage: $0 {printserv} {api_auth_key} {health|printers_in_error|printer_urls|device_urls|sixtyminutes|queue|sysinfo}\n";
|
|
exit (2);
|
|
}
|
|
|
|
# Associates queries with corresponding URLs
|
|
my %queries = (
|
|
health => 'https://' . $printserv . ':9192/api/health/status?Authorization=' . $apikey,
|
|
printers_in_error => 'https://' . $printserv . ':9192/api/health/printers/status?in-error-threshold=50&Authorization=' . $apikey,
|
|
printer_urls => 'https://' . $printserv . ':9192/api/health/printers/urls?Authorization=' . $apikey,
|
|
device_urls => 'https://' . $printserv . ':9192/api/health/devices/urls?Authorization=' . $apikey,
|
|
sixtyminutes => 'https://' . $printserv . ':9192/api/stats/recent-pages-count?minutes=60&Authorization=' . $apikey,
|
|
queue => 'https://' . $printserv . ':9192/api/stats/held-jobs-count?Authorization=' . $apikey,
|
|
sysinfo => 'https://' . $printserv . ':9192/api/health?Authorization=' . $apikey,
|
|
);
|
|
|
|
# Associates the functions to run to parse each query type
|
|
my %functions;
|
|
foreach (keys %queries) {
|
|
$functions{$_} = \&$_;
|
|
}
|
|
|
|
## In all of the functions below, if $data is not a hash, then we assume that $data is a string, and simply return it for output
|
|
|
|
sub health {
|
|
return (ref $data eq ref {}) ? (exists $data->{message} ? $data->{message} : $data->{comment}) . "\n" : $data;
|
|
}
|
|
|
|
sub printers_in_error {
|
|
return (ref $data eq ref {}) ? (exists $data->{message} ? $data->{message} : $data->{comment}) . "\n" : $data;
|
|
}
|
|
|
|
sub printer_urls {
|
|
# return (ref $data eq ref {}) ? $data->{printer_urls} . "\n" : $data;
|
|
|
|
if (ref $data eq ref {}) {
|
|
return "";
|
|
} else {
|
|
# Remove the Unicode character
|
|
$data =~ s/^\x{ef}\x{bb}\x{bf}//;
|
|
my @rows = split /\n/, $data;
|
|
|
|
# Create HTML table markups for nice output
|
|
$data = "<table>";
|
|
foreach (@rows) {
|
|
my @cols = split /,/;
|
|
$data = $data . "<tr><td>" . join ("</td><td>", @cols[0,1,2]) . "</td></tr>";
|
|
}
|
|
$data .= "</table>";
|
|
return $data;
|
|
}
|
|
}
|
|
|
|
sub device_urls {
|
|
return (ref $data eq ref {}) ? $data->{device_urls} . "\n" : $data;
|
|
}
|
|
|
|
sub sixtyminutes {
|
|
return (ref $data eq ref {}) ? "In the last 60 minutes there were " . $data->{recentPagesCount} . " pages printed\n" : $data;
|
|
}
|
|
|
|
sub queue {
|
|
return (ref $data eq ref {}) ? "There are " . $data->{heldJobsCount} . " jobs currently held for release\n" : $data;
|
|
}
|
|
|
|
sub sysinfo {
|
|
if (ref $data eq ref {}) {
|
|
# Create nice, indented JSON output
|
|
my $jsonny = JSON->new;
|
|
my $jpretty = $jsonny->pretty->encode($data);
|
|
|
|
# Replace newlines with HTML line breaks
|
|
$jpretty =~ s#\n#<br>#g;
|
|
# Replace each space with 2 HTML spaces for nice indent
|
|
$jpretty =~ s#\s#\ \ #g;
|
|
return $jpretty . "\n";
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
### This is for reference
|
|
|
|
# health => Status summary: primary health check
|
|
#curl -k 'https://ss219w:9192/api/health/status?Authorization=apikey'
|
|
|
|
# printers_in_error => Status summary: alert if >1 printers are in error
|
|
#curl -k 'https://ss219w:9192/api/health/printers/status?in-error-threshold=1&Authorization=apikey'
|
|
|
|
# printer_urls => Status per printer: display printer status URL's
|
|
#curl -k 'https://ss219w:9192/api/health/printers/urls?Authorization=apikey'
|
|
|
|
# device_urls => Status per device: display device status URL's
|
|
#curl -k 'https://ss219w:9192/api/health/devices/urls?Authorization=apikey'
|
|
|
|
# sixtyminutes => Real time system stats: pages printed in the last 60 minutes
|
|
#curl -k 'https://ss219w:9192/api/stats/recent-pages-count?minutes=60&Authorization=apikey'
|
|
|
|
# queue => Real time system stats: # of jobs in hold/release queue
|
|
#curl -k 'https://ss219w:9192/api/stats/held-jobs-count?Authorization=apikey'
|
|
|
|
# sysinfo => Detailed system info
|
|
#curl -k 'https://ss219w:9192/api/health?Authorization=apikey'
|
|
|
|
# Don't verify SSL hostname in case the certificate is self-signed
|
|
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
|
|
|
|
my $client = REST::Client->new();
|
|
|
|
# Retrieve the relevant query using a REST client, since the output is almost always JSON
|
|
$client -> GET ($queries{$what});
|
|
#print $client->responseCode, "\n";
|
|
#print $client->responseContent, "\n";
|
|
|
|
$respcode = $client->responseCode;
|
|
|
|
try {
|
|
# Try to decode the JSON into a hash
|
|
$data = decode_json($client->responseContent);
|
|
#print Dumper ($data);
|
|
} catch {
|
|
# Unable to decode JSON - take the response as a string
|
|
$data = $client->responseContent;
|
|
};
|
|
|
|
# Run the relevant parsing function
|
|
print $functions{$what}();
|
|
|
|
# Depending on the HTTP return code, we return either OK or CRITICAL
|
|
$respcode = ($respcode eq '200') ? 0 : 2;
|
|
|
|
exit ($respcode);
|
|
|