#!/usr/local/bin/php
<?php
	# check_influx - Plugin outputs data from InfluxDB in Nagios format
	# version 1.0   18.06.2016
	# by Mikanoshi - iam@mikanoshi.name, http://code.highspec.ru/Mikanoshi/check_influx
	#
	# 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).

	require_once __DIR__.'/vendor/autoload.php';

	//error_reporting(E_ALL);
	//ini_set('display_errors', 1);

	// InfluxDB settings
	$host = "localhost";
	$port = 8086;
	$db = "telegraf";

	$options = getopt("k:m:t:f:s:l:w:c:zpxb");

	if (isset($options["k"]))
		$keys = $options["k"];
	else
		usage();

	$measures = isset($options["m"]) ? $options["m"] : $measures = "/.*/";
	$format =  isset($options["f"]) ? $options["f"] : "";
	$timespan = isset($options["s"]) ? $options["s"] : "15m";
	$limit = isset($options["l"]) ? $options["l"] : 1;
	$titles = isset($options["t"]) ? explode(",", $options["t"]) : array();
	$warns = isset($options["w"]) ? explode(",", $options["w"]) : array();
	$crits = isset($options["c"]) ? explode(",", $options["c"]) : array();
	$istest = isset($options["z"]);
	$ispercents = isset($options["p"]);
	$iscounter = isset($options["x"]);
	$isbytes = isset($options["b"]);

	$client = new \InfluxDB\Client($host, $port);
	$database = $client->selectDB($db);

	$query = "SELECT ".$keys." FROM ".$measures." WHERE time > now() - ".$timespan." ORDER BY time DESC LIMIT ".$limit;
	$result = $database->query($query);
	$points = $result->getPoints();

	if ($istest) {
		echo $query."\n";
		print_r($points);
		die();
	}

	$vals = array();
	foreach ($points as $point)
	foreach ($point as $name => $value)
	if ($name !== "time" && $value !== "") array_push($vals, array($name, $value));

	$status = -1;
	if ($format == "perfdata")
		$info = "Data received ";
	else
		$info = "";
	$perfdata = "";

	function checklimit($val, $limit) {
		global $format;
		return $val > $limit;
	}

	foreach ($vals as $ds => $val) {
		if ($format == "info")
			$valueInfo = ($iscounter || $isbytes) ? round($val[1]) : round($val[1], 6);
		else
			$valueInfo = ($iscounter || $isbytes) ? round($val[1]) : round($val[1], 2);
		$valueData = ($iscounter || $isbytes) ? round($val[1]) : round($val[1], 6);
		$warn = array_key_exists($ds, $warns) ? $warns[$ds] : "";
		$crit = array_key_exists($ds, $crits) ? $crits[$ds] : "";
		if ($crit != "" && checklimit($valueData, $crit) && $status < 2) {
			$status = 2;
		} else if ($warn != "" && checklimit($valueData, $warn) && $status < 1) {
			$status = 1;
		} else if ($status < 0) {
			$status = 0;
		}
		$title = array_key_exists($ds, $titles) ? $titles[$ds] : $val[0];
		$unitsInfo = $ispercents ? "%": ($isbytes ? "B" : "");
		$unitsData = $ispercents ? "%": ($iscounter ? "c" : ($isbytes ? "B" : ""));
		if ($format === "" || $format === "info") $info .= $title."=".$valueInfo.$unitsInfo." ";
		$perfdata .= $title."=".$valueData.$unitsData.";".$warn.";".$crit." ";
	}

	if ($status == 0) echo "OK - "; else
	if ($status == 1) echo "WARNING - "; else
	if ($status == 2) echo "CRITICAL - "; else {
		echo "UNKNOWN - ";
		$info = "No data ";
		$status = 3;
	}

	echo $info;
	if ($perfdata !== "" && $format !== "info") echo "| ".$perfdata;
	echo "\n";
	exit($status);

	function usage() {
		echo "Usage:
	check_influx
	-k <key1,key2,...>
		[Required] Field keys to select (can contain aggregate functions, return last values)
	-m <meas1,meas2,...>
		[Optional] Measurements to get fields from (search all if not specified)
	-s <5m|1h|1d|...>
		[Optional] Defines period from now that is used to collect values (defaults to 15 minutes)
	-l <limit>
		[Optional] Number of points to display (defaults to 1, results are sorted by time in descending order)
	-t <title1,title2,...>
		[Optional] Replace field keys with these titles in an output string
	-w <warn_level1,warn_level2,...>
	-c <crit_level1,crit_level2,...>
		[Optional] Warning and critical levels for every field
	-f <perfdata|info>
		[Optional] Display only info or perfdata part (both if not specified)
	-x
		[Optional] Add c units to all values (counters)
	-p
		[Optional] Add % to all values (percents)
	-b
		[Optional] Add B to all values (data sizes)
	-z
		[Optional, Debug] Output query string and returned array of values only
Examples:
	check_influx -k conn_established,load1,load5 -m net,system -t acpt,1min,5min -w 50,3,6 -c 100,5,9 -s 15m
	check_influx -k usage_system,usage_user,usage_irq -m cpu -t system,user,irq -w 80,80,80 -c 90,90,90 -s 5m -p\n";
		exit(3);
	}
?>