Files
librenms-librenms/doc/Developing/os/Health-Information.md

257 lines
13 KiB
Markdown
Raw Normal View History

source: Developing/os/Health-Information.md
path: blob/master/doc/
#### Sensors
This document will guide you through adding health / sensor
information for your new device.
Currently we have support for the following health metrics along with
the values we expect to see the data in:
| Class | Measurement |
| ------------------------------- | --------------------------- |
| airflow | cfm |
| ber | ratio |
| charge | % |
| chromatic_disperision | ps/nm |
| cooling | W |
| count | # |
| current | A |
| dbm | dBm |
| delay | s |
| eer | eer |
| fanspeed | rpm |
| frequency | Hz |
| humidity | % |
| load | % |
| power | W |
| power_consumed | kWh |
| power_factor | ratio |
| pressure | kPa |
| quality_factor | dB |
| runtime | Min |
| signal | dBm |
| snr | SNR |
| state | # |
| temperature | C |
| voltage | V |
| waterflow | l/m |
#### Simple health discovery
We have support for defining health / sensor discovery using YAML
files so that you don't need to know how to write PHP.
> Please note that DISPLAY-HINTS are disabled so ensure you use the
> correct divisor / multiplier if applicable.
All yaml files are located in
`includes/definitions/discovery/$os.yaml`. Defining the information
here is not always possible and is heavily reliant on vendors being
sensible with the MIBs they generate. Only snmp walks are supported
and you must provide a sane table that can be traversed and contains
all of the data you need. We will use netbotz as an example here.
`includes/definitions/discovery/netbotz.yaml`
```yaml
mib: NETBOTZV2-MIB
modules:
sensors:
airflow:
options:
skip_values_lt: 0
data:
-
oid: airFlowSensorTable
value: airFlowSensorValue
divisor: 10
num_oid: '.1.3.6.1.4.1.5528.100.4.1.5.1.2.{{ $index }}'
descr: '{{ $airFlowSensorLabel }}'
index: 'airFlowSensorValue.{{ $index }}'
```
At the top you can define one or more mibs to be used in the lookup of data:
`mib: NETBOTZV2-MIB`
For `data:` you have the following options:
The only sensor we have defined here is airflow. The available options are as follows:
- `oid` (required): This is the name of the table you want to do the snmp walk on.
- `value` (optional): This is the key within the table that contains
the value. If not provided willuse `oid`
- `num_oid` (required): This is the numerical OID that contains
`value`. This should always include `{{ $index }}`. snmptranslate
-On can help figure out the number.
In case the index is a string, `{{ $index_string }}` can be used instead.
- `divisor` (optional): This is the divisor to use against the returned `value`.
- `multiplier` (optional): This is the multiplier to use against the returned `value`.
- `low_limit` (optional): This is the critical low threshold that
`value` should be (used in alerting). If an OID is specified then
divisor / multiplier are used.
- `low_warn_limit` (optional): This is the warning low threshold that
`value` should be (used in alerting). If an OID is specified then
divisor / multiplier are used.
- `warn_limit` (optional): This is the warning high threshold that
`value` should be (used in alerting). If an OID is specified then
divisor / multiplier are used.
- `high_limit` (optional): This is the critical high threshold that
`value` should be (used in alerting). If an OID is specified then
divisor / multiplier are used.
- `descr` (required): The visible label for this sensor. It can be a
key with in the table or a static string, optionally using `{{ index }}`.
- `group` (optional): Groups sensors together under in the webui,
displaying this text. Not specifying this will put the sensors in
the default group.
- `index` (optional): This is the index value we use to uniquely
identify this sensor. `{{ $index }}` will be replaced by the `index`
from the snmp walk.
- `skip_values` (optional): This is an array of values we should skip
over (see note below).
- `skip_value_lt` (optional): If sensor value is less than this, skip the discovery.
- `skip_value_gt` (optional): If sensor value is greater than this, skip the discovery.
- `entPhysicalIndex` (optional): If the sensor belongs to a physical
entity then you can specify the index here.
- `entPhysicalIndex_measured` (optional): If the sensor belongs to a
physical entity then you can specify the entity type here.
- `user_func` (optional): You can provide a function name for the
sensors value to be processed through (i.e. Convert fahrenheit to
celsius use `fahrenheit_to_celsius`)
For `options:` you have the following available:
- `divisor`: This is the divisor to use against the returned `value`.
- `multiplier`: This is the multiplier to use against the returned `value`.
- `skip_values`: This is an array of values we should skip over (see note below).
- `skip_value_lt`: If sensor value is less than this, skip the discovery.
- `skip_value_gt`: If sensor value is greater than this, skip the discovery.
Multiple variables can be used in the sensors definition. The syntax
is `{{ $variable }}`. Any oid in the current table can be used, as
well as pre_cached data. The index ($index) and the sub_indexes (in
case the oid is indexed multiple times) are also available: if
$index="1.20", then $subindex0="1" and $subindex1="20".
> `skip_values` can also compare items within the OID table against
Update IronWare sensors & bgp-peers discovery, allow skip_values to target a specific index appended to the OID (#10941) * Migrate ironware sensor discovery from php to yaml. * More sensors, add grouping. * dynamic_discovery_get_value() becomes getValueFromData() * Target a specific index with skip_values. * Improve Brocade BGP session discovery/polling This commit allows for the correct discovery of BGP sessions with 32-bit ASNs, IPv6 neighbors using the BGP4V2-MIB which is based on draft-ietf-idr-bgp4-mibv2-11 and also polls for IPv4 unicast received routes through the FOUNDRY-SN-BGP4-GROUP-MIB. Copied most of the code from PR#8877 by @Mikeburke14, cleaned up the code a little bit to match the normal LibreNMS style, and fixed bgpPeers_cbgp discovery as well as polling for the ipv4.unicast neighbors. Note that older Brocade IronWare firmware versions are known to have multiple defects relating to the BGP4V2-MIB which might result in certain missing non-established neighbors. Related vendor defect numbers: - DEFECT000633962 -- Symptom: The OID bgp4V2PeerAdminStatus does not return the correct value -- Reported: NI 05.7.00 -- Resolved: NI 05.8.00g - DEFECT000583319 -- Symptom: SNMP polling on bgp4V2PeerTable (OID brcdIp.3.5.1.1.2) does not display all the BGP entries -- Reported: NI 05.6.00 -- Resolved: NI 05.8.00e - DEFECT000550309 -- Symptom: SNMP polling on bgp4V2PeerTable (OID brcdIp.3.5.1.1.2) does not display the full information -- Reported: NI 05.7.00 -- Resolved: NI 05.8.00c * Add ironware CER & ICX platform test data. * Re-add ironware.json compatible with current master branch.
2020-02-01 23:28:03 +01:00
> values. The index of the sensor is used to retrieve the value
> from the OID, unless a target index is appended to the OID.
> Comparisons behave on a logical OR basis when chained, so only
> one of them needs to be matched for that particular sensor
> to be skipped during discovery. An example of this is below:
```yaml
skip_values:
-
oid: sensUnit
op: '!='
value: 4
Update IronWare sensors & bgp-peers discovery, allow skip_values to target a specific index appended to the OID (#10941) * Migrate ironware sensor discovery from php to yaml. * More sensors, add grouping. * dynamic_discovery_get_value() becomes getValueFromData() * Target a specific index with skip_values. * Improve Brocade BGP session discovery/polling This commit allows for the correct discovery of BGP sessions with 32-bit ASNs, IPv6 neighbors using the BGP4V2-MIB which is based on draft-ietf-idr-bgp4-mibv2-11 and also polls for IPv4 unicast received routes through the FOUNDRY-SN-BGP4-GROUP-MIB. Copied most of the code from PR#8877 by @Mikeburke14, cleaned up the code a little bit to match the normal LibreNMS style, and fixed bgpPeers_cbgp discovery as well as polling for the ipv4.unicast neighbors. Note that older Brocade IronWare firmware versions are known to have multiple defects relating to the BGP4V2-MIB which might result in certain missing non-established neighbors. Related vendor defect numbers: - DEFECT000633962 -- Symptom: The OID bgp4V2PeerAdminStatus does not return the correct value -- Reported: NI 05.7.00 -- Resolved: NI 05.8.00g - DEFECT000583319 -- Symptom: SNMP polling on bgp4V2PeerTable (OID brcdIp.3.5.1.1.2) does not display all the BGP entries -- Reported: NI 05.6.00 -- Resolved: NI 05.8.00e - DEFECT000550309 -- Symptom: SNMP polling on bgp4V2PeerTable (OID brcdIp.3.5.1.1.2) does not display the full information -- Reported: NI 05.7.00 -- Resolved: NI 05.8.00c * Add ironware CER & ICX platform test data. * Re-add ironware.json compatible with current master branch.
2020-02-01 23:28:03 +01:00
-
oid: sensConfig.0
op: '!='
value: 1
```
> ``` op ``` can be any of the following operators :
>
> =, !=, ==, !==, <=, >=, <, >,
> starts, ends, contains, regex, in_array, not_starts,
> not_ends, not_contains, not_regex, not_in_array
>
> Example:
```yaml
skip_values:
-
oid: sensorName
op: 'not_in_array'
value: ['sensor1', 'sensor2']
```
If you aren't able to use yaml to perform the sensor discovery, you
will most likely need to use Advanced health discovery.
#### Advanced health discovery
If you can't use the yaml files as above, then you will need to create
the discovery code in php.
The directory structure for sensor information is
`includes/discovery/sensors/$class/$os.inc.php`. The format of all of
the sensors follows the same code format which is to call the
`discover_sensor()` function - with the exception of state which
requires additional code.
`discover_sensor()` Accepts the following arguments:
- &$valid = This is always $valid['sensor'], do not pass any other values.
- $class = Required. This is the sensor class from the table above (i.e humidity).
- $device = Required. This is the $device array.
- $oid = Required. This must be the numerical OID for where the data
can be found, i.e .1.2.3.4.5.6.7.0
- $index = Required. This must be unique for this sensor class, device
and type. Typically it's the index from the table being walked or it
could be the name of the OID if it's a single value.
- $type = Required. This should be the OS name, i.e pulse.
- $descr = Required. This is a descriptive value for the sensor. Some
devices will provide names to use.
- $divisor = Defaults to 1. This is used to divided the returned value.
- $multiplier = Defaults to 1. This is used to multiply the returned value.
- $low_limit = Defaults to null. Sets the low threshold limit for the
sensor, used in alerting to report out range sensors.
- $low_warn_limit = Defaults to null. Sets the low warning limit for
the sensor, used in alerting to report near out of range sensors.
- $warn_limit = Defaults to null. Sets the high warning limit for the
sensor, used in alerting to report near out of range sensors.
- $high_limit = Defaults to null. Sets the high limit for the sensor,
used in alerting to report out range sensors.
- $current = Defaults to null. Can be used to set the current value on
discovery. Poller will update this on the next poll cycle anyway.
- $poller_type = Defaults to snmp. Things like the unix-agent can set
different values but for the most part this should be left as snmp.
- $entPhysicalIndex = Defaults to null. Sets the entPhysicalIndex to
be used to look up further hardware if available.
- $entPhysicalIndex_measured = Defaults to null. Sets the type of
entPhysicalIndex used, i.e ports.
- $user_func = Defaults to null. You can provide a function name for
the sensors value to be processed through (i.e. Convert fahrenheit
to celsius use `fahrenheit_to_celsius`)
- $group = Defaults to null. Groups sensors together under in the
webui, displaying this text.
For the majority of devices, this is all that's required to add
support for a sensor. Polling is done based on the data gathered using
`discover_sensor()`. If custom polling is needed then the file format
is similar to discovery:
`includes/polling/sensors/$class/$os.inc.php`. Whilst it's possible to
perform additional snmp queries within polling this should be avoided
where possible. The value for the OID is already available as `$sensor_value`.
Graphing is performed automatically for sensors, no custom graphing is
required or supported.
Remove guessed limits for some health sensors, documentation for sensor classes (#10327) * Default to null for group yaml discovery. * Update test data for a154bda yaml group null fix. * Changes to guessed limit functions for sensors. Original behaviour =================== The file `includes/discovery/functions.inc.php` contains `sensor_limit_low()` and `sensor_limit()` which both attempt to guess a sane value for sensors when no explicitly defined low_limit or high_limit can be found during discovery. Both switch control structures used in those two functions have empty case statements which means that if one of those matches, it's going to fall through and run the code for each subsequent case until a `break` is reached. For example, when we call `function sensor_low_limit(dbm, -13.036)` it will return the value `-12.3842` instead of `null`. That is because there will be a match at `case 'dbm':` which falls through all the way to `case 'cooling':`, where it performs `$limit = -13.036 * 0.95` before hitting a `break`. Changed behaviour =================== Removed `power_consumed` and `count` guessed low_limit and high_limit, I personally added those sensor classes in PR #9471 when I didn't understand that a switch control structure has fall-through behaviour so I can guarantee that guessing limits for those is a mistake on my behalf. It should not be there, only power_factor can have guessed limits. Apologies for the issue, I'm still a beginning programmer! Furthermore, I removed guessed high_limit values for `current` and `power` because these are supposed to draw higher values as more devices or components are installed on for example a PDU or a chassis. Finally, I removed guessed low_limit and high_limit for `dbm` sensors, there is a much too large variance in power budget on commercially available optical transceivers for there to be a sensible window where you can guess these values. * Documentation on adding sensor classes. * Update test data - sensor limit changes @ 30212d2
2019-06-21 16:03:27 +02:00
#### Adding a new sensor class
You will need to add code for your new sensor class in the following existing files:
- `app/Models/Sensor.php`: add a free icon from [Font Awesome](https://fontawesome.com/icons?d=gallery&m=free) in the $icons array.
- `doc/Developing/os/Health-Information.md`: documentation for every sensor class is mandatory.
- `includes/discovery/sensors.inc.php`: add the sensor class to the $run_sensors array.
- `includes/discovery/functions.inc.php`: optional - if sensible low_limit and high_limit values are guessable when a SNMP-retrievable threshold is not available, add a case for the sensor class to the sensor_limit() and/or sensor_low_limit() functions.
- `LibreNMS/Util/ObjectCache.php`: optional - choose menu grouping for the sensor class.
- `includes/html/pages/device/health.inc.php`: add a dbFetchCell(), $datas[], and $type_text[] entry for the sensor class.
- `includes/html/pages/device/overview.inc.php`: add `require 'overview/sensors/$class.inc.php'` in the desired order for the device overview page.
- `includes/html/pages/health.inc.php`: add a $type_text[] entry for the sensor class.
- `resources/lang/en/sensors.php`: add human-readable names and units for the sensor class in English, feel free to do so for other languages as well.
Remove guessed limits for some health sensors, documentation for sensor classes (#10327) * Default to null for group yaml discovery. * Update test data for a154bda yaml group null fix. * Changes to guessed limit functions for sensors. Original behaviour =================== The file `includes/discovery/functions.inc.php` contains `sensor_limit_low()` and `sensor_limit()` which both attempt to guess a sane value for sensors when no explicitly defined low_limit or high_limit can be found during discovery. Both switch control structures used in those two functions have empty case statements which means that if one of those matches, it's going to fall through and run the code for each subsequent case until a `break` is reached. For example, when we call `function sensor_low_limit(dbm, -13.036)` it will return the value `-12.3842` instead of `null`. That is because there will be a match at `case 'dbm':` which falls through all the way to `case 'cooling':`, where it performs `$limit = -13.036 * 0.95` before hitting a `break`. Changed behaviour =================== Removed `power_consumed` and `count` guessed low_limit and high_limit, I personally added those sensor classes in PR #9471 when I didn't understand that a switch control structure has fall-through behaviour so I can guarantee that guessing limits for those is a mistake on my behalf. It should not be there, only power_factor can have guessed limits. Apologies for the issue, I'm still a beginning programmer! Furthermore, I removed guessed high_limit values for `current` and `power` because these are supposed to draw higher values as more devices or components are installed on for example a PDU or a chassis. Finally, I removed guessed low_limit and high_limit for `dbm` sensors, there is a much too large variance in power budget on commercially available optical transceivers for there to be a sensible window where you can guess these values. * Documentation on adding sensor classes. * Update test data - sensor limit changes @ 30212d2
2019-06-21 16:03:27 +02:00
Create and populate new files for the sensor class in the following places:
- `includes/discovery/sensors/$class/`: create the folder where advanced php-based discovery files are stored. Not used for yaml discovery.
- `includes/html/graphs/device/$class.inc.php`: define unit names used in RRDtool graphs.
- `includes/html/graphs/sensor/$class.inc.php`: define various [parameters](https://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html) for RRDtool graphs.
- `includes/html/pages/device/health/$class.inc.php`
- `includes/html/pages/device/overview/sensors/$class.inc.php`
- `includes/html/pages/health/$class.inc.php`