mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Refactor alert templates to use Laravel Blade templating engine (#8803)
* Initial start on new templating support * further updates * more updates * More working version * Last fixes * Small updates * modified test to look for dbname. * Schema update * Added fix for not being able to disable Philips Hue transport * Updated sql file * Updated db_schema * Set myclabs/deep-copy to be 1.7.x version in composer * Fixes from murrant * Forced nikic/php-parser to version 3.1.x in composer * Updated composer to use custom fork of string-blade-compiler + fixed transport use * Updated to always use correct template * Merged legacy and blade templating engines * Removed template type + fixed test-alert.php * Added more template placeholders * Added ability to reference data in templates as $alert->X * Updated docs for templates * Updated db_schema.yaml * Added $alert->builder * Clarify the use of $alert->builder * Fixed the use of $alert->transport * renamed schema file * Added template validation * Small update to fix travis issue * Add Docs text to title bar * Updated amqp to new of version * Consistency in alert rule and template title bars
This commit is contained in:
37
LibreNMS/Alert/AlertData.php
Normal file
37
LibreNMS/Alert/AlertData.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* Template.php
|
||||
*
|
||||
* Base Template class
|
||||
*
|
||||
* 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2018 Tony Murray
|
||||
* @author Tony Murray <murraytony@gmail.com>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert;
|
||||
|
||||
class AlertData extends \Illuminate\Support\Collection
|
||||
{
|
||||
public function __get($name)
|
||||
{
|
||||
if ($this->has($name)) {
|
||||
return $this->get($name);
|
||||
}
|
||||
return "$name is not a valid \$alert data name";
|
||||
}
|
||||
}
|
213
LibreNMS/Alert/Template.php
Normal file
213
LibreNMS/Alert/Template.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
/**
|
||||
* Template.php
|
||||
*
|
||||
* Base Template class
|
||||
*
|
||||
* 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2018 Neil Lathwood
|
||||
* @author Neil Lathwood <gh+n@laf.io>
|
||||
*/
|
||||
|
||||
namespace LibreNMS\Alert;
|
||||
|
||||
use App\Models\AlertTemplate;
|
||||
|
||||
class Template
|
||||
{
|
||||
public $template;
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the template details
|
||||
*
|
||||
* @param null $obj
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTemplate($obj = null)
|
||||
{
|
||||
if ($this->template) {
|
||||
// Return the cached template information.
|
||||
return $this->template;
|
||||
}
|
||||
$this->template = AlertTemplate::whereHas('map', function ($query) use ($obj) {
|
||||
$query->where('alert_rule_id', '=', $obj['rule_id']);
|
||||
})->first();
|
||||
if (!$this->template) {
|
||||
$this->template = AlertTemplate::where('name', '=', 'Default Alert Template')->first();
|
||||
}
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
public function getTitle($data)
|
||||
{
|
||||
$data['parsed_title'] = $this->bladeTitle($data);
|
||||
return $this->legacyTitle($data);
|
||||
}
|
||||
|
||||
public function getBody($data)
|
||||
{
|
||||
$data['template']['parsed_template'] = $this->bladeBody($data);
|
||||
return $this->legacyBody($data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse Blade body
|
||||
*
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function bladeBody($data)
|
||||
{
|
||||
$alert['alert'] = new AlertData($data['alert']);
|
||||
try {
|
||||
return view(['template' => $data['template']->template], $alert)->__toString();
|
||||
} catch (\Exception $e) {
|
||||
return view(['template' => $this->getDefaultTemplate($data)], $alert)->__toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse Blade title
|
||||
*
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
public function bladeTitle($data)
|
||||
{
|
||||
$alert['alert'] = new AlertData($data['alert']);
|
||||
try {
|
||||
return view(['template' => $data['title']], $alert)->__toString();
|
||||
} catch (\Exception $e) {
|
||||
return $data['title'] ?: view(['template' => "Template " . $data['name']], $alert)->__toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse legacy body
|
||||
*
|
||||
* @param $data
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function legacyBody($data)
|
||||
{
|
||||
$tpl = $data['template']->parsed_template;
|
||||
$msg = '$ret .= "'.str_replace(array('{else}', '{/if}', '{/foreach}'), array('"; } else { $ret .= "', '"; } $ret .= "', '"; } $ret .= "'), addslashes($tpl)).'";';
|
||||
$parsed = $msg;
|
||||
$s = strlen($msg);
|
||||
$x = $pos = -1;
|
||||
$buff = '';
|
||||
$if = $for = $calc = false;
|
||||
while (++$x < $s) {
|
||||
if ($msg[$x] == '{' && $buff == '') {
|
||||
$buff .= $msg[$x];
|
||||
} elseif ($buff == '{ ') {
|
||||
$buff = '';
|
||||
} elseif ($buff != '') {
|
||||
$buff .= $msg[$x];
|
||||
}
|
||||
|
||||
if ($buff == '{if') {
|
||||
$pos = $x;
|
||||
$if = true;
|
||||
} elseif ($buff == '{foreach') {
|
||||
$pos = $x;
|
||||
$for = true;
|
||||
} elseif ($buff == '{calc') {
|
||||
$pos = $x;
|
||||
$calc = true;
|
||||
}
|
||||
|
||||
if ($pos != -1 && $msg[$x] == '}') {
|
||||
$orig = $buff;
|
||||
$buff = '';
|
||||
$pos = -1;
|
||||
if ($if) {
|
||||
$if = false;
|
||||
$o = 3;
|
||||
$native = array(
|
||||
'"; if( ',
|
||||
' ) { $ret .= "',
|
||||
);
|
||||
} elseif ($for) {
|
||||
$for = false;
|
||||
$o = 8;
|
||||
$native = array(
|
||||
'"; foreach( ',
|
||||
' as $key=>$value) { $ret .= "',
|
||||
);
|
||||
} elseif ($calc) {
|
||||
$calc = false;
|
||||
$o = 5;
|
||||
$native = array(
|
||||
'"; $ret .= (float) (0+(',
|
||||
')); $ret .= "',
|
||||
);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cond = trim(populate(substr($orig, $o, -1), false));
|
||||
$native = $native[0].$cond.$native[1];
|
||||
$parsed = str_replace($orig, $native, $parsed);
|
||||
unset($cond, $o, $orig, $native);
|
||||
}//end if
|
||||
}//end while
|
||||
$parsed = populate($parsed);
|
||||
return RunJail($parsed, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse legacy title
|
||||
*
|
||||
* @param $data
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function legacyTitle($data)
|
||||
{
|
||||
if (strstr($data['parsed_title'], '%')) {
|
||||
return RunJail('$ret = "'.populate(addslashes($data['parsed_title'])).'";', $data);
|
||||
} else {
|
||||
return $data['parsed_title'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the default template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultTemplate()
|
||||
{
|
||||
return '{{ $title }}' . PHP_EOL .
|
||||
'Severity: {{ $severity }}' . PHP_EOL .
|
||||
'@if ($state == 0)Time elapsed: {{ $elapsed }} @endif ' . PHP_EOL .
|
||||
'Timestamp: {{ $timestamp }}' . PHP_EOL .
|
||||
'Unique-ID: {{ $uid }}' . PHP_EOL .
|
||||
'Rule: @if ($name) {{ $name }} @else {{ $rule }} @endif ' . PHP_EOL .
|
||||
'@if ($faults)Faults:' . PHP_EOL .
|
||||
'@foreach ($faults as $key => $value)' . PHP_EOL .
|
||||
' #{{ $key }}: {{ $value[\'string\'] }} @endforeach' . PHP_EOL .
|
||||
'@endif' . PHP_EOL .
|
||||
'Alert sent to: @foreach ($contacts as $key => $value) {{ $value }} <{{ $key }}> @endforeach';
|
||||
}
|
||||
}
|
@@ -27,7 +27,7 @@
|
||||
|
||||
use LibreNMS\Util\FileLock;
|
||||
|
||||
$init_modules = array('alerts');
|
||||
$init_modules = ['alerts', 'alerts-cli'];
|
||||
require __DIR__ . '/includes/init.php';
|
||||
|
||||
$options = getopt('d::');
|
||||
|
38
app/Models/AlertTemplate.php
Normal file
38
app/Models/AlertTemplate.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* app/Models/AlertTemplate.php
|
||||
*
|
||||
* Model for access to alert_templates table data
|
||||
*
|
||||
* 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2018 Neil Lathwood
|
||||
* @author Neil Lathwood <gh+n@laf.io>
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class AlertTemplate extends BaseModel
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
// ---- Define Relationships ----
|
||||
|
||||
public function map()
|
||||
{
|
||||
return $this->hasMany('App\Models\AlertTemplateMap', 'alert_templates_id', 'id');
|
||||
}
|
||||
}
|
39
app/Models/AlertTemplateMap.php
Normal file
39
app/Models/AlertTemplateMap.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* app/Models/AlertTemplateMap.php
|
||||
*
|
||||
* Model for access to alert_template_map table data
|
||||
*
|
||||
* 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package LibreNMS
|
||||
* @link http://librenms.org
|
||||
* @copyright 2018 Neil Lathwood
|
||||
* @author Neil Lathwood <gh+n@laf.io>
|
||||
*/
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class AlertTemplateMap extends BaseModel
|
||||
{
|
||||
protected $table = 'alert_template_map';
|
||||
public $timestamps = false;
|
||||
|
||||
// ---- Define Relationships ----
|
||||
|
||||
public function template()
|
||||
{
|
||||
return $this->belongsTo('App\Models\AlertTemplate', 'alert_templates_id');
|
||||
}
|
||||
}
|
@@ -12,6 +12,13 @@
|
||||
"issues": "https://github.com/librenms/librenms/issues/",
|
||||
"irc": "irc://irc.freenode.org/#librenms"
|
||||
},
|
||||
"repositories":
|
||||
[
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/librenms/StringBladeCompiler"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.4",
|
||||
"ext-mysqli": "*",
|
||||
@@ -37,13 +44,15 @@
|
||||
"influxdb/influxdb-php": "^1.14",
|
||||
"laravel/laravel": "5.4.*",
|
||||
"oriceon/toastr-5-laravel": "dev-master",
|
||||
|
||||
"doctrine/inflector": "1.1.*",
|
||||
"symfony/event-dispatcher": "3.*",
|
||||
"symfony/css-selector": "3.*",
|
||||
"doctrine/instantiator": "1.0.*",
|
||||
"phpdocumentor/reflection-docblock": "3.*",
|
||||
"phpunit/php-token-stream": "1.*"
|
||||
"phpunit/php-token-stream": "1.*",
|
||||
"wpb/string-blade-compiler": "3.4.x-dev",
|
||||
"myclabs/deep-copy": "1.7.*",
|
||||
"nikic/php-parser": "v3.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"squizlabs/php_codesniffer": "^2.9.1",
|
||||
|
309
composer.lock
generated
309
composer.lock
generated
@@ -4,20 +4,20 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "cbaf71886db021d5c8e7e2a04c06361a",
|
||||
"content-hash": "1ec95b9b21153d67687370be2181ea01",
|
||||
"packages": [
|
||||
{
|
||||
"name": "amenadiel/jpgraph",
|
||||
"version": "3.6.19",
|
||||
"version": "3.6.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/HuasoFoundries/jpgraph.git",
|
||||
"reference": "c9f800a00850706f3fc4b26b6055b55952eb79bc"
|
||||
"reference": "10a818bc8c1b40deb0063f0f3c3e67c23e3030b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/HuasoFoundries/jpgraph/zipball/c9f800a00850706f3fc4b26b6055b55952eb79bc",
|
||||
"reference": "c9f800a00850706f3fc4b26b6055b55952eb79bc",
|
||||
"url": "https://api.github.com/repos/HuasoFoundries/jpgraph/zipball/10a818bc8c1b40deb0063f0f3c3e67c23e3030b7",
|
||||
"reference": "10a818bc8c1b40deb0063f0f3c3e67c23e3030b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -59,7 +59,7 @@
|
||||
"jpgraph",
|
||||
"pie"
|
||||
],
|
||||
"time": "2018-05-18T17:10:05+00:00"
|
||||
"time": "2018-06-13T13:59:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dapphp/radius",
|
||||
@@ -602,31 +602,24 @@
|
||||
},
|
||||
{
|
||||
"name": "influxdb/influxdb-php",
|
||||
"version": "1.14.5",
|
||||
"version": "1.14.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/influxdata/influxdb-php.git",
|
||||
"reference": "64c79de3f3e0e7f8c20b5fc51f50da8736767de9"
|
||||
"reference": "570bd5cdedb9b1c1628dceea5785bc40e08f7e48"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/64c79de3f3e0e7f8c20b5fc51f50da8736767de9",
|
||||
"reference": "64c79de3f3e0e7f8c20b5fc51f50da8736767de9",
|
||||
"url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/570bd5cdedb9b1c1628dceea5785bc40e08f7e48",
|
||||
"reference": "570bd5cdedb9b1c1628dceea5785bc40e08f7e48",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.0",
|
||||
"php": "^5.5 || ^7.0",
|
||||
"symfony/event-dispatcher": "^2.0 || ^3.0 || ^4.0"
|
||||
"php": "^5.5 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeclimate/php-test-reporter": "0.*",
|
||||
"symfony/config": "~2.8|~3.0|~4.0",
|
||||
"symfony/console": "~2.8|~3.0|~4.0",
|
||||
"symfony/filesystem": "~2.8|~3.0|~4.0",
|
||||
"symfony/phpunit-bridge": "^3.4 || ^4.0",
|
||||
"symfony/stopwatch": "~2.8|~3.0|~4.0",
|
||||
"symfony/yaml": "~2.8|~3.0|~4.0"
|
||||
"phpunit/phpunit": "^5.7"
|
||||
},
|
||||
"suggest": {
|
||||
"stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP."
|
||||
@@ -665,7 +658,7 @@
|
||||
"influxdb library",
|
||||
"time series"
|
||||
],
|
||||
"time": "2018-01-03T13:09:43+00:00"
|
||||
"time": "2018-07-06T10:13:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jakub-onderka/php-console-color",
|
||||
@@ -1197,17 +1190,62 @@
|
||||
"time": "2017-01-23T04:29:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "1.29.2",
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "ed6aa898982f441ccc9b2acdec51490f2bc5d337"
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/ed6aa898982f441ccc9b2acdec51490f2bc5d337",
|
||||
"reference": "ed6aa898982f441ccc9b2acdec51490f2bc5d337",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
|
||||
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/collections": "^1.0",
|
||||
"doctrine/common": "^2.6",
|
||||
"phpunit/phpunit": "^4.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DeepCopy\\": "src/DeepCopy/"
|
||||
},
|
||||
"files": [
|
||||
"src/DeepCopy/deep_copy.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Create deep copies (clones) of your objects",
|
||||
"keywords": [
|
||||
"clone",
|
||||
"copy",
|
||||
"duplicate",
|
||||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"time": "2017-10-19T19:58:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "1.32.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "64563e2b9f69e4db1b82a60e81efa327a30ff343"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/64563e2b9f69e4db1b82a60e81efa327a30ff343",
|
||||
"reference": "64563e2b9f69e4db1b82a60e81efa327a30ff343",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1219,6 +1257,13 @@
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Carbon\\Laravel\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"": "src/"
|
||||
@@ -1242,7 +1287,7 @@
|
||||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"time": "2018-05-29T15:23:46+00:00"
|
||||
"time": "2018-07-05T06:59:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
@@ -1400,16 +1445,16 @@
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.14",
|
||||
"version": "v2.0.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "f6ce7dd93628088e1017fb5dd73b0b9fec7df9e5"
|
||||
"reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/f6ce7dd93628088e1017fb5dd73b0b9fec7df9e5",
|
||||
"reference": "f6ce7dd93628088e1017fb5dd73b0b9fec7df9e5",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/29af24f25bab834fcbb38ad2a69fa93b867e070d",
|
||||
"reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1445,7 +1490,7 @@
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2018-06-06T17:40:22+00:00"
|
||||
"time": "2018-07-04T16:31:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pear/console_color2",
|
||||
@@ -1963,16 +2008,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psy/psysh",
|
||||
"version": "v0.9.5",
|
||||
"version": "v0.9.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bobthecow/psysh.git",
|
||||
"reference": "0951e91ac04ca28cf317f3997a0adfc319e80106"
|
||||
"reference": "4a2ce86f199d51b6e2524214dc06835e872f4fce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/0951e91ac04ca28cf317f3997a0adfc319e80106",
|
||||
"reference": "0951e91ac04ca28cf317f3997a0adfc319e80106",
|
||||
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/4a2ce86f199d51b6e2524214dc06835e872f4fce",
|
||||
"reference": "4a2ce86f199d51b6e2524214dc06835e872f4fce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2031,7 +2076,7 @@
|
||||
"interactive",
|
||||
"shell"
|
||||
],
|
||||
"time": "2018-06-02T16:39:22+00:00"
|
||||
"time": "2018-06-10T17:57:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
@@ -2265,16 +2310,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27"
|
||||
"reference": "1b97071a26d028c9bd4588264e101e14f6e7cd00"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/36f83f642443c46f3cf751d4d2ee5d047d757a27",
|
||||
"reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/1b97071a26d028c9bd4588264e101e14f6e7cd00",
|
||||
"reference": "1b97071a26d028c9bd4588264e101e14f6e7cd00",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2330,11 +2375,11 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-05-16T08:49:21+00:00"
|
||||
"time": "2018-05-23T05:02:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
@@ -2387,16 +2432,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "b28fd73fefbac341f673f5efd707d539d6a19f68"
|
||||
"reference": "47e6788c5b151cf0cfdf3329116bf33800632d75"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/b28fd73fefbac341f673f5efd707d539d6a19f68",
|
||||
"reference": "b28fd73fefbac341f673f5efd707d539d6a19f68",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/47e6788c5b151cf0cfdf3329116bf33800632d75",
|
||||
"reference": "47e6788c5b151cf0cfdf3329116bf33800632d75",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2439,11 +2484,11 @@
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-05-16T14:03:39+00:00"
|
||||
"time": "2018-06-25T11:10:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dotenv",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dotenv.git",
|
||||
@@ -2500,7 +2545,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
@@ -2563,16 +2608,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "472a92f3df8b247b49ae364275fb32943b9656c6"
|
||||
"reference": "3a8c3de91d2b2c68cd2d665cf9d00f7ef9eaa394"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/472a92f3df8b247b49ae364275fb32943b9656c6",
|
||||
"reference": "472a92f3df8b247b49ae364275fb32943b9656c6",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/3a8c3de91d2b2c68cd2d665cf9d00f7ef9eaa394",
|
||||
"reference": "3a8c3de91d2b2c68cd2d665cf9d00f7ef9eaa394",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2608,20 +2653,20 @@
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-05-16T08:49:21+00:00"
|
||||
"time": "2018-06-19T20:52:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "a7b5fc605d1c215cea1122359044b1e682eb70c0"
|
||||
"reference": "1c28679fcbb0d9b35e4fd49fbb74d2ca4ea17bce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/a7b5fc605d1c215cea1122359044b1e682eb70c0",
|
||||
"reference": "a7b5fc605d1c215cea1122359044b1e682eb70c0",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/1c28679fcbb0d9b35e4fd49fbb74d2ca4ea17bce",
|
||||
"reference": "1c28679fcbb0d9b35e4fd49fbb74d2ca4ea17bce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2662,20 +2707,20 @@
|
||||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-05-25T11:07:31+00:00"
|
||||
"time": "2018-06-21T11:10:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "3dac45df55ee0c5134c457a730cd68e2a2ce0445"
|
||||
"reference": "cb7edcdc47cab3c61c891e6e55337f8dd470d820"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/3dac45df55ee0c5134c457a730cd68e2a2ce0445",
|
||||
"reference": "3dac45df55ee0c5134c457a730cd68e2a2ce0445",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/cb7edcdc47cab3c61c891e6e55337f8dd470d820",
|
||||
"reference": "cb7edcdc47cab3c61c891e6e55337f8dd470d820",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2683,7 +2728,7 @@
|
||||
"psr/log": "~1.0",
|
||||
"symfony/debug": "~2.8|~3.0|~4.0",
|
||||
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
|
||||
"symfony/http-foundation": "^3.4.4|^4.0.4",
|
||||
"symfony/http-foundation": "~3.4.12|~4.0.12|^4.1.1",
|
||||
"symfony/polyfill-ctype": "~1.8"
|
||||
},
|
||||
"conflict": {
|
||||
@@ -2751,7 +2796,7 @@
|
||||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-05-25T13:16:28+00:00"
|
||||
"time": "2018-06-25T12:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -2928,16 +2973,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "4cbf2db9abcb01486a21b7a059e03a62fae63187"
|
||||
"reference": "acc5a37c706ace827962851b69705b24e71ca17c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/4cbf2db9abcb01486a21b7a059e03a62fae63187",
|
||||
"reference": "4cbf2db9abcb01486a21b7a059e03a62fae63187",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/acc5a37c706ace827962851b69705b24e71ca17c",
|
||||
"reference": "acc5a37c706ace827962851b69705b24e71ca17c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2973,7 +3018,7 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-05-16T08:49:21+00:00"
|
||||
"time": "2018-05-30T04:24:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
@@ -3116,16 +3161,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "0e6545672d8c9ce70dd472adc2f8b03155a46f73"
|
||||
"reference": "e173954a28a44a32c690815fbe4d0f2eac43accb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e6545672d8c9ce70dd472adc2f8b03155a46f73",
|
||||
"reference": "0e6545672d8c9ce70dd472adc2f8b03155a46f73",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/e173954a28a44a32c690815fbe4d0f2eac43accb",
|
||||
"reference": "e173954a28a44a32c690815fbe4d0f2eac43accb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3181,11 +3226,11 @@
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2018-04-26T12:42:15+00:00"
|
||||
"time": "2018-06-15T07:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.8.41",
|
||||
"version": "v2.8.42",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
@@ -3344,28 +3389,28 @@
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
"version": "v2.4.0",
|
||||
"version": "v2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||
"reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c"
|
||||
"reference": "6ae3e2e6494bb5e58c2decadafc3de7f1453f70a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
|
||||
"reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/6ae3e2e6494bb5e58c2decadafc3de7f1453f70a",
|
||||
"reference": "6ae3e2e6494bb5e58c2decadafc3de7f1453f70a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.0"
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
"dev-master": "2.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -3375,7 +3420,7 @@
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause-Attribution"
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
@@ -3390,7 +3435,7 @@
|
||||
"env",
|
||||
"environment"
|
||||
],
|
||||
"time": "2016-09-01T10:05:43+00:00"
|
||||
"time": "2018-07-01T10:25:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
@@ -3442,6 +3487,50 @@
|
||||
],
|
||||
"time": "2018-01-29T19:49:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "wpb/string-blade-compiler",
|
||||
"version": "3.4.x-dev",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/librenms/StringBladeCompiler.git",
|
||||
"reference": "30c974a305c14f412af3a8c515b74528429c4f5f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/librenms/StringBladeCompiler/zipball/30c974a305c14f412af3a8c515b74528429c4f5f",
|
||||
"reference": "30c974a305c14f412af3a8c515b74528429c4f5f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laravel/framework": "5.4.*",
|
||||
"php": ">=5.6.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Wpb\\String_Blade_Compiler\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Terre Porter",
|
||||
"email": "tporter@webpage-builders.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Blade String Compiler, render string as blade templates",
|
||||
"keywords": [
|
||||
"blade",
|
||||
"compiler",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/librenms/StringBladeCompiler/tree/3.4"
|
||||
},
|
||||
"time": "2018-06-21T21:13:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "xjtuwangke/passwordhash",
|
||||
"version": "dev-master",
|
||||
@@ -3883,51 +3972,6 @@
|
||||
],
|
||||
"time": "2017-01-05T08:46:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
|
||||
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/collections": "^1.0",
|
||||
"doctrine/common": "^2.6",
|
||||
"phpunit/phpunit": "^4.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DeepCopy\\": "src/DeepCopy/"
|
||||
},
|
||||
"files": [
|
||||
"src/DeepCopy/deep_copy.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Create deep copies (clones) of your objects",
|
||||
"keywords": [
|
||||
"clone",
|
||||
"copy",
|
||||
"duplicate",
|
||||
"object",
|
||||
"object graph"
|
||||
],
|
||||
"time": "2017-10-19T19:58:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "1.7.6",
|
||||
@@ -4925,7 +4969,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v3.4.11",
|
||||
"version": "v3.4.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/class-loader.git",
|
||||
@@ -5029,7 +5073,8 @@
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"xjtuwangke/passwordhash": 20,
|
||||
"oriceon/toastr-5-laravel": 20
|
||||
"oriceon/toastr-5-laravel": 20,
|
||||
"wpb/string-blade-compiler": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
|
@@ -161,7 +161,7 @@ return [
|
||||
Illuminate\Session\SessionServiceProvider::class,
|
||||
Illuminate\Translation\TranslationServiceProvider::class,
|
||||
Illuminate\Validation\ValidationServiceProvider::class,
|
||||
Illuminate\View\ViewServiceProvider::class,
|
||||
Wpb\String_Blade_Compiler\ViewServiceProvider::class,
|
||||
|
||||
/*
|
||||
* Package Service Providers...
|
||||
@@ -182,7 +182,6 @@ return [
|
||||
* Vendor Service Providers...
|
||||
*/
|
||||
Kamaln7\Toastr\ToastrServiceProvider::class,
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|
266
doc/Alerting/Old_Templates.md
Normal file
266
doc/Alerting/Old_Templates.md
Normal file
@@ -0,0 +1,266 @@
|
||||
source: Alerting/Templates.md
|
||||
|
||||
# Templates
|
||||
|
||||
Templates can be assigned to a single or a group of rules and can contain any kind of text. There is also a default template which is used for any rule that isn't associated with a template. This template can be found under `Alert Templates` page and can be edited. It also has an option revert it back to its default content.
|
||||
|
||||
The template-parser understands `if` and `foreach` controls and replaces certain placeholders with information gathered about the alert.
|
||||
|
||||
## Syntax
|
||||
|
||||
Controls:
|
||||
|
||||
- if-else (Else can be omitted):
|
||||
`{if %placeholder == value}Some Text{else}Other Text{/if}`
|
||||
- foreach-loop:
|
||||
`{foreach %faults}Key: %key<br/>Value: %value{/foreach}`
|
||||
|
||||
Placeholders:
|
||||
|
||||
Placeholders are special variables that if used within the template will be replaced with the relevant data, I.e:
|
||||
|
||||
`The device %hostname has been up for %uptime seconds` would result in the following `The device localhost has been up for 30344 seconds`.
|
||||
|
||||
- Device ID: `%device_id`
|
||||
- Hostname of the Device: `%hostname`
|
||||
- sysName of the Device: `%sysName`
|
||||
- sysDescr of the Device: `%sysDescr`
|
||||
- hardware of the Device: `%hardware`
|
||||
- Software version of the Device: `%version`
|
||||
- location of the Device: `%location`
|
||||
- uptime of the Device (in seconds): `%uptime`
|
||||
- short uptime of the Device (28d 22h 30m 7s): `%uptime_short`
|
||||
- long uptime of the Device (28 days, 22h 30m 7s): `%uptime_long`
|
||||
- description (purpose db field) of the Device: `%description`
|
||||
- notes of the Device: `%notes`
|
||||
- notes of the alert: `%alert_notes`
|
||||
- ping timestamp (if icmp enabled): `%ping_timestamp`
|
||||
- ping loss (if icmp enabled): `%ping_loss`
|
||||
- ping min (if icmp enabled): `%ping_min`
|
||||
- ping max (if icmp enabled): `%ping_max`
|
||||
- ping avg (if icmp enabled): `%ping_avg`
|
||||
- Title for the Alert: `%title`
|
||||
- Time Elapsed, Only available on recovery (`%state == 0`): `%elapsed`
|
||||
- Alert-ID: `%id`
|
||||
- Unique-ID: `%uid`
|
||||
- Faults, Only available on alert (`%state != 0`), must be iterated in a foreach (`{foreach %faults}`). Holds all available information about the Fault, accessible in the format `%value.Column`, for example: `%value.ifDescr`. Special field `%value.string` has most Identification-information (IDs, Names, Descrs) as single string, this is the equivalent of the default used.
|
||||
- State: `%state`
|
||||
- Severity: `%severity`
|
||||
- Rule: `%rule`
|
||||
- Rule-Name: `%name`
|
||||
- Timestamp: `%timestamp`
|
||||
- Transport name: `%transport`
|
||||
|
||||
- Contacts, must be iterated in a foreach, `%key` holds email and `%value` holds name: `%contacts`
|
||||
|
||||
Placeholders can be used within the subjects for templates as well although %faults is most likely going to be worthless.
|
||||
|
||||
> NOTE: Placeholder names which are contained within another need to be ordered correctly. As an example:
|
||||
|
||||
```text
|
||||
Limit: %value.sensor_limit / %value.sensor_limit_low
|
||||
```
|
||||
|
||||
Should be done as:
|
||||
|
||||
```text
|
||||
Limit: %value.sensor_limit_low / %value.sensor_limit
|
||||
```
|
||||
|
||||
The Default Template is a 'one-size-fit-all'. We highly recommend defining your own templates for your rules to include more specific information.
|
||||
|
||||
## Examples
|
||||
|
||||
Default Template:
|
||||
```text
|
||||
%title
|
||||
Severity: %severity
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Unique-ID: %uid
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{if %faults}Faults:
|
||||
{foreach %faults} #%key: %value.string{/foreach}{/if}
|
||||
Alert sent to: {foreach %contacts}%value <%key> {/foreach}
|
||||
```
|
||||
Ports Utilization Template:
|
||||
```text
|
||||
%title
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{foreach %faults}
|
||||
Physical Interface: %value.ifDescr
|
||||
Interface Description: %value.ifAlias
|
||||
Interface Speed: {calc (%value.ifSpeed/1000000000)} Gbs
|
||||
Inbound Utilization: {calc ((%value.ifInOctets_rate*8)/%value.ifSpeed)*100}%
|
||||
Outbound Utilization: {calc ((%value.ifOutOctets_rate*8)/%value.ifSpeed)*100}%
|
||||
{/foreach}
|
||||
```
|
||||
|
||||
Storage:
|
||||
```text
|
||||
|
||||
%title
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Location: %location
|
||||
Description: %description
|
||||
Features: %features
|
||||
Purpose: %purpose
|
||||
Notes: %notes
|
||||
|
||||
Server: %sysName {foreach %faults}Mount Point: %value.storage_descr Percent Utilized: %value.storage_perc{/foreach}
|
||||
```
|
||||
|
||||
Temperature Sensors:
|
||||
```text
|
||||
|
||||
%title
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Timestamp: %timestamp
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Location: %location
|
||||
Description: %description
|
||||
Features: %features
|
||||
Purpose: %purpose
|
||||
Notes: %notes
|
||||
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{if %faults}Faults:
|
||||
{foreach %faults}
|
||||
#%key: Temperature: %value.sensor_current°C
|
||||
** {calc(%value.sensor_current-%value.sensor_limit)}°C over limit
|
||||
Previous Measurement: %value.sensor_prev°C
|
||||
High Temperature Limit: %value.sensor_limit°C
|
||||
{/foreach}
|
||||
{/if}
|
||||
```
|
||||
|
||||
Value Sensors:
|
||||
```text
|
||||
|
||||
%title
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Timestamp: %timestamp
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Location: %location
|
||||
Description: %description
|
||||
Features: %features
|
||||
Purpose: %purpose
|
||||
Notes: %notes
|
||||
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{if %faults}Faults:
|
||||
{foreach %faults}
|
||||
#%key: Sensor%value.sensor_current
|
||||
** {calc(%value.sensor_current-%value.sensor_limit)}over limit
|
||||
Previous Measurement: %value.sensor_prev
|
||||
Limit: %value.sensor_limit
|
||||
{/foreach}
|
||||
{/if}
|
||||
```
|
||||
|
||||
Memory Alert:
|
||||
```text
|
||||
%title
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Location: %location
|
||||
Description: %description
|
||||
Notes: %notes
|
||||
|
||||
Server: %hostname {foreach %faults}
|
||||
Memory Description: %value.mempool_descr
|
||||
Percent Utilized: %value.mempool_perc{/foreach}
|
||||
```
|
||||
|
||||
|
||||
Conditional formatting example, will display a link to the host in email or just the hostname in any other transport:
|
||||
```text
|
||||
{if %transport == mail}<a href="https://my.librenms.install/device/device=%hostname/">%hostname</a>
|
||||
{else}
|
||||
%hostname
|
||||
{/if}
|
||||
```
|
||||
|
||||
Note the use of double-quotes. Single quotes (`'`) in templates will be escaped (replaced with `\'`) in the output and should therefore be avoided.
|
||||
|
||||
## Examples HTML
|
||||
|
||||
Note: To use HTML emails you must set HTML email to Yes in the WebUI under Global Settings > Alerting Settings > Email transport > Use HTML emails
|
||||
|
||||
Note: To include Graphs you must enable unauthorized graphs in config.php. Allow_unauth_graphs_cidr is optional, but more secure.
|
||||
```
|
||||
$config['allow_unauth_graphs_cidr'] = array(127.0.0.1/32');
|
||||
$config['allow_unauth_graphs'] = true;
|
||||
```
|
||||
|
||||
Service Alert:
|
||||
```
|
||||
<div style="font-family:Helvetica;">
|
||||
<h2>{if %state == 1}<span style="color:red;">%severity{/if}
|
||||
{if %state == 2}<span style="color:goldenrod;">acknowledged{/if}</span>
|
||||
{if %state == 3}<span style="color:green;">recovering{/if}</span>
|
||||
{if %state == 0}<span style="color:green;">recovered{/if}</span>
|
||||
</h2>
|
||||
<b>Host:</b> %hostname<br>
|
||||
<b>Duration:</b> %elapsed<br>
|
||||
<br>
|
||||
|
||||
{if %faults}
|
||||
{foreach %faults}<b>%value.service_desc - %value.service_type</b><br>
|
||||
%value.service_message<br>
|
||||
<br>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</div>
|
||||
```
|
||||
|
||||
Processor Alert with Graph:
|
||||
```
|
||||
%title <br>
|
||||
Severity: %severity <br>
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp <br>
|
||||
Alert-ID: %id <br>
|
||||
Rule: {if %name}%name{else}%rule{/if} <br>
|
||||
{if %faults}Faults:
|
||||
{foreach %faults}
|
||||
#%key: %value.string <br>
|
||||
{/foreach}
|
||||
{if %faults}<b>Faults:</b><br>
|
||||
{foreach %faults}<img src="https://server/graph.php?device=%value.device_id&type=device_processor&width=459&height=213&lazy_w=552&from=end-72h%22/%3E<br>
|
||||
https://server/graphs/id=%value.device_id/type=device_processor/<br>
|
||||
{/foreach}
|
||||
Template: CPU alert <br>
|
||||
{/if}
|
||||
{/if}
|
||||
```
|
||||
|
||||
## Included
|
||||
|
||||
We include a few templates for you to use, these are specific to the type of alert rules you are creating. For example if you create a rule that would alert on BGP sessions then you can
|
||||
assign the BGP template to this rule to provide more information.
|
||||
|
||||
The included templates apart from the default template are:
|
||||
|
||||
- BGP Sessions
|
||||
- Ports
|
||||
- Temperature
|
@@ -2,70 +2,66 @@ source: Alerting/Templates.md
|
||||
|
||||
# Templates
|
||||
|
||||
> This page is for installs running version 1.41 or later. You can find the older docs [here](Old_Templates.md)
|
||||
|
||||
Templates can be assigned to a single or a group of rules and can contain any kind of text. There is also a default template which is used for any rule that isn't associated with a template. This template can be found under `Alert Templates` page and can be edited. It also has an option revert it back to its default content.
|
||||
|
||||
The template-parser understands `if` and `foreach` controls and replaces certain placeholders with information gathered about the alert.
|
||||
The templating engine in use is Laravel Blade. We will cover some of the basics here, however the official Laravel docs will have more information [here](https://laravel.com/docs/5.4/blade)
|
||||
|
||||
## Syntax
|
||||
|
||||
Controls:
|
||||
|
||||
- if-else (Else can be omitted):
|
||||
`{if %placeholder == value}Some Text{else}Other Text{/if}`
|
||||
`@if ($alert->placeholder == 'value') Some Text @else Other Text @endif`
|
||||
- foreach-loop:
|
||||
`{foreach %faults}Key: %key<br/>Value: %value{/foreach}`
|
||||
`@foreach ($alert->faults as $key => $value) Key: $key<br/>Value: $value @endforeach`
|
||||
|
||||
Placeholders:
|
||||
|
||||
Placeholders are special variables that if used within the template will be replaced with the relevant data, I.e:
|
||||
|
||||
`The device %hostname has been up for %uptime seconds` would result in the following `The device localhost has been up for 30344 seconds`.
|
||||
`The device {{ $alert->hostname }} has been up for {{ $alert->uptime }} seconds` would result in the following `The device localhost has been up for 30344 seconds`.
|
||||
|
||||
- Device ID: `%device_id`
|
||||
- Hostname of the Device: `%hostname`
|
||||
- sysName of the Device: `%sysName`
|
||||
- sysDescr of the Device: `%sysDescr`
|
||||
- hardware of the Device: `%hardware`
|
||||
- Software version of the Device: `%version`
|
||||
- location of the Device: `%location`
|
||||
- uptime of the Device (in seconds): `%uptime`
|
||||
- short uptime of the Device (28d 22h 30m 7s): `%uptime_short`
|
||||
- long uptime of the Device (28 days, 22h 30m 7s): `%uptime_long`
|
||||
- description (purpose db field) of the Device: `%description`
|
||||
- notes of the Device: `%notes`
|
||||
- notes of the alert: `%alert_notes`
|
||||
- ping timestamp (if icmp enabled): `%ping_timestamp`
|
||||
- ping loss (if icmp enabled): `%ping_loss`
|
||||
- ping min (if icmp enabled): `%ping_min`
|
||||
- ping max (if icmp enabled): `%ping_max`
|
||||
- ping avg (if icmp enabled): `%ping_avg`
|
||||
- Title for the Alert: `%title`
|
||||
- Time Elapsed, Only available on recovery (`%state == 0`): `%elapsed`
|
||||
- Alert-ID: `%id`
|
||||
- Unique-ID: `%uid`
|
||||
- Faults, Only available on alert (`%state != 0`), must be iterated in a foreach (`{foreach %faults}`). Holds all available information about the Fault, accessible in the format `%value.Column`, for example: `%value.ifDescr`. Special field `%value.string` has most Identification-information (IDs, Names, Descrs) as single string, this is the equivalent of the default used.
|
||||
- State: `%state`
|
||||
- Severity: `%severity`
|
||||
- Rule: `%rule`
|
||||
- Rule-Name: `%name`
|
||||
- Timestamp: `%timestamp`
|
||||
- Transport name: `%transport`
|
||||
> When using placeholders to echo data, you need to wrap the placeholder in `{{ }}`. I.e `{{ $alert->hostname }}`.
|
||||
|
||||
- Contacts, must be iterated in a foreach, `%key` holds email and `%value` holds name: `%contacts`
|
||||
- Device ID: `$alert->device_id`
|
||||
- Hostname of the Device: `$alert->hostname`
|
||||
- sysName of the Device: `$alert->sysName`
|
||||
- sysDescr of the Device: `$alert->sysDescr`
|
||||
- sysContact of the Device: `$alert->sysContact`
|
||||
- OS of the Device: `$alert->os`
|
||||
- Type of Device: `$alert->type`
|
||||
- IP of the Device: `$alert->ip`
|
||||
- hardware of the Device: `$alert->hardware`
|
||||
- Software version of the Device: `$alert->version`
|
||||
- location of the Device: `$alert->location`
|
||||
- uptime of the Device (in seconds): `$alert->uptime`
|
||||
- short uptime of the Device (28d 22h 30m 7s): `$alert->uptime_short`
|
||||
- long uptime of the Device (28 days, 22h 30m 7s): `$alert->uptime_long`
|
||||
- description (purpose db field) of the Device: `$alert->description`
|
||||
- notes of the Device: `$alert->notes`
|
||||
- notes of the alert: `$alert->alert_notes`
|
||||
- ping timestamp (if icmp enabled): `$alert->ping_timestamp`
|
||||
- ping loss (if icmp enabled): `$alert->ping_loss`
|
||||
- ping min (if icmp enabled): `$alert->ping_min`
|
||||
- ping max (if icmp enabled): `$alert->ping_max`
|
||||
- ping avg (if icmp enabled): `$alert->ping_avg`
|
||||
- Title for the Alert: `$alert->title`
|
||||
- Time Elapsed, Only available on recovery (`$alert->state == 0`): `$alert->elapsed`
|
||||
- Rule Builder (the actual rule) (use `{!! $alert->builder !!}`): `$alert->builder`
|
||||
- Alert-ID: `$alert->id`
|
||||
- Unique-ID: `$alert->uid`
|
||||
- Faults, Only available on alert (`$alert->state != 0`), must be iterated in a foreach (`@foreach ($alert->faults as $key => $value) @endforeach`). Holds all available information about the Fault, accessible in the format `$value['Column']`, for example: `$value['ifDescr']`. Special field `$value['string']` has most Identification-information (IDs, Names, Descrs) as single string, this is the equivalent of the default used.
|
||||
- State: `$alert->state`
|
||||
- Severity: `$alert->severity`
|
||||
- Rule: `$alert->rule`
|
||||
- Rule-Name: `$alert->name`
|
||||
- Timestamp: `$alert->timestamp`
|
||||
- Transport name: `$alert->transport`
|
||||
- Contacts, must be iterated in a foreach, `$key` holds email and `$value` holds name: `$alert->contacts`
|
||||
|
||||
Placeholders can be used within the subjects for templates as well although %faults is most likely going to be worthless.
|
||||
|
||||
> NOTE: Placeholder names which are contained within another need to be ordered correctly. As an example:
|
||||
|
||||
```text
|
||||
Limit: %value.sensor_limit / %value.sensor_limit_low
|
||||
```
|
||||
|
||||
Should be done as:
|
||||
|
||||
```text
|
||||
Limit: %value.sensor_limit_low / %value.sensor_limit
|
||||
```
|
||||
Placeholders can be used within the subjects for templates as well although $faults is most likely going to be worthless.
|
||||
|
||||
The Default Template is a 'one-size-fit-all'. We highly recommend defining your own templates for your rules to include more specific information.
|
||||
|
||||
@@ -73,135 +69,138 @@ The Default Template is a 'one-size-fit-all'. We highly recommend defining your
|
||||
|
||||
Default Template:
|
||||
```text
|
||||
%title
|
||||
Severity: %severity
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Unique-ID: %uid
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{if %faults}Faults:
|
||||
{foreach %faults} #%key: %value.string{/foreach}{/if}
|
||||
Alert sent to: {foreach %contacts}%value <%key> {/foreach}
|
||||
{{ $alert->title }}
|
||||
Severity: {{ $alert->severity }}
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Timestamp: {{ $alert->timestamp }}
|
||||
Unique-ID: {{ $alert->uid }}
|
||||
Rule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif
|
||||
@if ($alert->faults) Faults:
|
||||
@foreach ($alert->faults as $key => $value)
|
||||
#{{ $key }}: {{ $value['string'] }}
|
||||
@endforeach
|
||||
@endif
|
||||
Alert sent to:
|
||||
@foreach ($alert->contacts as $key => $value)
|
||||
{{ $value }} <{{ $key }}>
|
||||
@endforeach
|
||||
```
|
||||
Ports Utilization Template:
|
||||
```text
|
||||
%title
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{foreach %faults}
|
||||
Physical Interface: %value.ifDescr
|
||||
Interface Description: %value.ifAlias
|
||||
Interface Speed: {calc (%value.ifSpeed/1000000000)} Gbs
|
||||
Inbound Utilization: {calc ((%value.ifInOctets_rate*8)/%value.ifSpeed)*100}%
|
||||
Outbound Utilization: {calc ((%value.ifOutOctets_rate*8)/%value.ifSpeed)*100}%
|
||||
{/foreach}
|
||||
{{ $alert->title }}
|
||||
Device Name: {{ $alert->hostname }}
|
||||
Severity: {{ $alert->severity }}
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Timestamp: {{ $alert->timestamp }}
|
||||
Rule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif
|
||||
@foreach ($alert->faults as $key => $value)
|
||||
Physical Interface: $value['ifDescr']
|
||||
Interface Description: $value['ifAlias']
|
||||
Interface Speed: @php echo ($value['ifSpeed']/1000000000); @endphp Gbs
|
||||
Inbound Utilization: @php echo (($value['ifInOctets_rate']*8)/$value['ifSpeed'])*100; @endphp%
|
||||
Outbound Utilization: @php echo (($value['ifOutOctets_rate']*8)/$value['ifSpeed'])*100; @endphp%
|
||||
@endforeach
|
||||
```
|
||||
|
||||
Storage:
|
||||
```text
|
||||
{{ $alert->title }}
|
||||
|
||||
%title
|
||||
Device Name: {{ $alert->hostname }}
|
||||
Severity: {{ $alert->severity }}
|
||||
Uptime: {{ $alert->uptime_short }}
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Timestamp: {{ $alert->timestamp }}
|
||||
Location: {{ $alert->location }}
|
||||
Description: {{ $alert->description }}
|
||||
Features: {{ $alert->features }}
|
||||
Purpose: {{ $alert->purpose }}
|
||||
Notes: {{ $alert->notes }}
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Location: %location
|
||||
Description: %description
|
||||
Features: %features
|
||||
Purpose: %purpose
|
||||
Notes: %notes
|
||||
|
||||
Server: %sysName {foreach %faults}Mount Point: %value.storage_descr Percent Utilized: %value.storage_perc{/foreach}
|
||||
Server: {{ $alert->sysName }} @foreach ($alert->faults as $key => $value)Mount Point: $value['storage_descr'] Percent Utilized: $value['storage_perc']@endforeach
|
||||
```
|
||||
|
||||
Temperature Sensors:
|
||||
```text
|
||||
{{ $alert->title }}
|
||||
|
||||
%title
|
||||
Device Name: {{ $alert->hostname }}
|
||||
Severity: {{ $alert->severity }}
|
||||
Timestamp: {{ $alert->timestamp }}
|
||||
Uptime: {{ $alert->uptime_short }}
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Location: {{ $alert->location }}
|
||||
Description: {{ $alert->description }}
|
||||
Features: {{ $alert->features }}
|
||||
Purpose: {{ $alert->purpose }}
|
||||
Notes: {{ $alert->notes }}
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Timestamp: %timestamp
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Location: %location
|
||||
Description: %description
|
||||
Features: %features
|
||||
Purpose: %purpose
|
||||
Notes: %notes
|
||||
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{if %faults}Faults:
|
||||
{foreach %faults}
|
||||
#%key: Temperature: %value.sensor_current°C
|
||||
** {calc(%value.sensor_current-%value.sensor_limit)}°C over limit
|
||||
Previous Measurement: %value.sensor_prev°C
|
||||
High Temperature Limit: %value.sensor_limit°C
|
||||
{/foreach}
|
||||
{/if}
|
||||
Rule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif
|
||||
@if ($alert->faults) Faults:
|
||||
@foreach ($faults as $key => $value)
|
||||
#{{ $key }}: Temperature: $value['sensor_current']°C
|
||||
** @php echo ($value['sensor_current']-$value['sensor_limit']); @endphp°C over limit
|
||||
Previous Measurement: $value['sensor_prev']°C
|
||||
High Temperature Limit: $value['sensor_limit']°C
|
||||
@endforeach
|
||||
@endif
|
||||
```
|
||||
|
||||
Value Sensors:
|
||||
```text
|
||||
{{ $alert->title }}
|
||||
|
||||
%title
|
||||
Device Name: {{ $alert->hostname }}
|
||||
Severity: {{ $alert->severity }}
|
||||
Timestamp: {{ $alert->timestamp }}
|
||||
Uptime: {{ $alert->uptime_short }}
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Location: {{ $alert->location }}
|
||||
Description: {{ $alert->description }}
|
||||
Features: {{ $alert->features }}
|
||||
Purpose: {{ $alert->purpose }}
|
||||
Notes: {{ $alert->notes }}
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Timestamp: %timestamp
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Location: %location
|
||||
Description: %description
|
||||
Features: %features
|
||||
Purpose: %purpose
|
||||
Notes: %notes
|
||||
|
||||
Rule: {if %name}%name{else}%rule{/if}
|
||||
{if %faults}Faults:
|
||||
{foreach %faults}
|
||||
#%key: Sensor%value.sensor_current
|
||||
** {calc(%value.sensor_current-%value.sensor_limit)}over limit
|
||||
Previous Measurement: %value.sensor_prev
|
||||
Limit: %value.sensor_limit
|
||||
{/foreach}
|
||||
{/if}
|
||||
Rule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif
|
||||
@if ($alert->faults) Faults:
|
||||
@foreach ($alert->faults as $key => $value)
|
||||
#{{ $key }}: Sensor {{ $value['sensor_current'] }}
|
||||
** @php echo ($value['sensor_current']-$value['sensor_limit']); @endphp over limit
|
||||
Previous Measurement: {{ $value['sensor_prev'] }}
|
||||
Limit: {{ $value['sensor_limit'] }}
|
||||
@endforeach
|
||||
@endif
|
||||
```
|
||||
|
||||
Memory Alert:
|
||||
```text
|
||||
%title
|
||||
{{ $alert->title }}
|
||||
|
||||
Device Name: %hostname
|
||||
Severity: %severity
|
||||
Uptime: %uptime_short
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp
|
||||
Location: %location
|
||||
Description: %description
|
||||
Notes: %notes
|
||||
Device Name: {{ $alert->hostname }}
|
||||
Severity: {{ $alert->severity }}
|
||||
Uptime: {{ $alert->uptime_short }}
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Timestamp: {{ $alert->timestamp }}
|
||||
Location: {{ $alert->location }}
|
||||
Description: {{ $alert->description }}
|
||||
Notes: {{ $alert->notes }}
|
||||
|
||||
Server: %hostname {foreach %faults}
|
||||
Memory Description: %value.mempool_descr
|
||||
Percent Utilized: %value.mempool_perc{/foreach}
|
||||
Server: {{ $alert->hostname }}
|
||||
@foreach ($alert->faults as $key => $value)
|
||||
Memory Description: {{ $value['mempool_descr'] }}
|
||||
Percent Utilized: {{ $value['mempool_perc'] }}
|
||||
@endforeach
|
||||
```
|
||||
|
||||
|
||||
Conditional formatting example, will display a link to the host in email or just the hostname in any other transport:
|
||||
```text
|
||||
{if %transport == mail}<a href="https://my.librenms.install/device/device=%hostname/">%hostname</a>
|
||||
{else}
|
||||
%hostname
|
||||
{/if}
|
||||
@if ($alert->transport == mail)<a href="https://my.librenms.install/device/device={{ $alert->hostname }}/">{{ $alert->hostname }}</a>
|
||||
@else
|
||||
{{ $alert->hostname }}
|
||||
@endif
|
||||
```
|
||||
|
||||
Note the use of double-quotes. Single quotes (`'`) in templates will be escaped (replaced with `\'`) in the output and should therefore be avoided.
|
||||
|
||||
## Examples HTML
|
||||
|
||||
Note: To use HTML emails you must set HTML email to Yes in the WebUI under Global Settings > Alerting Settings > Email transport > Use HTML emails
|
||||
@@ -215,43 +214,43 @@ $config['allow_unauth_graphs'] = true;
|
||||
Service Alert:
|
||||
```
|
||||
<div style="font-family:Helvetica;">
|
||||
<h2>{if %state == 1}<span style="color:red;">%severity{/if}
|
||||
{if %state == 2}<span style="color:goldenrod;">acknowledged{/if}</span>
|
||||
{if %state == 3}<span style="color:green;">recovering{/if}</span>
|
||||
{if %state == 0}<span style="color:green;">recovered{/if}</span>
|
||||
<h2>@if ($alert->state == 1) <span style="color:red;">{{ $alert->severity }} @endif
|
||||
@if ($alert->state == 2) <span style="color:goldenrod;">acknowledged @endif</span>
|
||||
@if ($alert->state == 3) <span style="color:green;">recovering @endif</span>
|
||||
@if ($alert->state == 0) <span style="color:green;">recovered @endif</span>
|
||||
</h2>
|
||||
<b>Host:</b> %hostname<br>
|
||||
<b>Duration:</b> %elapsed<br>
|
||||
<b>Host:</b> {{ $alert->hostname }}<br>
|
||||
<b>Duration:</b> {{ $alert->elapsed }}<br>
|
||||
<br>
|
||||
|
||||
{if %faults}
|
||||
{foreach %faults}<b>%value.service_desc - %value.service_type</b><br>
|
||||
%value.service_message<br>
|
||||
@if ($alert->faults)
|
||||
@foreach ($alert->faults as $key => $value)<b>$value['service_desc'] - $value['service_type']</b><br>
|
||||
$value['service_message']<br>
|
||||
<br>
|
||||
{/foreach}
|
||||
{/if}
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
```
|
||||
|
||||
Processor Alert with Graph:
|
||||
```
|
||||
%title <br>
|
||||
Severity: %severity <br>
|
||||
{if %state == 0}Time elapsed: %elapsed{/if}
|
||||
Timestamp: %timestamp <br>
|
||||
Alert-ID: %id <br>
|
||||
Rule: {if %name}%name{else}%rule{/if} <br>
|
||||
{if %faults}Faults:
|
||||
{foreach %faults}
|
||||
#%key: %value.string <br>
|
||||
{/foreach}
|
||||
{if %faults}<b>Faults:</b><br>
|
||||
{foreach %faults}<img src="https://server/graph.php?device=%value.device_id&type=device_processor&width=459&height=213&lazy_w=552&from=end-72h%22/%3E<br>
|
||||
https://server/graphs/id=%value.device_id/type=device_processor/<br>
|
||||
{/foreach}
|
||||
{{ $alert->title }} <br>
|
||||
Severity: {{ $alert->severity }} <br>
|
||||
@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif
|
||||
Timestamp: {{ $alert->timestamp }} <br>
|
||||
Alert-ID: {{ $alert->id }} <br>
|
||||
Rule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif <br>
|
||||
@if ($alert->faults) Faults:
|
||||
@foreach ($alert->faults as $key => $value)
|
||||
#{{ $key }}: {{ $value['string'] }}<br>
|
||||
@endforeach
|
||||
@if ($alert->faults) <b>Faults:</b><br>
|
||||
@foreach ($alert->faults as $key => $value)<img src="https://server/graph.php?device={{ $value['device_id'] }}&type=device_processor&width=459&height=213&lazy_w=552&from=end-72h><br>
|
||||
https://server/graphs/id={{ $value['device_id'] }}/type=device_processor/<br>
|
||||
@endforeach
|
||||
Template: CPU alert <br>
|
||||
{/if}
|
||||
{/if}
|
||||
@endif
|
||||
@endif
|
||||
```
|
||||
|
||||
## Included
|
||||
|
@@ -16,10 +16,10 @@
|
||||
|
||||
use LibreNMS\Authentication\Auth;
|
||||
|
||||
$init_modules = array('web', 'auth', 'alerts');
|
||||
$init_modules = array('web', 'auth', 'alerts', 'alerts-cli');
|
||||
require realpath(__DIR__ . '/..') . '/includes/init.php';
|
||||
|
||||
set_debug($_REQUEST['debug']);
|
||||
set_debug(isset($_REQUEST['debug']) ? $_REQUEST['debug'] : false);
|
||||
|
||||
if (!Auth::check()) {
|
||||
echo 'unauthenticated';
|
||||
|
@@ -44,8 +44,8 @@ $rule_id = $_POST['rule_id'];
|
||||
$count = mres($_POST['count']);
|
||||
$delay = mres($_POST['delay']);
|
||||
$interval = mres($_POST['interval']);
|
||||
$mute = mres($_POST['mute']);
|
||||
$invert = mres($_POST['invert']);
|
||||
$mute = mres(isset($_POST['mute']) ? $_POST['mute'] : null);
|
||||
$invert = mres(isset($_POST['invert']) ? $_POST['invert'] : null);
|
||||
$name = mres($_POST['name']);
|
||||
$proc = mres($_POST['proc']);
|
||||
$recovery = ($vars['recovery']);
|
||||
@@ -138,7 +138,7 @@ if (is_numeric($rule_id) && $rule_id > 0) {
|
||||
if (is_numeric($rule_id) && $rule_id > 0) {
|
||||
$devices = [];
|
||||
$groups = [];
|
||||
foreach ((array)$_POST['maps'] as $item) {
|
||||
foreach ((array)$vars['maps'] as $item) {
|
||||
if (starts_with($item, 'g')) {
|
||||
$groups[] = (int)substr($item, 1);
|
||||
} else {
|
||||
|
@@ -24,48 +24,50 @@
|
||||
|
||||
use LibreNMS\Authentication\Auth;
|
||||
|
||||
header('Content-type: text/plain');
|
||||
$status = 'error';
|
||||
|
||||
if (!Auth::user()->hasGlobalAdmin()) {
|
||||
die('ERROR: You need to be admin');
|
||||
header('Content-Type: application/json');
|
||||
$response = array('status' => $status, 'message' => 'You need to be admin');
|
||||
die(_json_encode($response));
|
||||
}
|
||||
|
||||
$status = 'error';
|
||||
$template_id = 0;
|
||||
|
||||
$name = mres($_POST['name']);
|
||||
if (!empty($name)) {
|
||||
if (is_numeric($_REQUEST['template_id']) && $_REQUEST['rule_id']) {
|
||||
$name = mres($vars['name']);
|
||||
if (isset($vars['template']) && empty(view(['template' => $vars['template']], [])->__toString())) {
|
||||
$message = 'Template failed to be parsed, please check the syntax';
|
||||
} elseif (!empty($name)) {
|
||||
if ((isset($vars['template_id']) && is_numeric($vars['template_id'])) && (isset($vars['rule_id']) && $vars['rule_id'])) {
|
||||
//Update the template/rule mapping
|
||||
|
||||
if (is_array($_REQUEST['rule_id'])) {
|
||||
$_REQUEST['rule_id'] = implode(",", $_REQUEST['rule_id']);
|
||||
if (is_array($vars['rule_id'])) {
|
||||
$vars['rule_id'] = implode(",", $vars['rule_id']);
|
||||
}
|
||||
if (substr($_REQUEST['rule_id'], 0, 1) != ",") {
|
||||
$_REQUEST['rule_id'] = ",".$_REQUEST['rule_id'];
|
||||
if (substr($vars['rule_id'], 0, 1) != ",") {
|
||||
$vars['rule_id'] = ",".$vars['rule_id'];
|
||||
}
|
||||
if (substr($_REQUEST['rule_id'], -1, 1) != ",") {
|
||||
$_REQUEST['rule_id'] .= ",";
|
||||
if (substr($vars['rule_id'], -1, 1) != ",") {
|
||||
$vars['rule_id'] .= ",";
|
||||
}
|
||||
if (dbUpdate(array('rule_id' => mres($_REQUEST['rule_id']), 'name' => $name), "alert_templates", "id = ?", array($_REQUEST['template_id'])) >= 0) {
|
||||
if (dbUpdate(array('rule_id' => mres($vars['rule_id']), 'name' => $name), "alert_templates", "id = ?", array($vars['template_id'])) >= 0) {
|
||||
$message = "Updated template and rule id mapping";
|
||||
} else {
|
||||
$message ="Failed to update the template and rule id mapping";
|
||||
}
|
||||
} elseif ($_REQUEST['template'] && is_numeric($_REQUEST['template_id'])) {
|
||||
} elseif ($vars['template'] && is_numeric($vars['template_id'])) {
|
||||
//Update template-text
|
||||
|
||||
if (dbUpdate(array('template' => $_REQUEST['template'], 'name' => $name, 'title' => $_REQUEST['title'], 'title_rec' => $_REQUEST['title_rec']), "alert_templates", "id = ?", array($_REQUEST['template_id'])) >= 0) {
|
||||
if (dbUpdate(array('template' => $vars['template'], 'name' => $name, 'title' => $vars['title'], 'title_rec' => $vars['title_rec']), "alert_templates", "id = ?", array($vars['template_id'])) >= 0) {
|
||||
$status = 'ok';
|
||||
$message = "Alert template updated";
|
||||
} else {
|
||||
$message = "Failed to update the template";
|
||||
}
|
||||
} elseif ($_REQUEST['template']) {
|
||||
} elseif ($vars['template']) {
|
||||
//Create new template
|
||||
|
||||
if ($name != 'Default Alert Template') {
|
||||
$template_id = dbInsert(array('template' => $_REQUEST['template'], 'name' => $name, 'title' => $_REQUEST['title'], 'title_rec' => $_REQUEST['title_rec']), "alert_templates");
|
||||
$template_id = dbInsert(array('template' => $vars['template'], 'name' => $name, 'title' => $vars['title'], 'title_rec' => $vars['title_rec']), "alert_templates");
|
||||
if ($template_id != false) {
|
||||
$status = 'ok';
|
||||
$message = "Alert template has been created.";
|
||||
@@ -84,5 +86,4 @@ if (!empty($name)) {
|
||||
|
||||
$response = array('status' => $status, 'message' => $message, 'newid' => $template_id);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo _json_encode($response);
|
||||
|
@@ -19,7 +19,7 @@ if (!Auth::user()->hasGlobalAdmin()) {
|
||||
die('ERROR: You need to be admin');
|
||||
}
|
||||
|
||||
$template_id = ($_POST['template_id']);
|
||||
$template_id = ($vars['template_id']);
|
||||
|
||||
if (is_numeric($template_id) && $template_id > 0) {
|
||||
$template = dbFetchRow('SELECT * FROM `alert_templates` WHERE `id` = ? LIMIT 1', array($template_id));
|
||||
@@ -28,6 +28,7 @@ if (is_numeric($template_id) && $template_id > 0) {
|
||||
'name' => $template['name'],
|
||||
'title' => $template['title'],
|
||||
'title_rec' => $template['title_rec'],
|
||||
'type' => $template['type'],
|
||||
);
|
||||
header('Content-type: application/json');
|
||||
echo _json_encode($output);
|
||||
|
@@ -24,75 +24,30 @@ if (!Auth::user()->hasGlobalAdmin()) {
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="Create">Alert Rules</h4>
|
||||
<h4 class="modal-title" id="Create">Alert Template :: <a href="https://docs.librenms.org/Alerting/Templates/"><i class="fa fa-book fa-1x"></i> Docs</a></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<span id="response"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="template" class="control-label">Template:</label><br />
|
||||
<div class="alert alert-danger" role="alert">You can enter text for your template directly below if you're feeling brave enough :)</div>
|
||||
<label for="name">Template name: </label>
|
||||
<input type="text" class="form-control input-sm" id="name" name="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="designer" class="control-label">Designer:</label><br />
|
||||
<div class="alert alert-warning" role="alert">The designer below will help you create a template - be warned, it's beta :)</div>
|
||||
<label for="template">Template: </label>
|
||||
<textarea class="form-control" id="template" name="template" rows="15"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" id="template" name="template" rows="15"></textarea><br /><br />
|
||||
<strong><em>Give your template a name: </em></strong><br />
|
||||
<input type="text" class="form-control input-sm" id="name" name="name"><br />
|
||||
<em>Optionally, add custom titles: </em><br />
|
||||
<input type="text" class="form-control input-sm" id="title" name="title" placeholder="Alert Title"><input type="text" class="form-control input-sm" id="title_rec" name="title_rec" placeholder="Recovery Title"><br />
|
||||
<span id="error"></span><br />
|
||||
<label for="title">Alert title: </label>
|
||||
<input type="text" class="form-control input-sm" id="title" name="title" placeholder="Alert Title">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="title_rec">Recovery title: </label>
|
||||
<input type="text" class="form-control input-sm" id="title_rec" name="title_rec" placeholder="Recovery Title">
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary btn-sm" name="create-template" id="create-template">Create template</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<span><strong>Controls:</strong><br />
|
||||
<?php
|
||||
$controls = array('if','endif','else','foreach', 'endforeach');
|
||||
foreach ($controls as $control) {
|
||||
echo ' <button type="button" class="btn btn-primary btn-sm" data-target="#control-add" id="control-add" name="control-add" data-type="control" data-value="'.$control.'">'.$control.'</button>';
|
||||
}
|
||||
?>
|
||||
</span><br /><br />
|
||||
<span><strong>Placeholders:</strong><br />
|
||||
<?php
|
||||
$placeholders = array('hostname', 'sysName', 'location', 'uptime', 'description', 'notes', 'title','elapsed','id','uid','faults','state','severity','rule','timestamp','contacts','key','value','new line');
|
||||
foreach ($placeholders as $placeholder) {
|
||||
echo ' <button type="button" class="btn btn-success btn-sm" data-target="#placeholder-add" id="placeholder-add" name="placeholder-add" data-type="placeholder" data-value="'.$placeholder.'">'.$placeholder.'</button>';
|
||||
}
|
||||
?>
|
||||
</span><br /><br />
|
||||
<span><strong>Operator:</strong><br />
|
||||
<?php
|
||||
$operators = array('==','!=','>=','>','<=','<','&&','||','blank');
|
||||
foreach ($operators as $operator) {
|
||||
echo ' <button type="button" class="btn btn-warning btn-sm" data-target="#operator-add" id="operator-add" name="operator-add" data-type="operator" data-value="'.$operator.'">'.$operator.'</button>';
|
||||
}
|
||||
?>
|
||||
<br /><br />
|
||||
<small><em>Free text - press enter to add</em></small><br />
|
||||
<input type="text" class="form-control" id="value" name="value" autocomplete="off"><br /><br />
|
||||
<input type="text" class="form-control" id="line" name="line"><br /><br />
|
||||
<input type="hidden" name="template_id" id="template_id">
|
||||
<input type="hidden" name="default_template" id="default_template" value="0">
|
||||
<button type="button" class="btn btn-primary" id="add_line" name="add_line">Add line</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -120,6 +75,9 @@ $('#alert-template').on('show.bs.modal', function (event) {
|
||||
$('#name').val(output['name']);
|
||||
$('#title').val(output['title']);
|
||||
$('#title_rec').val(output['title_rec']);
|
||||
if(output['template'].indexOf("{/if}")>=0){
|
||||
toastr.info('The old template syntax is no longer supported. Please see https://docs.librenms.org/Alerting/Old-Templates/');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -148,75 +106,6 @@ $('#create-template').click('', function(e) {
|
||||
alertTemplateAjaxOps(template, name, template_id, title, title_rec);
|
||||
});
|
||||
|
||||
$('#add_line').click('', function(e) {
|
||||
e.preventDefault();
|
||||
var line = $('#line').val();
|
||||
$('#template').append(line + '\r\n');
|
||||
$('#line').val('');
|
||||
});
|
||||
|
||||
$('button[name="control-add"],button[name="placeholder-add"],button[name="operator-add"]').click('', function(e) {
|
||||
e.preventDefault();
|
||||
var type = $(this).data("type");
|
||||
var value = $(this).data("value");
|
||||
var line = $('#line').val();
|
||||
var new_line = '';
|
||||
if(type == 'control') {
|
||||
$('button[name="control-add"]').prop('disabled',true);
|
||||
if(value == 'if') {
|
||||
new_line = '{if ';
|
||||
} else if(value == 'endif') {
|
||||
new_line = '{/if}';
|
||||
$('button[name="control-add"]').prop('disabled',false);
|
||||
} else if(value == 'else') {
|
||||
new_line = ' {else} ';
|
||||
} else if(value == 'foreach') {
|
||||
new_line = '{foreach ';
|
||||
} else if(value == 'endforeach') {
|
||||
new_line = '{/foreach} ';
|
||||
$('button[name="control-add"]').prop('disabled',false);
|
||||
}
|
||||
} else if(type == 'placeholder') {
|
||||
if($('button[name="control-add"]').prop('disabled') === true) {
|
||||
$('button[name="placeholder-add"]').prop('disabled',true);
|
||||
}
|
||||
if(value == 'new line') {
|
||||
new_line = '\\r\\n ';
|
||||
} else {
|
||||
new_line = '%'+value+' ';
|
||||
}
|
||||
if(value == 'key' || value == 'value' || value == 'new line') {
|
||||
$('button[name="placeholder-add"]').prop('disabled',false);
|
||||
}
|
||||
} else if(type == 'operator') {
|
||||
if(value == 'blank') {
|
||||
$('button[name="control-add"]').prop('disabled',false);
|
||||
$('button[name="placeholder-add"]').prop('disabled',false);
|
||||
new_line = '}';
|
||||
} else {
|
||||
$('button[name="operator-add"]').prop('disabled',true);
|
||||
new_line = value+' ';
|
||||
}
|
||||
}
|
||||
$('#line').val(line + new_line);
|
||||
$('#valuee').focus();
|
||||
});
|
||||
|
||||
$('#value').keypress(function (e) {
|
||||
if(e.which == 13) {
|
||||
updateLine($('#value').val());
|
||||
$('#value').val('');
|
||||
}
|
||||
});
|
||||
|
||||
$('div').on('click', 'button#reset-default', function(e) {
|
||||
e.preventDefault();
|
||||
var template_id = $("#template_id").val();
|
||||
var template = '%title\r\nSeverity: %severity\r\n{if %state == 0}Time elapsed: %elapsed\r\n{/if}Timestamp: %timestamp\r\nUnique-ID: %uid\r\nRule: {if %name}%name{else}%rule{/if}\r\n{if %faults}Faults:\r\n{foreach %faults} #%key: %value.string\r\n{/foreach}{/if}Alert sent to: {foreach %contacts}%value <%key> {/foreach}';
|
||||
var name = 'Default Alert Template';
|
||||
alertTemplateAjaxOps(template, name, template_id, '', '');
|
||||
});
|
||||
|
||||
function alertTemplateAjaxOps(template, name, template_id, title, title_rec)
|
||||
{
|
||||
$.ajax({
|
||||
@@ -225,6 +114,7 @@ function alertTemplateAjaxOps(template, name, template_id, title, title_rec)
|
||||
data: { type: "alert-templates", template: template, name: name, template_id: template_id, title: title, title_rec: title_rec},
|
||||
dataType: "json",
|
||||
success: function(output) {
|
||||
console.log(output);
|
||||
if(output.status == 'ok') {
|
||||
toastr.success(output.message);
|
||||
$("#alert-template").modal('hide');
|
||||
@@ -242,29 +132,14 @@ function alertTemplateAjaxOps(template, name, template_id, title, title_rec)
|
||||
$('#templatetable').bootgrid("append", newrow);
|
||||
}
|
||||
} else {
|
||||
$("#error").html('<div class="alert alert-danger">'+msg+'</div>');
|
||||
toastr.error(output.message);
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
$("#error").html('<div class="alert alert-danger">An error occurred updating this alert template.</div>');
|
||||
toastr.error('An error occurred updating this alert template.');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function updateLine(value) {
|
||||
var line = $('#line').val();
|
||||
//$('#value').prop('disabled',true);
|
||||
if($('button[name="placeholder-add"]').prop('disabled') === true) {
|
||||
value = '"'+value+'" } ';
|
||||
//$('#value').prop('disabled',false);
|
||||
} else {
|
||||
value = value + ' ';
|
||||
}
|
||||
$('#line').val(line + value);
|
||||
$('button[name="control-add"]').prop('disabled',false);
|
||||
$('button[name="placeholder-add"]').prop('disabled',false);
|
||||
$('button[name="operator-add"]').prop('disabled',false);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@@ -26,7 +26,7 @@ if (Auth::user()->hasGlobalAdmin()) {
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h5 class="modal-title" id="Create">Alert Rules :: <a href="https://docs.librenms.org/Alerting/">Docs <i class="fa fa-book fa-1x"></i></a> </h5>
|
||||
<h5 class="modal-title" id="Create">Alert Rule :: <a href="https://docs.librenms.org/Alerting/"><i class="fa fa-book fa-1x"></i> Docs</a> </h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
|
@@ -1568,6 +1568,7 @@ echo '
|
||||
<label for="hue_duration" class="col-sm-4 control-label">Philips Hue Duration</label>
|
||||
<div class="col-sm-4">
|
||||
<select id="hue_duration" class="form-control" name="global-config-select" data-config_id="'.$hue_duration['config_id'].'">
|
||||
<option '.( $hue_duration['config_value'] == "" ? "selected" : ""). ' value=""></option>
|
||||
<option '.( $hue_duration['config_value'] == "select" ? "selected" : ""). ' value="select">1 Second</option>
|
||||
<option '.( $hue_duration['config_value'] == "lselect" ? "selected" : ""). ' value="lselect">15 Seconds</option>
|
||||
</select>
|
||||
|
@@ -13,3 +13,87 @@
|
||||
*/
|
||||
|
||||
require_once 'includes/print-alert-templates.php';
|
||||
?>
|
||||
|
||||
<form action="" method="post">
|
||||
<input type="hidden" name="tool" value="convert">
|
||||
<input type="submit" class="btn btn-primary btn-sm" value="Convert template">
|
||||
</form>
|
||||
<br />
|
||||
<?php
|
||||
if ($vars['tool'] === 'convert' || $vars['old']) {
|
||||
if ($vars['old']) {
|
||||
foreach (explode(PHP_EOL, $vars['old']) as $line) {
|
||||
if (str_contains($line, '{calc')) {
|
||||
$new .= preg_replace(
|
||||
[
|
||||
'/{calc[ ]*([\w\d\s\%\.\(\)\*\/\-\+\/]+)}/',// Replaces {calc (something*100)}
|
||||
'/%([\w\d]+)\.([\w\d]+)/',// Replaces %something.anything
|
||||
],
|
||||
[
|
||||
'@php echo \1; @endphp ',
|
||||
'$value[\'\2\']',
|
||||
],
|
||||
$line
|
||||
);
|
||||
} else {
|
||||
$new .= convert_template($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo "
|
||||
<form action='' method='post'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
Paste old template here<br />
|
||||
<textarea name='old' cols='80' rows='30'>{$vars['old']}</textarea>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
New<br />
|
||||
<textarea name='old' cols='80' rows='30' disabled>$new</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<button type='submit' class='btn btn-success btn-sm' name='submit' value='convert'>Convert</button>
|
||||
</form>
|
||||
";
|
||||
}
|
||||
|
||||
function convert_template($old)
|
||||
{
|
||||
$find = [
|
||||
'/{if %([\w=\s]+)}/',// Replaces {if %something == else}
|
||||
'/{else}/',// Replaces {else}
|
||||
'/{\/if}/',// Replaces {/if}
|
||||
'/{foreach %faults}/',// Replaces {foreach %faults}
|
||||
'/{foreach %contacts}/',// Replaces {foreach %contacts}
|
||||
'/{\/foreach}/',// Replaces {/foreach}
|
||||
'/{calc[ ]*([\w\d\s\%\.\(\)\*\/\-\+\/]+)}/',// Replaces {calc (something*100)}
|
||||
'/%value.string/',// Replaces %value.string
|
||||
'/%([\w\d]+)\.([\w\d]+)/',// Replaces %something.anything
|
||||
'/%([\w\d]+)/',// Replaces %anything
|
||||
];
|
||||
$replace = [
|
||||
'@if ($alert->\1) ',
|
||||
' @else ',
|
||||
' @endif',
|
||||
'@foreach ($alert->faults as $key => $value)',
|
||||
'@foreach ($alert->contacts as $key => $value)',
|
||||
'@endforeach ',
|
||||
'@php echo \1; @endphp ',
|
||||
'$value[\'string\']',
|
||||
'{{ $\1[\'\2\'] }}',
|
||||
'{{ $alert->\1 }}',
|
||||
];
|
||||
$old = preg_replace($find, $replace, $old);
|
||||
|
||||
// Revert some over-zealous changes:
|
||||
$find = [
|
||||
'/\$alert->key/',
|
||||
'/\$alert->value/',
|
||||
];
|
||||
$replace = [
|
||||
'$key',
|
||||
'$value',
|
||||
];
|
||||
return preg_replace($find, $replace, $old);
|
||||
}
|
@@ -22,6 +22,7 @@
|
||||
* @subpackage Alerts
|
||||
*/
|
||||
|
||||
use LibreNMS\Alert\Template;
|
||||
use LibreNMS\Alerting\QueryBuilderParser;
|
||||
use LibreNMS\Authentication\Auth;
|
||||
|
||||
@@ -345,80 +346,6 @@ function GetContacts($results)
|
||||
return $tmp_contacts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format Alert
|
||||
* @param array $obj Alert-Array
|
||||
* @return string
|
||||
*/
|
||||
function FormatAlertTpl($obj)
|
||||
{
|
||||
$tpl = $obj["template"];
|
||||
$msg = '$ret .= "'.str_replace(array('{else}', '{/if}', '{/foreach}'), array('"; } else { $ret .= "', '"; } $ret .= "', '"; } $ret .= "'), addslashes($tpl)).'";';
|
||||
$parsed = $msg;
|
||||
$s = strlen($msg);
|
||||
$x = $pos = -1;
|
||||
$buff = '';
|
||||
$if = $for = $calc = false;
|
||||
while (++$x < $s) {
|
||||
if ($msg[$x] == '{' && $buff == '') {
|
||||
$buff .= $msg[$x];
|
||||
} elseif ($buff == '{ ') {
|
||||
$buff = '';
|
||||
} elseif ($buff != '') {
|
||||
$buff .= $msg[$x];
|
||||
}
|
||||
|
||||
if ($buff == '{if') {
|
||||
$pos = $x;
|
||||
$if = true;
|
||||
} elseif ($buff == '{foreach') {
|
||||
$pos = $x;
|
||||
$for = true;
|
||||
} elseif ($buff == '{calc') {
|
||||
$pos = $x;
|
||||
$calc = true;
|
||||
}
|
||||
|
||||
if ($pos != -1 && $msg[$x] == '}') {
|
||||
$orig = $buff;
|
||||
$buff = '';
|
||||
$pos = -1;
|
||||
if ($if) {
|
||||
$if = false;
|
||||
$o = 3;
|
||||
$native = array(
|
||||
'"; if( ',
|
||||
' ) { $ret .= "',
|
||||
);
|
||||
} elseif ($for) {
|
||||
$for = false;
|
||||
$o = 8;
|
||||
$native = array(
|
||||
'"; foreach( ',
|
||||
' as $key=>$value) { $ret .= "',
|
||||
);
|
||||
} elseif ($calc) {
|
||||
$calc = false;
|
||||
$o = 5;
|
||||
$native = array(
|
||||
'"; $ret .= (float) (0+(',
|
||||
')); $ret .= "',
|
||||
);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cond = trim(populate(substr($orig, $o, -1), false));
|
||||
$native = $native[0].$cond.$native[1];
|
||||
$parsed = str_replace($orig, $native, $parsed);
|
||||
unset($cond, $o, $orig, $native);
|
||||
}//end if
|
||||
}//end while
|
||||
$parsed = populate($parsed);
|
||||
return RunJail($parsed, $obj);
|
||||
}//end FormatAlertTpl()
|
||||
|
||||
/**
|
||||
* Populate variables
|
||||
* @param string $txt Text with variables
|
||||
@@ -476,19 +403,19 @@ function DescribeAlert($alert)
|
||||
{
|
||||
$obj = array();
|
||||
$i = 0;
|
||||
$device = dbFetchRow('SELECT hostname, sysName, sysDescr, hardware, version, location, purpose, notes, uptime FROM devices WHERE device_id = ?', array($alert['device_id']));
|
||||
$device = dbFetchRow('SELECT hostname, sysName, sysDescr, sysContact, os, type, ip, hardware, version, location, purpose, notes, uptime FROM devices WHERE device_id = ?', array($alert['device_id']));
|
||||
$attribs = get_dev_attribs($alert['device_id']);
|
||||
if (can_ping_device($attribs)) {
|
||||
$ping_stats = dbFetchRow('SELECT `timestamp`, `loss`, `min`, `max`, `avg` FROM `device_perf` WHERE `device_id` = ? ORDER BY `timestamp` LIMIT 1', [$alert['device_id']]);
|
||||
}
|
||||
$tpl = dbFetchRow('SELECT `template`,`title`,`title_rec` FROM `alert_templates` JOIN `alert_template_map` ON `alert_template_map`.`alert_templates_id`=`alert_templates`.`id` WHERE `alert_template_map`.`alert_rule_id`=?', array($alert['rule_id']));
|
||||
if (!$tpl) {
|
||||
$tpl = dbFetchRow("SELECT `template`,`title`,`title_rec` FROM `alert_templates` WHERE `name`='Default Alert Template'");
|
||||
}
|
||||
$default_tpl = "%title\r\nSeverity: %severity\r\n{if %state == 0}Time elapsed: %elapsed\r\n{/if}Timestamp: %timestamp\r\nUnique-ID: %uid\r\nRule: {if %name}%name{else}%rule{/if}\r\n{if %faults}Faults:\r\n{foreach %faults} #%key: %value.string\r\n{/foreach}{/if}Alert sent to: {foreach %contacts}%value <%key> {/foreach}";
|
||||
|
||||
$obj['hostname'] = $device['hostname'];
|
||||
$obj['sysName'] = $device['sysName'];
|
||||
$obj['sysDescr'] = $device['sysDescr'];
|
||||
$obj['sysContact'] = $device['sysContact'];
|
||||
$obj['os'] = $device['os'];
|
||||
$obj['type'] = $device['type'];
|
||||
$obj['ip'] = inet6_ntop($device['ip']);
|
||||
$obj['hardware'] = $device['hardware'];
|
||||
$obj['version'] = $device['version'];
|
||||
$obj['location'] = $device['location'];
|
||||
@@ -499,6 +426,7 @@ function DescribeAlert($alert)
|
||||
$obj['notes'] = $device['notes'];
|
||||
$obj['alert_notes'] = $alert['note'];
|
||||
$obj['device_id'] = $alert['device_id'];
|
||||
$obj['rule_id'] = $alert['rule_id'];
|
||||
if (can_ping_device($attribs)) {
|
||||
$obj['ping_timestamp'] = $ping_stats['template'];
|
||||
$obj['ping_loss'] = $ping_stats['loss'];
|
||||
@@ -507,17 +435,12 @@ function DescribeAlert($alert)
|
||||
$obj['ping_avg'] = $ping_stats['avg'];
|
||||
}
|
||||
$extra = $alert['details'];
|
||||
if (!isset($tpl['template'])) {
|
||||
$obj['template'] = $default_tpl;
|
||||
} else {
|
||||
$obj['template'] = $tpl['template'];
|
||||
}
|
||||
|
||||
$tpl = new Template;
|
||||
$template = $tpl->getTemplate($obj);
|
||||
|
||||
if ($alert['state'] >= 1) {
|
||||
if (!empty($tpl['title'])) {
|
||||
$obj['title'] = $tpl['title'];
|
||||
} else {
|
||||
$obj['title'] = 'Alert for device '.$device['hostname'].' - '.($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
}
|
||||
$obj['title'] = $template->title ?: 'Alert for device '.$device['hostname'].' - '.($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
if ($alert['state'] == 2) {
|
||||
$obj['title'] .= ' got acknowledged';
|
||||
} elseif ($alert['state'] == 3) {
|
||||
@@ -529,9 +452,10 @@ function DescribeAlert($alert)
|
||||
foreach ($extra['rule'] as $incident) {
|
||||
$i++;
|
||||
$obj['faults'][$i] = $incident;
|
||||
$obj['faults'][$i]['string'] = null;
|
||||
foreach ($incident as $k => $v) {
|
||||
if (!empty($v) && $k != 'device_id' && (stristr($k, 'id') || stristr($k, 'desc') || stristr($k, 'msg')) && substr_count($k, '_') <= 1) {
|
||||
$obj['faults'][$i]['string'] .= $k.' => '.$v.'; ';
|
||||
$obj['faults'][$i]['string'] .= $k.' = '.$v.'; ';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -552,11 +476,7 @@ function DescribeAlert($alert)
|
||||
$extra['count'] = 0;
|
||||
dbUpdate(array('details' => gzcompress(json_encode($id['details']), 9)), 'alert_log', 'id = ?', array($alert['id']));
|
||||
|
||||
if (!empty($tpl['title_rec'])) {
|
||||
$obj['title'] = $tpl['title_rec'];
|
||||
} else {
|
||||
$obj['title'] = 'Device '.$device['hostname'].' recovered from '.($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
}
|
||||
$obj['title'] = $template->title_rec ?: 'Device '.$device['hostname'].' recovered from '.($alert['name'] ? $alert['name'] : $alert['rule']);
|
||||
$obj['elapsed'] = TimeFormat(strtotime($alert['time_logged']) - strtotime($id['time_logged']));
|
||||
$obj['id'] = $id['id'];
|
||||
foreach ($extra['rule'] as $incident) {
|
||||
@@ -571,6 +491,7 @@ function DescribeAlert($alert)
|
||||
} else {
|
||||
return 'Unknown State';
|
||||
}//end if
|
||||
$obj['builder'] = $alert['builder'];
|
||||
$obj['uid'] = $alert['id'];
|
||||
$obj['alert_id'] = $alert['alert_id'];
|
||||
$obj['severity'] = $alert['severity'];
|
||||
@@ -579,9 +500,7 @@ function DescribeAlert($alert)
|
||||
$obj['timestamp'] = $alert['time_logged'];
|
||||
$obj['contacts'] = $extra['contacts'];
|
||||
$obj['state'] = $alert['state'];
|
||||
if (strstr($obj['title'], '%')) {
|
||||
$obj['title'] = RunJail('$ret = "'.populate(addslashes($obj['title'])).'";', $obj);
|
||||
}
|
||||
$obj['template'] = $template;
|
||||
return $obj;
|
||||
}//end DescribeAlert()
|
||||
|
||||
@@ -886,6 +805,7 @@ function ExtTransports($obj)
|
||||
{
|
||||
global $config;
|
||||
$tmp = false;
|
||||
$type = new Template;
|
||||
// To keep scrutinizer from naging because it doesnt understand eval
|
||||
foreach ($config['alert']['transports'] as $transport => $opts) {
|
||||
if (is_array($opts)) {
|
||||
@@ -894,8 +814,10 @@ function ExtTransports($obj)
|
||||
$class = 'LibreNMS\\Alert\\Transport\\' . ucfirst($transport);
|
||||
if (($opts === true || !empty($opts)) && $opts != false && class_exists($class)) {
|
||||
$obj['transport'] = $transport;
|
||||
$msg = FormatAlertTpl($obj);
|
||||
$obj['msg'] = $msg;
|
||||
$obj['alert'] = collect($obj);
|
||||
$obj['title'] = $type->getTitle($obj);
|
||||
$obj['alert']['title'] = $obj['title'];
|
||||
$obj['msg'] = $type->getBody($obj);
|
||||
echo $transport.' => ';
|
||||
$instance = new $class;
|
||||
$tmp = $instance->deliverAlert($obj, $opts);
|
||||
|
@@ -1030,7 +1030,7 @@ function object_is_cached($section, $obj)
|
||||
function can_ping_device($attribs)
|
||||
{
|
||||
global $config;
|
||||
if ($config['icmp_check'] === true && $attribs['override_icmp_disable'] != "true") {
|
||||
if ($config['icmp_check'] === true && (isset($attribs['override_icmp_disable']) && $attribs['override_icmp_disable'] != "true")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -1569,7 +1569,7 @@ function load_os(&$device)
|
||||
}
|
||||
|
||||
// Set type to a predefined type for the OS if it's not already set
|
||||
if ($device['attribs']['override_device_type'] != 1 && $config['os'][$device['os']]['type'] != $device['type']) {
|
||||
if ((!isset($device['attribs']['override_device_type']) && $device['attribs']['override_device_type'] != 1) && $config['os'][$device['os']]['type'] != $device['type']) {
|
||||
log_event('Device type changed ' . $device['type'] . ' => ' . $config['os'][$device['os']]['type'], $device, 'system', 3);
|
||||
$device['type'] = $config['os'][$device['os']]['type'];
|
||||
dbUpdate(array('type' => $device['type']), 'devices', 'device_id=?', array($device['device_id']));
|
||||
|
@@ -175,10 +175,6 @@ function dbInsert($data, $table)
|
||||
dbCommitTransaction();
|
||||
// return $id;
|
||||
} else {
|
||||
if ($table != 'Contact') {
|
||||
trigger_error('QDB - Insert failed.', E_USER_WARNING);
|
||||
}
|
||||
|
||||
dbRollbackTransaction();
|
||||
$id = null;
|
||||
}
|
||||
@@ -285,7 +281,7 @@ function dbUpdate($data, $table, $where = null, $parameters = array())
|
||||
$return = mysqli_affected_rows($database_link);
|
||||
} else {
|
||||
// echo("$fullSql");
|
||||
trigger_error('QDB - Update failed.', E_USER_WARNING);
|
||||
//trigger_error('QDB - Update failed.', E_USER_WARNING);
|
||||
$return = false;
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,7 @@ function set_debug($state = true, $silence = false)
|
||||
|
||||
restore_error_handler(); // disable Laravel error handler
|
||||
|
||||
if ($debug) {
|
||||
if (isset($debug) && $debug) {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
ini_set('log_errors', 0);
|
||||
@@ -1025,7 +1025,7 @@ function log_event($text, $device = null, $type = null, $severity = 2, $referenc
|
||||
'datetime' => array("NOW()"),
|
||||
'severity' => $severity,
|
||||
'message' => $text,
|
||||
'username' => Auth::user()->username ?: '',
|
||||
'username' => isset(Auth::user()->username) ? Auth::user()->username : '',
|
||||
);
|
||||
|
||||
dbInsert($insert, 'eventlog');
|
||||
|
@@ -90,6 +90,13 @@ if (module_selected('polling', $init_modules)) {
|
||||
if (module_selected('alerts', $init_modules)) {
|
||||
require_once $install_dir . '/includes/device-groups.inc.php';
|
||||
require_once $install_dir . '/includes/alerts.inc.php';
|
||||
if (module_selected('alerts-cli', $init_modules)) {
|
||||
// Boot Laravel - we only use it in alerting at present
|
||||
require $install_dir . '/bootstrap/autoload.php';
|
||||
$app = require_once $install_dir . '/bootstrap/app.php';
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
$kernel->bootstrap();
|
||||
}
|
||||
}
|
||||
|
||||
// Display config.php errors instead of http 500
|
||||
|
@@ -103,7 +103,6 @@ alert_schedule_items:
|
||||
alert_templates:
|
||||
Columns:
|
||||
- { Field: id, Type: int(11), 'Null': false, Extra: auto_increment }
|
||||
- { Field: rule_id, Type: varchar(255), 'Null': false, Extra: '', Default: ',' }
|
||||
- { Field: name, Type: varchar(255), 'Null': false, Extra: '' }
|
||||
- { Field: template, Type: longtext, 'Null': false, Extra: '' }
|
||||
- { Field: title, Type: varchar(255), 'Null': true, Extra: '' }
|
||||
|
@@ -154,6 +154,7 @@ pages:
|
||||
- Intro: Support/Device-Notes/index.md
|
||||
- Carel pCOweb: Support/Device-Notes/Carel-pCOweb-Devices.md
|
||||
- hidden:
|
||||
- Alerting/Old_Templates.md
|
||||
- API/API-Docs.md
|
||||
- Installation/Installing-LibreNMS.md
|
||||
- Extensions/Alerting.md
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$init_modules = array('alerts');
|
||||
$init_modules = ['alerts', 'alerts-cli'];
|
||||
require __DIR__ . '/../includes/init.php';
|
||||
|
||||
$options = getopt('t:h:r:p:s:d::');
|
||||
@@ -20,6 +20,7 @@ if ($options['r'] && $options['h']) {
|
||||
$alert = $alerts[0];
|
||||
|
||||
$alert['details']['delay'] = 0;
|
||||
$alert['note'] = 'Testing';
|
||||
IssueAlert($alert);
|
||||
} else {
|
||||
c_echo("
|
||||
|
1
sql-schema/254.sql
Normal file
1
sql-schema/254.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `alert_templates` DROP `rule_id`;
|
@@ -60,7 +60,7 @@ class DBSetupTest extends DBTestCase
|
||||
}
|
||||
|
||||
// cannot assume user use the librenms database name
|
||||
if (str_contains($line, 'librenms')) {
|
||||
if (str_contains($line, 'librenms.')) {
|
||||
throw new PHPUnitException("Do not include the database name in schema files\n$file: $line");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user