mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
feature: Added ZFS support for FreeBSD (#7938)
* add the ZFS graphs * And now the ZFS non-graph stuff. Still need to move it over to using JSON. * Now uses JSON. * use stripslashes as SNMPD loves to slash up the JSON * Document ZFS. * very minor formatting cleanup * minor formatting cleanup and remove a bit of code from when I was mucking around debugging it all
This commit is contained in:
@@ -42,6 +42,7 @@ Different applications support a variety of ways to collect data: by direct conn
|
||||
1. [Unbound](#unbound) - Agent
|
||||
1. [UPS-nut](#ups-nut) - SNMP extend
|
||||
1. [UPS-apcups](#ups-apcups) - SNMP extend
|
||||
1. [ZFS](#zfs) - SNMP extend
|
||||
|
||||
### Apache
|
||||
Either use SNMP extend or use the agent.
|
||||
@@ -953,3 +954,22 @@ extend sdfsinfo /etc/snmp/sdfsinfo
|
||||
4. Restart snmpd on your host
|
||||
|
||||
5. On the device page in Librenms, edit your host and check the `SDFS info` under the Applications tab or wait for it to be auto-discovered.
|
||||
|
||||
### ZFS
|
||||
|
||||
###### SNMP Extend
|
||||
1. Copy the perl script to the desired host (the host must be added to LibreNMS devices)
|
||||
```
|
||||
wget https://github.com/librenms/librenms-agent/raw/master/snmp/zfs-freebsd -O /etc/snmp/zfs-freebsd
|
||||
```
|
||||
|
||||
2. Make the script executable (chmod +x /etc/snmp/zfs-freebsd)
|
||||
|
||||
3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:
|
||||
```
|
||||
extend zfs /etc/snmp/zfs-freebsd
|
||||
```
|
||||
|
||||
4. Restart snmpd on your host
|
||||
|
||||
At this time, only FreeBSD is support. Linux support is eventually planned.
|
||||
|
@@ -132,6 +132,9 @@ function nicecase($item)
|
||||
case 'freeradius':
|
||||
return 'FreeRADIUS';
|
||||
|
||||
case 'zfs':
|
||||
return 'ZFS';
|
||||
|
||||
default:
|
||||
return ucfirst($item);
|
||||
}
|
||||
@@ -1663,3 +1666,28 @@ function generate_stacked_graphs($transparency = '88')
|
||||
return array('transparency' => '', 'stacked' => '-1');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ZFS pools for a device... just requires the device ID
|
||||
* an empty return means ZFS is not in use or there are currently no pools
|
||||
* @param $device_id
|
||||
* @return array
|
||||
*/
|
||||
function get_zfs_pools($device_id)
|
||||
{
|
||||
$options=array(
|
||||
'filter' => array(
|
||||
'type' => array('=', 'zfs'),
|
||||
),
|
||||
);
|
||||
|
||||
$component=new LibreNMS\Component();
|
||||
$zfsc=$component->getComponents($device_id, $options);
|
||||
|
||||
if (isset($zfsc[$device_id])) {
|
||||
$id = $component->getFirstComponentID($zfsc, $device_id);
|
||||
return json_decode($zfsc[$device_id][$id]['pools']);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
71
html/includes/graphs/application/zfs_arc_cache_hits.inc.php
Normal file
71
html/includes/graphs/application/zfs_arc_cache_hits.inc.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'hits/second';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand',
|
||||
'ds' => 'demand_data_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand Meta',
|
||||
'ds' => 'demand_meta_hits',
|
||||
);
|
||||
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'MRU',
|
||||
'ds' => 'mru_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'MRU Ghost',
|
||||
'ds' => 'mru_ghost_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'MFU',
|
||||
'ds' => 'mfu_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'MFU Ghost',
|
||||
'ds' => 'mfu_ghost_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch',
|
||||
'ds' => 'pre_data_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch Meta',
|
||||
'ds' => 'pre_meta_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Anonymous',
|
||||
'ds' => 'anon_hits',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'ARC',
|
||||
'ds' => 'arc_hits',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = '% of Hits';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Anon Used',
|
||||
'ds' => 'anon_hits_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Most Recent',
|
||||
'ds' => 'mru_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Most Frequent',
|
||||
'ds' => 'mfu_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'MRU Ghost',
|
||||
'ds' => 'mru_ghost_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'MFU Ghost',
|
||||
'ds' => 'mfu_ghost_per',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = '% of Hits';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand',
|
||||
'ds' => 'demand_hits_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch',
|
||||
'ds' => 'pre_hits_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand Meta',
|
||||
'ds' => 'meta_hits_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch Meta',
|
||||
'ds' => 'pre_meta_hits_per',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
45
html/includes/graphs/application/zfs_arc_cache_miss.inc.php
Normal file
45
html/includes/graphs/application/zfs_arc_cache_miss.inc.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'misses/second';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand',
|
||||
'ds' => 'demand_data_misses',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand Meta',
|
||||
'ds' => 'demand_meta_misses',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch',
|
||||
'ds' => 'pre_data_misses',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch Meta',
|
||||
'ds' => 'pre_meta_misses',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'ARC',
|
||||
'ds' => 'arc_misses',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = '% of Misses';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand',
|
||||
'ds' => 'demand_misses_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch',
|
||||
'ds' => 'pre_misses_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Demand Meta',
|
||||
'ds' => 'meta_misses_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Prefetch Meta',
|
||||
'ds' => 'pre_meta_misses_per',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
40
html/includes/graphs/application/zfs_arc_efficiency.inc.php
Normal file
40
html/includes/graphs/application/zfs_arc_efficiency.inc.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'percent';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Cache Hit',
|
||||
'ds' => 'cache_hits_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Cache Miss',
|
||||
'ds' => 'cache_miss_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Actual Hit',
|
||||
'ds' => 'actual_hit_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Data Demand',
|
||||
'ds' => 'data_demand_per',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
40
html/includes/graphs/application/zfs_arc_misc.inc.php
Normal file
40
html/includes/graphs/application/zfs_arc_misc.inc.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'per second';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Deleted',
|
||||
'ds' => 'deleted',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Recycle Misses',
|
||||
'ds' => 'recycle_miss',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Evict Skip',
|
||||
'ds' => 'evict_skip',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Mutex Skip',
|
||||
'ds' => 'mutex_skip',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
40
html/includes/graphs/application/zfs_arc_size.inc.php
Normal file
40
html/includes/graphs/application/zfs_arc_size.inc.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'bytes';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'ARC Size',
|
||||
'ds' => 'arc_size',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Target Size',
|
||||
'ds' => 'target_size',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Target Max',
|
||||
'ds' => 'target_size_max',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Target Min',
|
||||
'ds' => 'target_size_min',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'bytes';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Frequently Used',
|
||||
'ds' => 'mfu_size',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Recently Used',
|
||||
'ds' => 'p',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
35
html/includes/graphs/application/zfs_arc_size_per.inc.php
Normal file
35
html/includes/graphs/application/zfs_arc_size_per.inc.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = '% of Max';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'ARC Size%',
|
||||
'ds' => 'arc_size_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Target Size%',
|
||||
'ds' => 'target_size_per',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Target Min%',
|
||||
'ds' => 'min_size_per',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
25
html/includes/graphs/application/zfs_pool_cap.inc.php
Normal file
25
html/includes/graphs/application/zfs_pool_cap.inc.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'percent';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id'], $vars['pool']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Capacity',
|
||||
'ds' => 'cap',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
25
html/includes/graphs/application/zfs_pool_frag.inc.php
Normal file
25
html/includes/graphs/application/zfs_pool_frag.inc.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'percent';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id'], $vars['pool']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Frag',
|
||||
'ds' => 'frag',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
40
html/includes/graphs/application/zfs_pool_space.inc.php
Normal file
40
html/includes/graphs/application/zfs_pool_space.inc.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$unit_text = 'bytes';
|
||||
$colours = 'psychedelic';
|
||||
$dostack = 0;
|
||||
$printtotal = 0;
|
||||
$addarea = 1;
|
||||
$transparency = 15;
|
||||
|
||||
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app['app_id'], $vars['pool']));
|
||||
|
||||
|
||||
$rrd_list=array();
|
||||
if (rrdtool_check_rrd_exists($rrd_filename)) {
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Size',
|
||||
'ds' => 'size',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Allocated',
|
||||
'ds' => 'alloc',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Free',
|
||||
'ds' => 'free',
|
||||
);
|
||||
$rrd_list[]=array(
|
||||
'filename' => $rrd_filename,
|
||||
'descr' => 'Expand Size',
|
||||
'ds' => 'expandsz',
|
||||
);
|
||||
} else {
|
||||
d_echo('RRD "'.$rrd_filename.'" not found');
|
||||
}
|
||||
|
||||
require 'includes/graphs/generic_multi_line.inc.php';
|
@@ -283,6 +283,19 @@ $graphs['freeradius'] = array(
|
||||
'queue',
|
||||
);
|
||||
|
||||
$graphs['zfs'] = array(
|
||||
'arc_misc',
|
||||
'arc_size',
|
||||
'arc_size_per',
|
||||
'arc_size_breakdown',
|
||||
'arc_efficiency',
|
||||
'arc_cache_hits_by_list',
|
||||
'arc_cache_hits_by_type',
|
||||
'arc_cache_misses_by_type',
|
||||
'arc_cache_hits',
|
||||
'arc_cache_miss',
|
||||
);
|
||||
|
||||
print_optionbar_start();
|
||||
|
||||
echo "<span style='font-weight: bold;'>Apps</span> » ";
|
||||
|
83
html/pages/device/apps/zfs.inc.php
Normal file
83
html/pages/device/apps/zfs.inc.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
global $config;
|
||||
|
||||
$pools=get_zfs_pools($device['device_id']);
|
||||
|
||||
$link_array = array(
|
||||
'page' => 'device',
|
||||
'device' => $device['device_id'],
|
||||
'tab' => 'apps',
|
||||
'app' => 'zfs',
|
||||
);
|
||||
|
||||
print_optionbar_start();
|
||||
|
||||
echo generate_link('ARC', $link_array);
|
||||
echo '| Pools:';
|
||||
$pool_int=0;
|
||||
while (isset($pools[$pool_int])) {
|
||||
$pool=$pools[$pool_int];
|
||||
$label=$pool;
|
||||
|
||||
if ($vars['pool'] == $pool) {
|
||||
$label='>>'.$pool.'<<';
|
||||
}
|
||||
|
||||
$pool_int++;
|
||||
|
||||
$append='';
|
||||
if (isset($pools[$pool_int])) {
|
||||
$append=', ';
|
||||
}
|
||||
|
||||
echo generate_link($label, $link_array, array('pool'=>$pool)).$append;
|
||||
}
|
||||
|
||||
print_optionbar_end();
|
||||
|
||||
if (!isset($vars['pool'])) {
|
||||
$graphs = array(
|
||||
'zfs_arc_misc' => 'ARC misc',
|
||||
'zfs_arc_size' => 'ARC size in bytes',
|
||||
'zfs_arc_size_per' => 'ARC size, percent of max size',
|
||||
'zfs_arc_size_breakdown' => 'ARC size breakdown',
|
||||
'zfs_arc_efficiency' => 'ARC efficiency',
|
||||
'zfs_arc_cache_hits_by_list' => 'ARC cache hits by list',
|
||||
'zfs_arc_cache_hits_by_type' => 'ARC cache hits by type',
|
||||
'zfs_arc_cache_misses_by_type' => 'ARC cache misses by type',
|
||||
'zfs_arc_cache_hits' => 'ARC cache hits',
|
||||
'zfs_arc_cache_miss' => 'ARC cache misses',
|
||||
);
|
||||
} else {
|
||||
$graphs = array(
|
||||
'zfs_pool_space'=>'Pool Space',
|
||||
'zfs_pool_cap'=>'Pool Capcity',
|
||||
'zfs_pool_frag'=>'Pool Fragmentation',
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($graphs as $key => $text) {
|
||||
$graph_type = $key;
|
||||
$graph_array['height'] = '100';
|
||||
$graph_array['width'] = '215';
|
||||
$graph_array['to'] = $config['time']['now'];
|
||||
$graph_array['id'] = $app['app_id'];
|
||||
$graph_array['type'] = 'application_'.$key;
|
||||
|
||||
if (isset($vars['pool'])) {
|
||||
$graph_array['pool']=$vars['pool'];
|
||||
}
|
||||
|
||||
|
||||
echo '<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">'.$text.'</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">';
|
||||
include 'includes/print-graphrow.inc.php';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
}
|
197
includes/polling/applications/zfs.inc.php
Normal file
197
includes/polling/applications/zfs.inc.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
use LibreNMS\RRD\RrdDefinition;
|
||||
|
||||
echo ' zfs ';
|
||||
|
||||
$name = 'zfs';
|
||||
$app_id = $app['app_id'];
|
||||
$options = '-O qv';
|
||||
$mib = 'NET-SNMP-EXTEND-MIB';
|
||||
$oid = 'nsExtendOutputFull.3.122.102.115';
|
||||
$json = snmp_get($device, $oid, $options, $mib);
|
||||
|
||||
$zfs=json_decode(stripslashes($json), true);
|
||||
|
||||
$rrd_name = array('app', $name, $app_id);
|
||||
$rrd_def = RrdDefinition::make()
|
||||
->addDataset('deleted', 'DERIVE', 0)
|
||||
->addDataset('evict_skip', 'DERIVE', 0)
|
||||
->addDataset('mutex_skip', 'DERIVE', 0)
|
||||
->addDataset('recycle_miss', 'DERIVE', 0)
|
||||
->addDataset('arc_size', 'GAUGE', 0)
|
||||
->addDataset('target_size_max', 'GAUGE', 0)
|
||||
->addDataset('target_size_min', 'GAUGE', 0)
|
||||
->addDataset('target_size', 'GAUGE', 0)
|
||||
->addDataset('target_size_per', 'GAUGE', 0)
|
||||
->addDataset('arc_size_per', 'GAUGE', 0)
|
||||
->addDataset('target_size_arat', 'GAUGE', 0)
|
||||
->addDataset('min_size_per', 'GAUGE', 0)
|
||||
->addDataset('mfu_size', 'GAUGE', 0)
|
||||
->addDataset('p', 'GAUGE', 0)
|
||||
->addDataset('rec_used_per', 'GAUGE', 0)
|
||||
->addDataset('freq_used_per', 'GAUGE', 0)
|
||||
->addDataset('arc_hits', 'DERIVE', 0)
|
||||
->addDataset('arc_misses', 'DERIVE', 0)
|
||||
->addDataset('demand_data_hits', 'DERIVE', 0)
|
||||
->addDataset('demand_data_misses', 'DERIVE', 0)
|
||||
->addDataset('demand_meta_hits', 'DERIVE', 0)
|
||||
->addDataset('demand_meta_misses', 'DERIVE', 0)
|
||||
->addDataset('mfu_ghost_hits', 'DERIVE', 0)
|
||||
->addDataset('mfu_hits', 'DERIVE', 0)
|
||||
->addDataset('mru_ghost_hits', 'DERIVE', 0)
|
||||
->addDataset('mru_hits', 'DERIVE', 0)
|
||||
->addDataset('pre_data_hits', 'DERIVE', 0)
|
||||
->addDataset('pre_data_misses', 'DERIVE', 0)
|
||||
->addDataset('pre_meta_hits', 'DERIVE', 0)
|
||||
->addDataset('pre_meta_misses', 'DERIVE', 0)
|
||||
->addDataset('anon_hits', 'DERIVE', 0)
|
||||
->addDataset('arc_accesses_total', 'DERIVE', 0)
|
||||
->addDataset('demand_data_total', 'DERIVE', 0)
|
||||
->addDataset('pre_data_total', 'DERIVE', 0)
|
||||
->addDataset('real_hits', 'DERIVE', 0)
|
||||
->addDataset('cache_hits_per', 'GAUGE', 0)
|
||||
->addDataset('cache_miss_per', 'GAUGE', 0)
|
||||
->addDataset('actual_hit_per', 'GAUGE', 0)
|
||||
->addDataset('data_demand_per', 'GAUGE', 0)
|
||||
->addDataset('data_pre_per', 'GAUGE', 0)
|
||||
->addDataset('anon_hits_per', 'GAUGE', 0)
|
||||
->addDataset('mru_per', 'GAUGE', 0)
|
||||
->addDataset('mfu_per', 'GAUGE', 0)
|
||||
->addDataset('mru_ghost_per', 'GAUGE', 0)
|
||||
->addDataset('mfu_ghost_per', 'GAUGE', 0)
|
||||
->addDataset('demand_hits_per', 'GAUGE', 0)
|
||||
->addDataset('pre_hits_per', 'GAUGE', 0)
|
||||
->addDataset('meta_hits_per', 'GAUGE', 0)
|
||||
->addDataset('pre_meta_hits_per', 'GAUGE', 0)
|
||||
->addDataset('demand_misses_per', 'GAUGE', 0)
|
||||
->addDataset('pre_misses_per', 'GAUGE', 0)
|
||||
->addDataset('meta_misses_per', 'GAUGE', 0)
|
||||
->addDataset('pre_meta_misses_per', 'GAUGE', 0);
|
||||
|
||||
$fields = array(
|
||||
'deleted' => $zfs{deleted},
|
||||
'evict_skip' => $zfs{evict_skip},
|
||||
'mutex_skip' => $zfs{mutex_skip},
|
||||
'recycle_miss' => $zfs{recycle_miss},
|
||||
'arc_size' => $zfs{arc_size},
|
||||
'target_size_max' => $zfs{target_size_max},
|
||||
'target_size_min' => $zfs{target_size_min},
|
||||
'target_size' => $zfs{target_size},
|
||||
'target_size_per' => $zfs{target_size_per},
|
||||
'arc_size_per' => $zfs{arc_size_per},
|
||||
'target_size_arat' => $zfs{target_size_arat},
|
||||
'min_size_per' => $zfs{min_size_per},
|
||||
'mfu_size' => $zfs{mfu_size},
|
||||
'p' => $zfs{p},
|
||||
'rec_used_per' => $zfs{rec_used_per},
|
||||
'freq_used_per' => $zfs{freq_used_per},
|
||||
'arc_hits' => $zfs{arc_hits},
|
||||
'arc_misses' => $zfs{arc_misses},
|
||||
'demand_data_hits' => $zfs{demand_data_hits},
|
||||
'demand_data_misses' => $zfs{demand_data_misses},
|
||||
'demand_meta_hits' => $zfs{demand_meta_hits},
|
||||
'demand_meta_misses' => $zfs{demand_meta_misses},
|
||||
'mfu_ghost_hits' => $zfs{mfu_ghost_hits},
|
||||
'mfu_hits' => $zfs{mfu_hits},
|
||||
'mru_ghost_hits' => $zfs{mru_ghost_hits},
|
||||
'mru_hits' => $zfs{mru_hits},
|
||||
'pre_data_hits' => $zfs{pre_data_hits},
|
||||
'pre_data_misses' => $zfs{pre_data_misses},
|
||||
'pre_meta_hits' => $zfs{pre_meta_hits},
|
||||
'pre_meta_misses' => $zfs{pre_meta_misses},
|
||||
'anon_hits' => $zfs{anon_hits},
|
||||
'arc_accesses_total' => $zfs{arc_accesses_total},
|
||||
'demand_data_total' => $zfs{demand_data_total},
|
||||
'pre_data_total' => $zfs{pre_data_total},
|
||||
'real_hits' => $zfs{real_hits},
|
||||
'cache_hits_per' => $zfs{cache_hits_per},
|
||||
'cache_miss_per' => $zfs{cache_miss_per},
|
||||
'actual_hit_per' => $zfs{actual_hit_per},
|
||||
'data_demand_per' => $zfs{data_demand_per},
|
||||
'data_pre_per' => $zfs{data_pre_per},
|
||||
'anon_hits_per' => $zfs{anon_hits_per},
|
||||
'mru_per' => $zfs{mru_per},
|
||||
'mfu_per' => $zfs{mfu_per},
|
||||
'mru_ghost_per' => $zfs{mru_ghost_per},
|
||||
'mfu_ghost_per' => $zfs{mfu_ghost_per},
|
||||
'demand_hits_per' => $zfs{demand_hits_per},
|
||||
'pre_hits_per' => $zfs{pre_hits_per},
|
||||
'meta_hits_per' => $zfs{meta_hits_per},
|
||||
'pre_meta_hits_per' => $zfs{pre_meta_hits_per},
|
||||
'demand_misses_per' => $zfs{demand_misses_per},
|
||||
'pre_misses_per' => $zfs{pre_misses_per},
|
||||
'meta_misses_per' => $zfs{meta_misses_per},
|
||||
'pre_meta_misses_per' => $zfs{pre_meta_misses_per},
|
||||
);
|
||||
|
||||
$tags = array('name' => $name, 'app_id' => $app_id, 'rrd_def' => $rrd_def, 'rrd_name' => $rrd_name);
|
||||
data_update($device, 'app', $tags, $fields);
|
||||
|
||||
//
|
||||
// process additional info returned
|
||||
//
|
||||
|
||||
$pools=array();
|
||||
$pool_rrd_def = RrdDefinition::make()
|
||||
->addDataset('size', 'GAUGE', 0)
|
||||
->addDataset('alloc', 'GAUGE', 0)
|
||||
->addDataset('free', 'GAUGE', 0)
|
||||
->addDataset('expandsz', 'GAUGE', 0)
|
||||
->addDataset('frag', 'GAUGE', 0)
|
||||
->addDataset('cap', 'GAUGE', 0)
|
||||
->addDataset('dedup', 'GAUGE', 0);
|
||||
|
||||
$pools_int=0;
|
||||
while (isset($zfs{'pools'}{$pools_int})) {
|
||||
$pools[]=$zfs{'pools'}{$pools_int}{'name'};
|
||||
$rrd_name = array('app', $name, $app_id, $zfs{'pools'}{$pools_int}{'name'});
|
||||
$fields = array(
|
||||
'size' => $zfs{'pools'}{$pools_int}{'size'},
|
||||
'alloc' => $zfs{'pools'}{$pools_int}{'alloc'},
|
||||
'free' => $zfs{'pools'}{$pools_int}{'free'},
|
||||
'expandsz' => $zfs{'pools'}{$pools_int}{'expandsz'},
|
||||
'frag' => $zfs{'pools'}{$pools_int}{'frag'},
|
||||
'cap' => $zfs{'pools'}{$pools_int}{'cap'},
|
||||
'dedup' => $zfs{'pools'}{$pools_int}{'dedup'},
|
||||
);
|
||||
$tags = array('name' => $name, 'app_id' => $app_id, 'rrd_def' => $pool_rrd_def, 'rrd_name' => $rrd_name);
|
||||
data_update($device, 'app', $tags, $fields);
|
||||
|
||||
$pools_int++;
|
||||
}
|
||||
|
||||
//
|
||||
// component processing for ZFS
|
||||
//
|
||||
$device_id=$device['device_id'];
|
||||
$options=array(
|
||||
'filter' => array(
|
||||
'device_id' => array('=', $device_id),
|
||||
'type' => array('=', 'zfs'),
|
||||
),
|
||||
);
|
||||
|
||||
$component=new LibreNMS\Component();
|
||||
$components=$component->getComponents($device_id, $options);
|
||||
|
||||
// if no pools, delete zfs components
|
||||
if (empty($pools)) {
|
||||
if (isset($components[$device_id])) {
|
||||
foreach ($components[$device_id] as $component_id => $_unused) {
|
||||
$component->deleteComponent($component_id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isset($components[$device_id])) {
|
||||
$zfsc = $components[$device_id];
|
||||
} else {
|
||||
$zfsc = $component->createComponent($device_id, 'zfs');
|
||||
}
|
||||
|
||||
$id = $component->getFirstComponentID($zfsc);
|
||||
$zfsc[$id]['label'] = 'ZFS';
|
||||
$zfsc[$id]['pools'] = json_encode($pools);
|
||||
|
||||
$component->setComponentPrefs($device_id, $zfsc);
|
||||
}
|
Reference in New Issue
Block a user