Skip to content

Instantly share code, notes, and snippets.

@Freeaqingme
Last active August 29, 2015 14:09
Show Gist options
  • Save Freeaqingme/e70aed309066abecadcd to your computer and use it in GitHub Desktop.
Save Freeaqingme/e70aed309066abecadcd to your computer and use it in GitHub Desktop.
Icinga2 perfdata to influxdb
#!/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