#!/usr/bin/perl
#
# check_apache_watch - Apache mod_watch monitoring plugin
# version 3.1   17.06.2016
# by Mikanoshi - iam@mikanoshi.name, http://code.highspec.ru/Mikanoshi/check_apache_watch
#
# Collectd output uses "apache" value format, add this to your types.db:
############################################ 
# apache	docs:GAUGE:0:U, reqs:GAUGE:0:U
############################################
#
# This plugin is a free software and comes with ABSOLUTELY NO WARRANTY.
# It may be used, redistributed and/or modified under the terms of the
# GNU General Public Licence Version 3 (see https://www.gnu.org/licenses/gpl.txt).

use Sys::Hostname;
use Term::ANSIColor;

my %exit_codes = ('UNKNOWN', 3, 'OK', 0, 'WARNING', 1, 'CRITICAL', 2);

my $ret = undef;
if (!eval "require LWP::UserAgent;") {
	$ret = "LWP::UserAgent not found";
}

if (@ARGV < 2) {
	print "Usage: check_apache_watch
	<watch-list url>
		".colored("[Required] watch-list URL, e.g. http://login:pass\@example.org:80/watch-list?auto", "grey6")."
	<domain.com,example.org,...>
		".colored("[Required] Comma-separated list of domains to monitor (used as type-instances for collectd and as \"domain\" tag for influxlp)", "grey6")."
	<collectd|influxlp>
		".colored("[Optional] Output format - nagios, collectd, influxlp (defaults to nagios)", "grey6")."
	
	".colored("Collectd format:", "underline")."
	<myhost.com>
		".colored("[Optional] Hostname (defaults to current system hostname)", "grey6")."
	<myplugin>
		".colored("[Optional] Plugin name (defaults to apachewatch)", "grey6")."
	<300>
		".colored("[Optional] Interval (defaults to 60 sec)", "grey6")."

	".colored("Influx Line-Protocol format:", "underline")."
	<mymeasurement>
		".colored("[Optional] Measurement name (defaults to apachewatch)", "grey6")."\n";
	exit $exit_codes{'UNKNOWN'};
}

my $URL = $ARGV[0];
my @domains = split(',', $ARGV[1]);
my $is_collectd = exists $ARGV[2] && $ARGV[2] eq "collectd";
my $is_influxlp = exists $ARGV[2] && $ARGV[2] eq "influxlp";
my $hostname = hostname();
my $plugin = "apachewatch";
my $type = "apache";
my $interval = 60;

if ($is_collectd) {
	if (exists $ARGV[3]) { $hostname = $ARGV[3] }
	if (exists $ARGV[4]) { $plugin = $ARGV[4] }
	if (exists $ARGV[5]) { $interval = $ARGV[5] }
}

if ($is_influxlp) {
	if (exists $ARGV[3]) { $plugin = $ARGV[3] }
}

my $message = "";
sub doprint {
	$msg = shift;
	if ($is_influxlp) {
		return;
	} elsif ($is_collectd) {
		$message .= $msg;
	} else {
		print $msg;
	}
}

my @servers = ();
my @data;

my $timestamp = time();
my $ua = LWP::UserAgent->new (timeout => 5);
my $response = $ua->request (HTTP::Request->new ('GET', $URL));

my $severity = "failure";
my $status = $exit_codes{'UNKNOWN'};
if ($response->is_success) {
	if ($response->code == 200) {
		doprint "OK - Data received";
		$severity = "okay";
		$status = $exit_codes{'OK'};
	} else {
		doprint "CRITICAL - Response code: ", $response->code, "\n";
		exit $exit_codes{'CRITICAL'};
	}
} else {
	doprint "CRITICAL - Cannot open watch-list url\n";
	exit $exit_codes{'CRITICAL'};
}

foreach my $string (split (/\n/, $response->content)) {
	my ($server, undef, $ifInOctets, $ifOutOctets, $ifRequests, $ifDocuments) = split (/\s/, $string, 6);
	push @servers, $server unless $server eq "SERVER";
	push @data, "$server $ifRequests $ifDocuments" unless $server eq "SERVER";
}

my $msgout = "";
if ($is_collectd) {
	$msgout = ($severity eq "okay") ? "" : "PUTNOTIF time=".$timestamp." severity=".$severity." host=".$hostname." plugin=".$plugin." type=".$type." message=\"".$message."\"\n";
}

doprint " |";
foreach my $string (sort (@data)) {
	my ($server, $ifRequests, $ifDocuments) = split (/\s/, $string);
	if (grep $_ eq $server, @domains) {
		(my $txtserver = $server) =~ s/(-|\.)/\_/g;
		doprint " ${txtserver}::docs=".$ifDocuments."c;;; ${txtserver}::reqs=".$ifRequests."c;;;";
		if ($is_influxlp) {
			$msgout .= $plugin.",domain=".$server." docs=".$ifDocuments.",reqs=".$ifRequests." ".($timestamp * 1000000000)."\n";
		} elsif ($is_collectd) {
			$msgout .= "PUTVAL ".$hostname."/".$plugin."/".$type."-".$txtserver." interval=".$interval." ".$timestamp.":".$ifDocuments.":".$ifRequests."\n";
		}
	}
}
doprint "\n";

if ($is_collectd || $is_influxlp) {
	print $msgout;
}

exit $status;