Skip to content

Instantly share code, notes, and snippets.

@PhrozenByte
Last active February 6, 2016 12:31
Show Gist options
  • Save PhrozenByte/ffc804eff2447d58362d to your computer and use it in GitHub Desktop.
Save PhrozenByte/ffc804eff2447d58362d to your computer and use it in GitHub Desktop.
Helper functions for Munin plugins written in PHP
<?php
/**
* Helper functions for Munin plugins written in PHP
* Version 1.1 (build 20160206)
*
* Copyright (C) 2016 Daniel Rudolf <www.daniel-rudolf.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* See <http://www.gnu.org/licenses/> to receive a full-text-copy of
* the GNU General Public License.
*/
define('TIME_NOW', time());
set_error_handler(function($errorCode, $errorMessage, $errorFile, $errorLine) {
if (error_reporting() === 0) {
return false;
}
print_stderr('PHP error in file \'' . $errorFile . '\' on line ' . $errorLine . ': [' . $errorCode . '] ' . $errorMessage);
exit(1);
}, -1);
set_exception_handler(function(Exception $e) {
print_stderr('PHP exception in file \'' . $e->getFile() . '\' on line ' . $e->getLine() . ': [' . $e->getCode() . '] ' . $e->getMessage());
exit(1);
});
function print_stdout($message) {
print $message . "\n";
}
function print_stderr($message) {
fwrite(STDERR, $message . "\n");
}
function is_munin_autoconf() {
return (($_SERVER['argc'] > 1) && ($_SERVER['argv'][1] === 'autoconf'));
}
function is_munin_config() {
return (($_SERVER['argc'] > 1) && ($_SERVER['argv'][1] === 'config'));
}
function is_munin_suggest() {
return (($_SERVER['argc'] > 1) && ($_SERVER['argv'][1] === 'suggest'));
}
function is_munin_values() {
return (!is_munin_autoconf() && !is_munin_config() && !is_munin_suggest());
}
function check_multigraph($output = false) {
if (!isset($_SERVER['MUNIN_CAP_MULTIGRAPH']) || ($_SERVER['MUNIN_CAP_MULTIGRAPH'] != 1)) {
if ($output) {
if (is_munin_autoconf()) {
print_stdout('no (no multigraph support)');
} elseif (is_munin_config()) {
print_stdout('graph_title ' . (defined('GRAPH_NAME') ? GRAPH_NAME : 'This plugin') . ' requires multigraph support');
print_stdout('multigraph.label No multigraph here');
print_stdout('multigraph.info This plugin has been installed in a munin-node that is too old to know about multigraph plugins. Even if your munin master understands multigraph plugins this is not enough, the node too needs to be new enough. Version 1.4.0 or later should work.');
} elseif (is_munin_values()) {
print_stdout('multigraph.value 0');
}
}
return false;
}
return true;
}
function get_multigraph_env($fieldName, $variableName) {
$variadic = array_slice(func_get_args(), 2);
if (!defined('GRAPH_NAME')) {
return null;
}
do {
$identifier = GRAPH_NAME;
for ($i = 0, $l = count($variadic); $i < $l; $i++) {
if ($variadic[$i] === null) {
$variadic = array_slice($variadic, 0, $i);
break;
}
$identifier .= '_' . $variadic[$i];
}
if (isset($_SERVER[$identifier.'_'.$fieldName.'_'.$variableName])) {
return $_SERVER[$identifier.'_'.$fieldName.'_'.$variableName];
}
if (isset($_SERVER[$identifier.'_'.$variableName])) {
return $_SERVER[$identifier.'_'.$variableName];
}
} while (array_pop($variadic) !== null);
return null;
}
function read_statefile() {
if (file_exists($_SERVER['MUNIN_STATEFILE'])) {
$errorMessagePrefix = 'Unable to read statefile \'' . $_SERVER['MUNIN_STATEFILE'] . '\'';
if (!is_file($_SERVER['MUNIN_STATEFILE'])) {
throw new ErrorException($errorMessagePrefix . ': Not a file');
}
if (!is_readable($_SERVER['MUNIN_STATEFILE'])) {
throw new ErrorException($errorMessagePrefix . ': Permission denied');
}
$rawStateData = file($_SERVER['MUNIN_STATEFILE'], FILE_IGNORE_NEW_LINES);
if (!is_array($rawStateData)) {
throw new ErrorException($errorMessagePrefix . ': Unknown file() error');
}
if (empty($rawStateData) || ($rawStateData === array(''))) {
return array();
}
$magicStateNumber = array_shift($rawStateData);
if ($magicStateNumber !== '%MUNIN-STATE1.0') {
throw new ErrorException($errorMessagePrefix . ': unrecognized magic number \'' . $magicStateNumber . '\'');
}
$identifierPartRegex = '[a-zA-Z0-9](?:[a-zA-Z0-9\.\-_]*[a-zA-Z0-9])?';
$identifierRegex = defined('GRAPH_NAME') ? preg_quote(GRAPH_NAME, '/') : $identifierPartRegex;
$identifierRegex .= '(?:_' . $identifierPartRegex . ')*';
$stateData = array();
foreach ($rawStateData as $lineNo => $rawStateItem) {
if (preg_match('/^(' . $identifierRegex . ')\.([a-zA-Z0-9]+) (.+)$/', $rawStateItem, $rawStateItemMatches) !== 1) {
throw new ErrorException($errorMessagePrefix . ': invalid state item at line #' . ($lineNo + 1) . ': ' . $rawStateItem);
}
array_shift($rawStateItemMatches);
list($identifier, $fieldName, $rawValue) = $rawStateItemMatches;
$value = $rawValue;
if (is_string($rawValue) && preg_match('/^(N;|b:[01];|[aOs]:[0-9]+:.*[;}]|[id]:[0-9\.E\+\-]+;)$/su', $rawValue)) {
$value = unserialize($rawValue);
if (($value === false) && ($rawValue !== 'b:0;')) {
throw new ErrorException($errorMessagePrefix . ': invalid value of state item \'' . $identifier . '.' . $fieldName.'\' at line #' . ($lineNo + 1) . ': ' . $rawValue);
}
}
if (!isset($stateData[$identifier])) {
$stateData[$identifier] = array();
}
if (isset($stateData[$identifier][$fieldName])) {
throw new ErrorException($errorMessagePrefix . ': duplicate state item at line #' . ($lineNo + 1) . ': ' . $identifier . '.' . $fieldName);
}
$stateData[$identifier][$fieldName] = $value;
}
return $stateData;
}
return array();
}
function write_statefile($saveStateData, $strictTypes = false) {
if (file_exists($_SERVER['MUNIN_STATEFILE'])) {
if (!is_file($_SERVER['MUNIN_STATEFILE'])) {
throw new ErrorException($errorMessagePrefix . ': Not a file');
}
if (!is_writable($_SERVER['MUNIN_STATEFILE'])) {
throw new ErrorException($errorMessagePrefix . ': Permission denied');
}
}
if (!empty($saveStateData)) {
$errorMessagePrefix = 'Unable to write statefile \'' . $_SERVER['MUNIN_STATEFILE'] . '\'';
$rawSaveStateData = array();
$rawSaveStateData[] = '%MUNIN-STATE1.0';
foreach ($saveStateData as $identifier => $saveStateDataItem) {
foreach ($saveStateDataItem as $fieldName => $value) {
if (($fieldName === 'id') && ($value === $identifier)) {
continue;
}
if (!$strictTypes && (($value === null) || ($value === ''))) {
continue;
}
if ($strictTypes || (!is_string($value) && !is_int($value) && !is_float($value))) {
$value = serialize($value);
}
$rawSaveStateData[] = $identifier . '.' . $fieldName . ' ' . $value;
}
}
if (!file_exists($_SERVER['MUNIN_STATEFILE']) && !is_writable(dirname($_SERVER['MUNIN_STATEFILE']))) {
throw new ErrorException($errorMessagePrefix . ': Target directory not writable');
}
$result = file_put_contents($_SERVER['MUNIN_STATEFILE'], implode("\n", $rawSaveStateData) . "\n");
if ($result === false) {
throw new ErrorException($errorMessagePrefix . ': Unknown file_put_contents() error');
}
} else {
$result = unlink($_SERVER['MUNIN_STATEFILE']);
if ($result === false) {
throw new ErrorException($errorMessagePrefix . ': Unknown unlink() error');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment