/** Returns a list of templates. @param array $templatepaths list of requested templates. @return array list of templates. **/ public function loadTemplates(array $templatepaths, $loader) { $templates = array(); $hasChanged = false; foreach ($templatepaths as $path) { $fileAge = filemtime($path); if ($this->templates != null && array_key_exists($path, $this->templates) && $this->templates[$path][FILE_AGE_KEY] >= $fileAge) { array_push($templates, $this->templates[$path][RULE_KEY]); continue; } $template = call_user_func($loader, $path); if ($template == null) { \histou\Debug::add("The template: {$path} is not valid PHP!"); } else { $hasChanged = true; $this->templates[$path][FILE_AGE_KEY] = $fileAge; $this->templates[$path][RULE_KEY] = $template->getRule(); array_push($templates, $template); } } if ($hasChanged) { $this->saveCache(); } return $templates; }
public function testErrorMarkdownDashboard() { $this->init(); $panel = new \histou\grafana\TextPanel('', 1); $panel->setMode(\histou\grafana\TextPanel::MARKDOWN); $panel->setContent("foo"); $row = new \histou\grafana\Row("ERROR"); $row->addPanel($panel); $dashboard = new \histou\grafana\dashboard\dashboardInfluxdb('Error'); $dashboard->addRow($row); $this->assertEquals($dashboard, \histou\Debug::errorMarkdownDashboard("foo")); }
public static function testConfig() { //test php command $cmd = static::$phpCommand . " -h 2>&1"; $process = proc_open($cmd, \histou\Basic::$descriptorSpec, $pipes); if (!is_resource($process)) { \histou\Basic::returnData(\histou\Debug::errorMarkdownDashboard("# Error: Could not start: {$cmd}")); // @codeCoverageIgnore return 1; // @codeCoverageIgnore } stream_get_contents($pipes[1]); fclose($pipes[1]); $returnCode = proc_close($process); if ($returnCode != 0) { \histou\Basic::returnData(\histou\Debug::errorMarkdownDashboard("# '" . $cmd . "' did not return with returncode 0. Maybe the phpCommand is not set properly."), 1); return 1; } return 0; }
public function testReturnData() { $this->init(); \histou\Debug::enable(); $dashboard = new \histou\grafana\dashboard\DashboardInfluxDB('foo'); ob_start(); \histou\Basic::returnData($dashboard); $out1 = ob_get_contents(); ob_end_clean(); $this->assertSame($this->emptyDashboard, $out1); $_GET["callback"] = 1; ob_start(); \histou\Basic::returnData('{"foo":"bar"}'); $out2 = ob_get_contents(); ob_end_clean(); $this->assertSame('1({"foo":"bar"})', $out2); ob_start(); \histou\Basic::returnData(1); $out3 = ob_get_contents(); ob_end_clean(); $this->assertContains("<pre>Don't know what to do with this type: integer", $out3); }
/** Uses the php -l command to test if a file contains valid PHP code. @param string $filePath path to the file to check. @return bool. **/ public static function isFileValidPHP($filePath) { //TODO:test if php content. e.g. just foo would work... $cmd = \histou\Basic::$phpCommand . " -l {$filePath} 2>&1"; $process = proc_open($cmd, \histou\Basic::$descriptorSpec, $pipes); if (!is_resource($process)) { \histou\Debug::add("Error: Could not start: {$cmd}"); // @codeCoverageIgnore return false; // @codeCoverageIgnore } $syntaxCheck = stream_get_contents($pipes[1]); fclose($pipes[1]); $returnCode = proc_close($process); if (substr($syntaxCheck, 1, 12) == "Parse error:") { \histou\Debug::add("Syntaxcheck: " . $syntaxCheck); } if ($returnCode != 0) { \histou\Debug::add("Error: " . $syntaxCheck); } return $returnCode == 0; }
foreach ($forecastTemplates as $ftemplate) { \histou\Debug::add($ftemplate); } \histou\Debug::add("Is the first ForecastTemplate valid: " . \histou\Debug::printBoolean($fValid) . "\n"); if ($fValid) { $forecastTemplate = $forecastTemplates[0]; $className = get_class($forecastTemplate); if ($className == 'histou\\template\\Rule') { $forecast = \histou\template\loader::loadForecastTemplate($forecastTemplate->getFileName(), true); } if (isset($forecast)) { $forecast->setForecastDurations(); } } if (isset($template) && !empty($template)) { $className = get_class($template); if ($className == 'histou\\template\\Rule') { $dashboard = \histou\template\loader::loadTemplate($template->getFileName(), true)->generateDashboard($perfData); } elseif ($className == 'histou\\template\\Template' || $className == 'histou\\template\\SimpleTemplate') { $dashboard = $template->generateDashboard($perfData); } else { \histou\Basic::returnData(\histou\Debug::errorMarkdownDashboard("# unkown class {$className}"), 1); } if ($dashboard == null) { \histou\Basic::returnData(\histou\Debug::errorMarkdownDashboard('# Template did not return a dashboard!'), 1); } else { \histou\Basic::returnData($dashboard, 0); } } else { \histou\Basic::returnData(\histou\Debug::errorMarkdownDashboard('# No template found!'), 1); }
public function testForecastLoad() { $files = array(join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template1.php')) => '<?php $rule = new \\histou\\template\\Rule( $host = ".*", $service = ".*", $command = "NONE", $perfLabel = array("rta", "pl") ); $forecast = <<<EOF [ { "label":"size", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"10m", "forecast_interval":"1m", "update_rate":"1m" }, { "label":"time", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"10m", "forecast_interval":"1m", "update_rate":"1m" } ] EOF; ', join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template2.php')) => '<?php $rule = new \\histou\\template\\Rule( $host = ".*", $service = ".*", adsfasdfasdf $command = ".*", $perfLabel = array("rta", "pl") ); $forecast = <<<EOF [ { "label":"size", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"10m", "forecast_interval":"1m", "update_rate":"1m" }, { "label":"time", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"10m", "forecast_interval":"1m", "update_rate":"1m" } ] EOF; ', join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template3.php')) => '<?php $rule = new \\histou\\template\\Rule( $host = ".*", $service = ".*", $command = ".*", $perfLabel = array("rta", "pl") ); $forecast = <<<EOF [ { "label":"size", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"20m", "forecast_interval":"1m", "update_rate":"1m" }, { "label":"time", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"30m", "forecast_interval":"1m", "update_rate":"1m" } ] EOF; '); foreach ($files as $file => $content) { file_put_contents($file, $content); } $templateFiles = \histou\Folder::loadFolders(array(FORECAST_TEMPLATE_FOLDER)); $expected = array(join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template1.php')), join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template2.php')), join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template3.php'))); $this->assertEquals(sort($expected), sort($templateFiles)); $templates = array(); foreach ($files as $file => $content) { array_push($templates, \histou\template\Loader::loadForecastTemplate($file)); } $this->assertInstanceOf('\\histou\\template\\ForecastTemplate', $templates[0]); $this->assertInstanceOf('\\histou\\template\\ForecastTemplate', $templates[2]); $this->assertSame(null, $templates[1]); //Syntaxcheck failed $this->assertContains('Parse error: syntax error', \histou\Debug::getLogAsMarkdown()); $this->assertSame(FORECAST_TEMPLATE_FOLDER, $templates[0]->getPath()); $this->assertSame('template1.php', $templates[0]->getBaseName()); $this->assertSame('template1', $templates[0]->getSimpleFileName()); $this->assertSame("File:\t{$expected['0']}:\nRule:\n\tFile:\t{$expected['0']}:\n\t\tHost: ;.*;\n\t\tService: ;.*;\n\t\tCommand: ;^\$;\n\t\tPerflabel: ;pl;, ;rta;", $templates[0]->__toString()); $rule = $templates[0]->getRule(); $this->assertSame('template1.php', $rule->getBaseName()); $this->assertSame(join(DIRECTORY_SEPARATOR, array(FORECAST_TEMPLATE_FOLDER, 'template1.php')), $rule->getFileName()); $expected = '[ { "label":"size", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"10m", "forecast_interval":"1m", "update_rate":"1m" }, { "label":"time", "method":"SimpleLinearRegression", "methodSpecificOptions":{ }, "lookback_range":"30m", "forecast_range":"10m", "forecast_interval":"1m", "update_rate":"1m" } ]'; $this->assertSame($expected, $templates[0]->getJSON()); $this->assertSame(null, \histou\template\ForecastTemplate::$config); $templates[0]->setForecastDurations(); $this->assertSame(array('size' => array('method' => 'SimpleLinearRegression', 'forecast' => '10m'), 'time' => array('method' => 'SimpleLinearRegression', 'forecast' => '10m')), \histou\template\ForecastTemplate::$config); $templates[2]->setForecastDurations(); $this->assertSame(array('size' => array('method' => 'SimpleLinearRegression', 'forecast' => '20m'), 'time' => array('method' => 'SimpleLinearRegression', 'forecast' => '30m')), \histou\template\ForecastTemplate::$config); $default = \histou\template\template::findDefaultTemplate($templates, "template1.php"); $this->assertSame($templates[0], $default); $default2 = \histou\template\template::findDefaultTemplate($templates, "foo.php"); $this->assertSame(null, $default2); }
$forecastTemplate = \histou\template\loader::loadForecastTemplate($forecastTemplate->getFileName(), true); } $result .= $forecastTemplate->getJSON(); } else { $result .= "[]"; } $result .= ","; } $result = rtrim($result, ","); $result .= "]"; echo $result; } else { \histou\template\Rule::setCheck(HOST, SERVICE, COMMAND, $PERF_LABEL); usort($forecastTemplates, '\\histou\\template\\Template::compare'); $fValid = $forecastTemplates[0]->isValid(); \histou\Debug::add("ForecastTemplate order:"); foreach ($forecastTemplates as $ftemplate) { \histou\Debug::add($ftemplate); } \histou\Debug::add("Is the first ForecastTemplate valid: " . \histou\Debug::printBoolean($fValid) . "\n"); if ($fValid) { $forecastTemplate = $forecastTemplates[0]; $className = get_class($forecastTemplate); if ($className == 'histou\\template\\Rule') { $forecastTemplate = \histou\template\loader::loadForecastTemplate($forecastTemplate->getFileName(), true); } echo $forecastTemplate->getJSON(); } else { echo "[]"; } }
/** Expects a filename and parses the file, to return a rule and a dashbord lambda. @param string $file Path to file. @return array. **/ public static function parseSimpleTemplate($file) { $lines = file($file, FILE_SKIP_EMPTY_LINES); $foundJson = false; $ruleHits = array(); $dashboard = ""; foreach ($lines as $line) { if (substr(trim($line), 0, 1) == "#") { //Comment found continue; } if ($foundJson) { $dashboard .= $line; } else { if (sizeof($ruleHits) != 4) { //Searching for Ruleset foreach (array('host', 'service', 'command', 'perfLabel') as $type) { if (preg_match(";^\\s*{$type}\\s*=\\s*(.*?)\$;", $line, $hit)) { if ($type == 'perfLabel') { $ruleHits[$type] = str_getcsv($hit[1]); foreach ($ruleHits[$type] as &$label) { $label = trim($label); } } else { $ruleHits[$type] = trim($hit[1]); } } } } if (preg_match(";^\\s*{;", $line)) { //Found dashboard beginning $foundJson = true; $dashboard .= $line; } } } $rule = new Rule($ruleHits['host'], $ruleHits['service'], $ruleHits['command'], $ruleHits['perfLabel']); $genTemplate = function ($perfData) use($dashboard) { $jsonDashboard = static::isStringValidJson($dashboard); if ($jsonDashboard === null) { \histou\Debug::enable(); return \histou\Debug::errorMarkdownDashboard('#The Template given was not valid json!'); } $oldPerfData = array('host' => array(), 'service' => array(), 'command' => array()); if ($jsonDashboard && array_key_exists('rows', $jsonDashboard)) { foreach ($jsonDashboard['rows'] as &$row) { if (array_key_exists('panels', $row)) { foreach ($row['panels'] as &$panel) { // remove PanelTitel if needed if (\histou\Basic::$disablePanelTitle) { $panel['title'] = ''; } // get old Perfdata if (array_key_exists('targets', $panel)) { foreach ($panel['targets'] as $target) { if (array_key_exists('tags', $target)) { foreach ($target['tags'] as $tag) { $key = $tag['key']; if (array_key_exists($key, $oldPerfData)) { array_push($oldPerfData[$key], $tag['value']); } } } } } } } } } $dashboard = json_encode($jsonDashboard); foreach ($oldPerfData as $label => $value) { if (sizeof($value) > 0) { $counted = array_count_values($value); $oldPerfData[$label] = array_search(max($counted), $counted); } } //Test if hostname != service != command if so replace them $perfDataSize = sizeof($oldPerfData); $perfDataKeys = array_keys($oldPerfData); $replaced = false; for ($i = 0; $i < $perfDataSize; $i++) { if ($oldPerfData[$perfDataKeys[$i]] != $oldPerfData[$perfDataKeys[($i + 1) % $perfDataSize]] && $oldPerfData[$perfDataKeys[$i]] != $oldPerfData[$perfDataKeys[($i + 2) % $perfDataSize]] && array_key_exists($perfDataKeys[$i], $oldPerfData) && array_key_exists($perfDataKeys[$i], $perfData) && $oldPerfData[$perfDataKeys[$i]] != $perfData[$perfDataKeys[$i]]) { $dashboard = str_replace($oldPerfData[$perfDataKeys[$i]], $perfData[$perfDataKeys[$i]], $dashboard); $replaced = true; } } if (!$replaced) { \histou\Debug::add('# Nothing replace because hostname, service, command are equal in the template'); } return $dashboard; }; return array($rule, $genTemplate); }