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.
Princeton/pu/libexec/check_papercut_status

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#\&nbsp;\&nbsp;#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);