mirror of
https://github.com/librenms/librenms.git
synced 2024-09-29 06:16:43 +00:00
commit
bcf3c5c541
@ -208,7 +208,7 @@ function ExtTransports($obj) {
|
||||
global $config;
|
||||
$tmp = false; //To keep scrutinizer from naging because it doesnt understand eval
|
||||
foreach( $config['alert']['transports'] as $transport=>$opts ) {
|
||||
if( file_exists($config['install_dir']."/includes/alerts/transport.".$transport.".php") ) {
|
||||
if( ($opts === true || !empty($opts)) && file_exists($config['install_dir']."/includes/alerts/transport.".$transport.".php") ) {
|
||||
echo $transport." => ";
|
||||
eval('$tmp = function($obj,$opts) { global $config; '.file_get_contents($config['install_dir']."/includes/alerts/transport.".$transport.".php").' };');
|
||||
$tmp = $tmp($obj,$opts);
|
||||
@ -292,7 +292,7 @@ function DescribeAlert($alert) {
|
||||
$i++;
|
||||
$obj['faults'][$i] = $incident;
|
||||
foreach( $incident as $k=>$v ) {
|
||||
if( !empty($v) && $k != 'device_id' && (stristr($k,'id') || stristr($k,'desc')) && substr_count($k,'_') <= 1 ) {
|
||||
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."; ";
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ Table of Content:
|
||||
- [Ports](#entity-ports)
|
||||
- [Processors](#entity-processors)
|
||||
- [Storage](#entity-storage)
|
||||
- [Macros](#macros)
|
||||
- [Device](#macros-device)
|
||||
- [Port](#macros-port)
|
||||
- [Time](#macros-time)
|
||||
|
||||
|
||||
# <a name="about">About</a>
|
||||
|
||||
@ -316,3 +321,109 @@ __processors.processor_descr__ = The description of the processor.
|
||||
__storage.storage_descr__ = The description of the storage.
|
||||
|
||||
__storage.storage_perc__ = The usage of the storage as a percentage.
|
||||
|
||||
# <a name="macros">Macros</a>
|
||||
|
||||
Macros are shorthands to either portion of rules or pure SQL enhanced with placeholders.
|
||||
You can define your own macros in your `config.php`.
|
||||
|
||||
Example macro-implementation of Debian-Devices
|
||||
```php
|
||||
$config['alert']['macros']['rule']['is_debian'] = '%devices.features ~ "@debian@"';
|
||||
```
|
||||
And in the Rule:
|
||||
```
|
||||
... && %macros.is_debian = "1" && ...
|
||||
```
|
||||
|
||||
This Example-macro is a Boolean-macro, it applies a form of filter to the set of results defined by the rule.
|
||||
All macros that are not unary should return Boolean.
|
||||
|
||||
You can only apply _Equal_ or _Not-Equal_ Operations on Bollean-macros where `True` is represented by `"1"` and `False` by `"0"`.
|
||||
|
||||
|
||||
## <a name="macros-device">Device</a> (Boolean)
|
||||
|
||||
Entity: `%macros.device`
|
||||
|
||||
Description: Only select devices that aren't deleted, ignored or disabled.
|
||||
|
||||
Source: `(%devices.disabled = "0" && %devices.ignore = "0")`
|
||||
|
||||
### <a name="macros-device-up">Device is up</a> (Boolean)
|
||||
|
||||
Entity: `%macros.device_up`
|
||||
|
||||
Description: Only select devices that are up.
|
||||
|
||||
Implies: %macros.device
|
||||
|
||||
Source: `(%devices.status = "1" && %macros.device)`
|
||||
|
||||
### <a name="macros-device-down">Device is down</a> (Boolean)
|
||||
|
||||
Entity: `%macros.device_down`
|
||||
|
||||
Description: Only select devices that are down.
|
||||
|
||||
Implies: %macros.device
|
||||
|
||||
Source: `(%devices.status = "0" && %macros.device)`
|
||||
|
||||
## <a name="macros-port">Port</a> (Boolean)
|
||||
|
||||
Entity: `%macros.port`
|
||||
|
||||
Description: Only select ports that aren't deleted, ignored or disabled.
|
||||
|
||||
Source: `(%ports.deleted = "0" && %ports.ignore = "0" && %ports.disabled = "0")`
|
||||
|
||||
### <a name="macros-port-up">Port is up</a> (Boolean)
|
||||
|
||||
Entity: `%macros.port_up`
|
||||
|
||||
Description: Only select ports that are up and also should be up.
|
||||
|
||||
Implies: %macros.port
|
||||
|
||||
Source: `(%ports.ifOperStatus = "up" && %ports.ifAdminStatus = "up" && %macros.port)`
|
||||
|
||||
### <a name="macros-port-down">Port is down</a> (Boolean)
|
||||
|
||||
Entity: `%macros.port_down`
|
||||
|
||||
Description: Only select ports that are down.
|
||||
|
||||
Implies: %macros.port
|
||||
|
||||
Source: `(%ports.ifOperStatus = "down" && %ports.ifAdminStatus != "down" && %macros.port)`
|
||||
|
||||
### <a name="macros-port-usage-perc">Port-Usage in Percent</a> (Decimal)
|
||||
|
||||
Entity: `%macros.port_usage_perc`
|
||||
|
||||
Description: Return port-usage in percent.
|
||||
|
||||
Source: `((%ports.ifInOctets_rate*8)/%ports.ifSpeed)*100`
|
||||
|
||||
## <a name="macros-time">Time</a>
|
||||
|
||||
### <a name="macros-time-now">Now</a> (Datetime)
|
||||
|
||||
Entity: `%macros.now`
|
||||
|
||||
Description: Alias of MySQL's NOW()
|
||||
|
||||
Source: `NOW()`
|
||||
|
||||
### <a name="macros-time-past-Nm">Past N Minutes</a> (Datetime)
|
||||
|
||||
Entity: `%macros.past_$m`
|
||||
|
||||
Description: Returns a MySQL Timestamp dated `$` Minutes in the past. `$` can only be a supported Resolution.
|
||||
|
||||
Example: `%macros.past_5m` is Last 5 Minutes.
|
||||
|
||||
Resolution: 5,10,15,30,60
|
||||
|
||||
Source: `DATE_SUB(NOW(),INTERVAL $ MINUTE)`
|
||||
|
@ -67,6 +67,11 @@ if( isset($_GET['term'],$_GET['device_id']) ) {
|
||||
$chk = $memcache->get('rule-suggest_'.$term[0]);
|
||||
}
|
||||
if( !(sizeof($chk) > 0) || $chk === false ) {
|
||||
if( $term[0] == "macros" ) {
|
||||
foreach( $config['alert']['macros']['rule'] as $macro=>$v ) {
|
||||
$chk[] = "macros.".$macro;
|
||||
}
|
||||
} else {
|
||||
$tmp = dbFetchRows('SHOW COLUMNS FROM '.$term[0]);
|
||||
foreach( $tmp as $tst ) {
|
||||
if( isset($tst['Field']) ) {
|
||||
@ -74,6 +79,7 @@ if( isset($_GET['term'],$_GET['device_id']) ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$current = true;
|
||||
} else {
|
||||
if( $config['memcached']['enable'] ) {
|
||||
@ -84,6 +90,7 @@ if( isset($_GET['term'],$_GET['device_id']) ) {
|
||||
foreach( $tmp as $tst ) {
|
||||
$chk[] = $tst['TABLE_NAME'].'.';
|
||||
}
|
||||
$chk[] = 'macros.';
|
||||
}
|
||||
}
|
||||
if( sizeof($chk) > 0 ) {
|
||||
|
@ -21,6 +21,12 @@ if(!is_numeric($_POST['group_id'])) {
|
||||
exit;
|
||||
} else {
|
||||
if(dbDelete('device_groups', "`id` = ?", array($_POST['group_id']))) {
|
||||
if( dbFetchCell('SELECT COUNT(id) FROM alert_map WHERE target = ?',array('g'.$_POST['group_id'])) >= 1 ) {
|
||||
foreach( dbFetchRows('SELECT id FROM alert_map WHERE target = ?',array('g'.$_POST['group_id'])) as $map ) {
|
||||
$_POST['map_id'] = $map['id'];
|
||||
include('forms/delete-alert-map.inc.php');
|
||||
}
|
||||
}
|
||||
echo('group has been deleted.');
|
||||
exit;
|
||||
} else {
|
||||
|
@ -245,11 +245,13 @@ $('#and, #or').click('', function(e) {
|
||||
strategy: 'array',
|
||||
tagFieldName: 'rules[]'
|
||||
});
|
||||
if(entity.indexOf("%") >= 0) {
|
||||
$('#response').data('tagmanager').populate([ entity+' '+condition+' '+value+' '+glue ]);
|
||||
} else {
|
||||
$('#response').data('tagmanager').populate([ '%'+entity+' '+condition+' "'+value+'" '+glue ]);
|
||||
if(value.indexOf("%") < 0) {
|
||||
value = '"'+value+'"';
|
||||
}
|
||||
if(entity.indexOf("%") < 0) {
|
||||
entity = '%'+entity;
|
||||
}
|
||||
$('#response').data('tagmanager').populate([ entity+' '+condition+' '+value+' '+glue ]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -12,12 +12,12 @@ $no_refresh = TRUE;
|
||||
<?php
|
||||
|
||||
if(isset($_POST['create-default'])) {
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%devices.status != "1" && %devices.disabled = "0" && %devices.ignore = "0"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"-1","delay":"300"}', 'disabled' => 0, 'name' => 'Devices up/down');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%devices.uptime < "300" && %devices.disabled = "0" && %devices.ignore = "0"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'Device rebooted');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%bgpPeers.bgpPeerState != "established"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'BGP Session down');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%macros.device_down = "1"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"-1","delay":"300"}', 'disabled' => 0, 'name' => 'Devices up/down');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%devices.uptime < "300" && %macros.device = "1"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'Device rebooted');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%bgpPeers.bgpPeerState != "established" && %macros.device_up = "1"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'BGP Session down');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%bgpPeers.bgpPeerFsmEstablishedTime < "300" && %bgpPeers.bgpPeerState = "established"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'BGP Session establised');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%ports.ifOperStatus != "up" && %ports.ifAdminStatus = "up" && %ports.deleted = "0" && %ports.ignore = "0" && %ports.disabled = "0"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'Port status up/down');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '((%ports.ifInOctets_rate*8)/%ports.ifSpeed)*100 >= 80', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"-1","delay":"300"}', 'disabled' => 0, 'name' => 'Port utilisation over threshold');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%macros.port_down = "1"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"1","delay":"300"}', 'disabled' => 0, 'name' => 'Port status up/down');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%macros.port_usage_perc >= "80"', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"-1","delay":"300"}', 'disabled' => 0, 'name' => 'Port utilisation over threshold');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%sensors.sensor_current > %sensors.sensor_limit', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"-1","delay":"300"}', 'disabled' => 0, 'name' => 'Sensor over limit');
|
||||
$default_rules[] = array('device_id' => '-1', 'rule' => '%sensors.sensor_current < %sensors.sensor_limit_low', 'severity' => 'critical', 'extra' => '{"mute":false,"count":"-1","delay":"300"}', 'disabled' => 0, 'name' => 'Sensor under limit');
|
||||
foreach( $default_rules as $add_rule ) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
$pagetitle[] = "Alert Stats";
|
||||
|
||||
$sql = "";
|
||||
if (isset($device['device_id']) && $device['device_id'] > 0) {
|
||||
$sql = " AND alert_log.device_id=?";
|
||||
$param = array(
|
||||
|
@ -48,11 +48,11 @@ foreach (dbFetchRows($sql,$param) as $alert) {
|
||||
$fault_detail .= $tmp;
|
||||
} else {
|
||||
foreach ($tmp_alerts as $k=>$v) {
|
||||
if (!empty($v) && $k != 'device_id' && (stristr($k,'id') || stristr($k,'desc')) && substr_count($k,'_') <= 1) {
|
||||
if (!empty($v) && $k != 'device_id' && (stristr($k,'id') || stristr($k,'desc') || stristr($k,'msg')) && substr_count($k,'_') <= 1) {
|
||||
$fault_detail .= "$k => '$v', ";
|
||||
}
|
||||
$fault_detail = rtrim($fault_detail,", ");
|
||||
}
|
||||
$fault_detail = rtrim($fault_detail,", ");
|
||||
}
|
||||
$fault_detail .= "<br>";
|
||||
}
|
||||
@ -97,7 +97,7 @@ foreach (dbFetchRows($sql,$param) as $alert) {
|
||||
if ($_SESSION['userlevel'] >= '10') {
|
||||
$ack_ico = 'volume-up';
|
||||
$ack_col = 'success';
|
||||
if(in_array($alert['state'],array(2,3,4))) {
|
||||
if($alert['state'] == 2) {
|
||||
$ack_ico = 'volume-off';
|
||||
$ack_col = 'danger';
|
||||
}
|
||||
|
@ -28,9 +28,13 @@ include_once($config['install_dir'].'/html/includes/authentication/'.$config['au
|
||||
/**
|
||||
* Generate SQL from Rule
|
||||
* @param string $rule Rule to generate SQL for
|
||||
* @return string
|
||||
* @return string|boolean
|
||||
*/
|
||||
function GenSQL($rule) {
|
||||
$rule = RunMacros($rule);
|
||||
if( empty($rule) ) {
|
||||
return false;
|
||||
}
|
||||
$tmp = explode(" ",$rule);
|
||||
$tables = array();
|
||||
foreach( $tmp as $opt ) {
|
||||
@ -55,6 +59,29 @@ function GenSQL($rule) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Macros
|
||||
* @param string $rule Rule to process
|
||||
* @return string|boolean
|
||||
*/
|
||||
function RunMacros($rule,$x=1) {
|
||||
global $config;
|
||||
krsort($config['alert']['macros']['rule']);
|
||||
foreach( $config['alert']['macros']['rule'] as $macro=>$value ) {
|
||||
if( !strstr($macro," ") ) {
|
||||
$rule = str_replace('%macros.'.$macro,$value,$rule);
|
||||
}
|
||||
}
|
||||
if( strstr($rule,"%macros") ) {
|
||||
if( ++$x < 30 ) {
|
||||
$rule = RunMacros($rule,$x);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Alert-Rules for Devices
|
||||
* @param int $device Device-ID
|
||||
@ -158,8 +185,8 @@ function GetContacts($results) {
|
||||
if( sizeof($results) == 0 ) {
|
||||
return array();
|
||||
}
|
||||
if( $config['alerts']['email']['default_only'] ) {
|
||||
return array($config['alerts']['email']['default'] => 'NOC');
|
||||
if( $config['alert']['default_only'] == true || $config['alerts']['email']['default_only'] == true ) {
|
||||
return array(''.($config['alert']['default_mail'] ? $config['alert']['default_mail'] : $config['alerts']['email']['default']) => 'NOC');
|
||||
}
|
||||
$users = get_userlist();
|
||||
$contacts = array();
|
||||
|
@ -201,6 +201,44 @@ $config['email_smtp_password'] = NULL; // Password for SM
|
||||
|
||||
// Alerting Settings
|
||||
|
||||
$config['alert'] = array(
|
||||
'macros' => array( //Macros:
|
||||
'rule' => array( // For Rules
|
||||
//Time Macros
|
||||
'now' => 'NOW()',
|
||||
'past_5m' => 'DATE_SUB(NOW(),INTERVAL 5 MINUTE)',
|
||||
'past_10m' => 'DATE_SUB(NOW(),INTERVAL 10 MINUTE)',
|
||||
'past_15m' => 'DATE_SUB(NOW(),INTERVAL 15 MINUTE)',
|
||||
'past_30m' => 'DATE_SUB(NOW(),INTERVAL 30 MINUTE)',
|
||||
'past_60m' => 'DATE_SUB(NOW(),INTERVAL 60 MINUTE)',
|
||||
|
||||
//Device Macros
|
||||
'device' => '(%devices.disabled = "0" && %devices.ignore = "0")',
|
||||
'device_up' => '(%devices.status = "1" && %macros.device)',
|
||||
'device_down' => '(%devices.status = "0" && %macros.device)',
|
||||
|
||||
//Port Macros
|
||||
'port' => '(%ports.deleted = "0" && %ports.ignore = "0" && %ports.disabled = "0")',
|
||||
'port_up' => '(%ports.ifOperStatus = "up" && %ports.ifAdminStatus = "up" && %macros.port)',
|
||||
'port_down' => '(%ports.ifOperStatus = "down" && %ports.ifAdminStatus != "down" && %macros.port)',
|
||||
'port_usage_perc' => '((%ports.ifInOctets_rate*8)/%ports.ifSpeed)*100',
|
||||
|
||||
//Misc Macros
|
||||
),
|
||||
),
|
||||
'transports' => array( //Transports:
|
||||
'dummy' => false, // Dummy alerting (debug)
|
||||
'mail' => false, // E-Mail alerting
|
||||
'irc' => false, // IRC Alerting
|
||||
),
|
||||
'globals' => false, //Issue to global-read users
|
||||
'admins' => false, //Issue to administrators
|
||||
'default_only' => false, //Only issue to default
|
||||
'default_mail' => '', //Default email
|
||||
);
|
||||
|
||||
//Legacy options
|
||||
|
||||
$config['alerts']['email']['default'] = NULL; // Default alert recipient
|
||||
$config['alerts']['email']['default_only'] = FALSE; // Only use default recipient
|
||||
$config['alerts']['email']['enable'] = TRUE; // Enable email alerts
|
||||
|
Loading…
Reference in New Issue
Block a user