feature: Send collected data to graphite server (#6201)

* Initial support for graphite

* Enable graphite include

* fixed typos.

* Fixed port naming to graphite metric names

* Added documentation for Graphite

* added documentation for graphite

* fixed style

* replace / with _ in interface names for graphite

* sets default graphite port

* adds rrd-name tags to the metric, otherwise metrics get lost

* add suggested storage schema for graphite

* add whitespace

* Updated to show some output

* bad english
This commit is contained in:
Falk Stern
2017-03-22 16:35:44 +01:00
committed by Tony Murray
parent e7057ecea5
commit affe5090f4
7 changed files with 104 additions and 2 deletions

View File

@@ -0,0 +1,32 @@
source: Extensions/Graphite.md
# Enabling support for Graphite.
This module sends all metrics to a remote graphite service. You need something like Grafana for graphing.
### What you don't get
- Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.
RRD will continue to function as normal so LibreNMS itself should continue to function as normal.
### Configuration
```php
$config['graphite']['enable'] = true;
$config['graphite']['host'] = 'your.graphite.server';
$config['graphite']['port'] = 2003; // this defaults to 2003 and is usually not needed
$config['graphite']['prefix'] = 'your.metric.prefix';
```
Your metric path can be prefixed if required, otherwise the metric path for Graphite will be in the form of
`hostname.measurement.fieldname`, interfaces will be stored as `hostname.ports.ifName.fieldname`.
The same data then stored within rrd will be sent to Graphite and recorded. You can then create graphs within Grafana
to display the information you need.
### Graphite Configuration
As LibreNMS updates its metrics every 5 minutes, the following addition to your storage-schemas.conf is suggested.
```
[network]
pattern = your\.metric\.prefix\..*
retentions = 5m:30d,15m:90d,1h:1y
```

View File

@@ -67,4 +67,5 @@ function data_update($device, $measurement, $tags, $fields)
rrdtool_data_update($device, $measurement, $tags, $fields);
influx_update($device, $measurement, rrd_array_filter($tags), $fields);
graphite_update($device, $measurement, $tags, $fields);
} // data_update

View File

@@ -397,7 +397,7 @@ $config['network_map_vis_options'] = '{
"damping": 0.4,
"avoidOverlap": 1
},
"repulsion": {
"centralGravity": 0.2,
"springLength": 250,
@@ -413,7 +413,7 @@ $config['network_map_vis_options'] = '{
"springConstant": 0.2,
"damping": 0.07
},
"maxVelocity": 50,
"minVelocity": 0.4,
"solver": "hierarchicalRepulsion",
@@ -905,3 +905,6 @@ $config['influxdb']['verifySSL'] = false;
// Xirrus - Disable station/client polling if true as it may take a long time on larger/heavily used APs.
$config['xirrus_disable_stations'] = false;
// Graphite default port
$config['graphite']['port'] = 2003;

44
includes/graphite.inc.php Normal file
View File

@@ -0,0 +1,44 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2017 Falk Stern <https://github.com/fstern/ >
*
* 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. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
function graphite_update($device, $measurement, $tags, $fields)
{
global $graphite, $config;
if ($graphite !== false) {
$timestamp = time();
$graphite_prefix = $config['graphite']['prefix'];
// metrics will be built as prefix.hostname.measurement.field value timestamp
// metric fields can not contain . as this is used by graphite as a field separator
$hostname = preg_replace('/\./', '_', $device['hostname']);
$measurement = preg_replace(array('/\./', '/\//'), '_', $measurement);
$measurement = preg_replace('/\|/', '.', $measurement);
$measurement_name = preg_replace('/\./', '_', $tags['rrd_name']);
if (is_array($measurement_name)) {
$ms_name = implode(".", $measurement_name);
} else {
$ms_name = $measurement_name;
}
// remove the port-id tags from the metric
if (preg_match('/^port-id\d+/', $ms_name)) {
$ms_name = "";
}
foreach ($fields as $k => $v) {
$metric = implode(".", array_filter(array($graphite_prefix, $hostname, $measurement, $ms_name, $k)));
$line = implode(" ", array($metric, $v, $timestamp));
d_echo("Sending $line\n");
fwrite($graphite, $line . "\n");
}
}
}

View File

@@ -47,6 +47,7 @@ require_once $install_dir . '/includes/common.php';
require $install_dir . '/includes/dbFacile.php';
require $install_dir . '/includes/rrdtool.inc.php';
require $install_dir . '/includes/influxdb.inc.php';
require $install_dir . '/includes/graphite.inc.php';
require $install_dir . '/includes/datastore.inc.php';
require $install_dir . '/includes/billing.php';
require $install_dir . '/includes/syslog.php';

View File

@@ -751,6 +751,7 @@ foreach ($ports as $port) {
$fields['ifOutOctets_rate'] = $port['ifOutOctets_rate'];
influx_update($device, 'ports', rrd_array_filter($tags), $fields);
graphite_update($device, 'ports|' . $ifName, $tags, $fields);
// End Update IF-MIB
// Update PAgP

View File

@@ -110,12 +110,28 @@ if (isset($options['f'])) {
$config['noinfluxdb'] = true;
}
if (isset($options['g'])) {
$config['nographite'] = true;
}
if ($config['noinfluxdb'] !== true && $config['influxdb']['enable'] === true) {
$influxdb = influxdb_connect();
} else {
$influxdb = false;
}
if ($config['nographite'] !== true && $config['graphite']['enable'] === true) {
$graphite = fsockopen($config['graphite']['host'], $config['graphite']['port']);
if ($graphite !== false) {
echo "Connection made to {$config['graphite']['host']} for Graphite support\n";
} else {
echo "Connection to {$config['graphite']['host']} has failed, Graphite support disabled\n";
$config['nographite'] = true;
}
} else {
$graphite = false;
}
rrdtool_initialize();
echo "Starting polling run:\n\n";
@@ -141,6 +157,10 @@ $poller_end = microtime(true);
$poller_run = ($poller_end - $poller_start);
$poller_time = substr($poller_run, 0, 5);
if ($graphite !== false) {
fclose($graphite);
}
if ($polled_devices) {
dbInsert(array('type' => 'poll', 'doing' => $doing, 'start' => $poller_start, 'duration' => $poller_time, 'devices' => $polled_devices, 'poller' => $config['distributed_poller_name'] ), 'perf_times');
}