Last active
August 29, 2015 14:09
-
-
Save Freeaqingme/e70aed309066abecadcd to your computer and use it in GitHub Desktop.
Icinga2 perfdata to influxdb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php5 | |
<?php | |
// select value from /.*/ | |
// delete from /.*/ | |
const PERFDATA_DIR = '/var/spool/icinga2/perfdata/'; | |
$dir = new DirectoryIterator(PERFDATA_DIR); | |
justKeepOnGoing: | |
foreach ($dir as $fileinfo) { | |
if ($fileinfo->isDot()) { | |
continue; | |
} | |
$timestamp = substr($fileinfo->getFilename(), strpos($fileinfo->getFilename(), '.') + 1); | |
if ($timestamp > (time() - 10)) { | |
// Allow icinga to finish writing the file. Maybe look into if it does some sort of locking? | |
continue; | |
} | |
parseFile(PERFDATA_DIR . $fileinfo->getFilename()); | |
} | |
sleep(10); | |
goto justKeepOnGoing; | |
function parseFile($filename) { | |
$lines = file($filename); | |
// Debug: $lines = array_chunk($lines, 50); $lines= $lines[0]; | |
$perfdata = array_map(function($line) { | |
$res = preg_match_all('/(([^\s^\:]*)\:{2}([^\t]*))/', trim($line), $matches); | |
if ($res === false || $res < 5 || $res > 10) { | |
echo "Could not parse line: $line\n"; | |
syslog(\LOG_WARNING, "Could not parse line: $line"); | |
return; | |
} | |
return array_combine($matches[2], $matches[3]); | |
}, $lines); | |
$parsedPerfData = array(); | |
array_walk($perfdata, function($line) use (&$parsedPerfData) { | |
$serviceDescKey = $line['DATATYPE'] == 'SERVICEPERFDATA' ? 'SERVICEDESC' : 'HOSTCHECKCOMMAND'; | |
if ($line[$line['DATATYPE']] == '') { | |
return; | |
} | |
preg_match_all("/(?:([a-z0-9\/\.]*)|(?:\'([^']*)\'))=([^\s]*)/", $line[$line['DATATYPE']], $matches); | |
$values = array_combine(array_replace($matches[1], array_filter($matches[2])), $matches[3]); | |
foreach($values as $key => $value) { | |
$measurement = strpos($value, ';') ? substr($value, 0, strpos($value, ';')) : $value; | |
// Separate number from unit. Keep in account scientific notation | |
preg_match('/([0-9\.]*(?:e\-?[0-9]*)?)([a-zA-Z]*)/', $measurement, $matches); | |
$out = array( | |
'value' => (float) $matches[1], | |
'time' => ((float) $line['TIMET'])*1000, | |
'unit' => $matches[2], | |
'raw_value' => $value | |
) + $line; | |
unset($out['TIMET']); | |
$parsedPerfData[$line[$serviceDescKey] . '.' . $key][] = $out; | |
} | |
}); | |
$out = array_map(function($name, $values) { | |
return array( | |
'name' => $name, | |
'time_precision' => 's', | |
'columns' => array_keys($values[0]), | |
'points' => array_map('array_values', $values) | |
); | |
}, array_keys($parsedPerfData), $parsedPerfData); | |
$json = json_encode($out); | |
$ch = curl_init('http://host:8086/db/icinga/series'); | |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $json); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 30); | |
curl_setopt($ch, CURLOPT_USERPWD, 'icinga:XXXXXXXXXXXXXXX' ); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array( | |
'Content-Type: application/json', | |
'Content-Length: ' . strlen($json)) | |
); | |
$return = curl_exec($ch); | |
curl_close($ch); | |
if ($return === false) { | |
echo sprintf('Could not import file %s: %s', $filename, $return) . PHP_EOL; | |
syslog(\LOG_ERR, sprintf('Could not import file %s: %s', $filename, $return)); | |
} else { | |
echo "imported $filename\n"; | |
$ret = unlink($filename); | |
if($ret === false) { | |
echo sprintf('Could not delete file %s', $filename); | |
syslog(\LOG_ERR, sprintf('Could not delete file %s', $filename)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment