Reporting / rrd - refactor existing code (#7836)

Add RRD package with a simple factory class and a basic construct to define different rrd output types we support.
This package contains the following:

* RRD/Types -- Output definitions, responsible for generating RRD structures and feeding data
* RRD/Stats -- Statistics gathering classes
* Factory -- binds types and statistics together. 

On my end on a simple test this is roughly 40% faster than running /var/db/rrd/updaterrd.sh, which makes caching of metadata (config access) less relevant.

The new script should be able to replace all existing rrd cruft and supports a debug mode to find discrepanties between defined outputs in types and collected data in stats.

```
Usage: updaterrd.php [-h] [-d]
            -d debug mode, output errors to stdout
```
This commit is contained in:
Ad Schellevis 2024-09-02 16:40:47 +02:00 committed by GitHub
parent 54ccb747cd
commit 895e58ff25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 1741 additions and 549 deletions

24
plist
View File

@ -1080,7 +1080,31 @@
/usr/local/opnsense/scripts/health/definitions/system-processor.xml
/usr/local/opnsense/scripts/health/fetchData.py
/usr/local/opnsense/scripts/health/flush_rrd.py
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Factory.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Base.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/GatewayQuality.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Interfaces.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Mbuf.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Memory.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Ntp.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/OpenVPN.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Processor.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/States.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Stats/Temperature.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Base.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/GatewayQuality.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Mbuf.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Memory.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Ntp.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/OpenVPN.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Packets.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Processor.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/States.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Temperature.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Traffic.php
/usr/local/opnsense/scripts/health/library/OPNsense/RRD/Types/Wireless.php
/usr/local/opnsense/scripts/health/listReports.py
/usr/local/opnsense/scripts/health/updaterrd.php
/usr/local/opnsense/scripts/interfaces/capture.py
/usr/local/opnsense/scripts/interfaces/carp_global_status.php
/usr/local/opnsense/scripts/interfaces/carp_set_status.php

View File

@ -296,12 +296,14 @@ function core_cron()
$jobs[]['autocron'] = array('/usr/local/sbin/configctl -d firmware changelog cron', '0', '22');
/**
* rrd graph collector, only execute when script is present and not locked by rrd_configure()
* rrd graph collector, only schedule execution when enabled
*/
$jobs[]['autocron'] = [
'test -e /var/db/rrd/updaterrd.sh && /usr/local/bin/flock -n -E 1 /var/db/rrd/updaterrd.sh /var/db/rrd/updaterrd.sh',
'*'
];
if (!empty($config['rrd']['enable'])) {
$jobs[]['autocron'] = [
'/usr/local/bin/flock -n -E 0 -o /tmp/updaterrd.lock /usr/local/opnsense/scripts/health/updaterrd.php',
'*'
];
}
if (!empty($config['system']['rrdbackup']) && $config['system']['rrdbackup'] > 0) {
$jobs[]['autocron'] = array(

View File

@ -26,538 +26,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
function rrd_create($rrdcreatecmd)
{
@mkdir('/var/db/rrd', 0775);
@chown('/var/db/rrd', 'nobody');
$rrdcreateoutput = array();
$rrdcreatereturn = 0;
exec("$rrdcreatecmd 2>&1", $rrdcreateoutput, $rrdcreatereturn);
if ($rrdcreatereturn != 0) {
$rrdcreateoutput = implode(" ", $rrdcreateoutput);
log_msg(sprintf('RRD create failed exited with %s, the error is: %s', $rrdcreatereturn, $rrdcreateoutput), LOG_ERR);
}
unset($rrdcreateoutput);
return $rrdcreatereturn;
}
function rrd_configure($verbose = false, $bootup = false)
{
global $config;
service_log('Generating RRD graphs...', $verbose);
$rrddbpath = "/var/db/rrd/";
$traffic = "-traffic.rrd";
$packets = "-packets.rrd";
$states = "-states.rrd";
$wireless = "-wireless.rrd";
$proc = "-processor.rrd";
$mem = "-memory.rrd";
$mbuf = "-mbuf.rrd";
$cellular = "-cellular.rrd";
$vpnusers = "-vpnusers.rrd";
$ntpd = "ntpd.rrd";
$cputemp = "-cputemp.rrd";
$rrdtool = "/usr/local/bin/rrdtool";
$netstat = "/usr/bin/netstat";
$awk = "/usr/bin/awk";
$pfctl = "/sbin/pfctl";
$sysctl = "/sbin/sysctl";
$cpustats = "/usr/local/sbin/cpustats";
$ifconfig = "/sbin/ifconfig";
$ntpq = "/usr/local/sbin/ntpq";
$rrdtrafficinterval = 60;
$rrdwirelessinterval = 60;
$rrdpacketsinterval = 60;
$rrdstatesinterval = 60;
$rrdlbpoolinterval = 60;
$rrdprocinterval = 60;
$rrdmeminterval = 60;
$rrdmbufinterval = 60;
$rrdcellularinterval = 60;
$rrdvpninterval = 60;
$rrdntpdinterval = 60;
$rrdcputempinterval = 60;
$trafficvalid = $rrdtrafficinterval * 2;
$wirelessvalid = $rrdwirelessinterval * 2;
$packetsvalid = $rrdpacketsinterval * 2;
$statesvalid = $rrdstatesinterval * 2;
$procvalid = $rrdlbpoolinterval * 2;
$memvalid = $rrdmeminterval * 2;
$mbufvalid = $rrdmbufinterval * 2;
$cellularvalid = $rrdcellularinterval * 2;
$vpnvalid = $rrdvpninterval * 2;
$ntpdvalid = $rrdntpdinterval * 2;
$cputempvalid = $rrdcputempinterval * 2;
/* Assume 2*10GigE for now */
$downstream = 2500000000;
$upstream = 2500000000;
/* XXX: kill off traffic collectors, remove when we know the update required a reboot */
killbypid('/var/run/updaterrd.pid');
if (isset($config['rrd']['enable'])) {
/* create directory if needed */
if (!is_dir($rrddbpath)) {
mkdir($rrddbpath, 0775);
}
chown($rrddbpath, "nobody");
/* open file handle to update script and lock it in exclusive mode */
@touch('/var/db/rrd/updaterrd.sh');
$fobj = new \OPNsense\Core\FileObject('/var/db/rrd/updaterrd.sh', 'r+', 0755, LOCK_EX);
/* db update script */
$rrdupdatesh = "#!/bin/sh\n";
$rrdupdatesh .= "\n";
$rrdupdatesh .= "export TERM=dumb\n";
$rrdupdatesh .= "\n";
$ifdescrs = get_configured_interface_with_descr();
/* IPsec counters */
$ifdescrs['ipsec'] = "IPsec";
$ovpn_servers = (new OPNsense\OpenVPN\OpenVPN())->serverDevices();
foreach ($ovpn_servers as $ifname => $data) {
$ifdescrs[$ifname] = $data['descr'];
}
/* process all real and pseudo interfaces */
foreach ($ifdescrs as $ifname => $ifdescr) {
$temp = get_real_interface($ifname);
if ($temp != '') {
$realif = $temp;
}
/* TRAFFIC, set up the rrd file */
if (!file_exists("$rrddbpath$ifname$traffic")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
$rrdcreate .= "DS:inpass:COUNTER:$trafficvalid:0:$downstream ";
$rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream ";
$rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream ";
$rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream ";
$rrdcreate .= "DS:inpass6:COUNTER:$trafficvalid:0:$downstream ";
$rrdcreate .= "DS:outpass6:COUNTER:$trafficvalid:0:$upstream ";
$rrdcreate .= "DS:inblock6:COUNTER:$trafficvalid:0:$downstream ";
$rrdcreate .= "DS:outblock6:COUNTER:$trafficvalid:0:$upstream ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U:U:U:U:U");
}
$rrdupdatesh .= "\n";
$rrdupdatesh .= "# polling traffic for interface $ifname $realif IPv4/IPv6 counters \n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:";
$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$6 };/Out4\/Pass/ { b4po = \$6 };/In4\/Block/ { b4bi = \$6 };/Out4\/Block/ { b4bo = \$6 };\\\n";
$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$6 };/Out6\/Pass/ { b6po = \$6 };/In6\/Block/ { b6bi = \$6 };/Out6\/Block/ { b6bo = \$6 };\\\n";
$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
/* PACKETS, set up the rrd file */
if (!file_exists("$rrddbpath$ifname$packets")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
$rrdcreate .= "DS:inpass6:COUNTER:$packetsvalid:0:$downstream ";
$rrdcreate .= "DS:outpass6:COUNTER:$packetsvalid:0:$upstream ";
$rrdcreate .= "DS:inblock6:COUNTER:$packetsvalid:0:$downstream ";
$rrdcreate .= "DS:outblock6:COUNTER:$packetsvalid:0:$upstream ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U:U:U:U:U");
}
$rrdupdatesh .= "\n";
$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:";
$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n";
$rrdupdatesh .= "/In4\/Pass/ { b4pi = \$4 };/Out4\/Pass/ { b4po = \$4 };/In4\/Block/ { b4bi = \$4 };/Out4\/Block/ { b4bo = \$4 };\\\n";
$rrdupdatesh .= "/In6\/Pass/ { b6pi = \$4 };/Out6\/Pass/ { b6po = \$4 };/In6\/Block/ { b6bi = \$4 };/Out6\/Block/ { b6bo = \$4 };\\\n";
$rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n";
/* WIRELESS, set up the rrd file */
if (isset($config['interfaces'][$ifname]['wireless']['mode']) && $config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
if (!file_exists("$rrddbpath$ifname$wireless")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
}
$rrdupdatesh .= "\n";
$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
$rrdupdatesh .= "WIFI=`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\${WIFI}\n";
}
/* OpenVPN, set up the rrd file */
if (isset($ovpn_servers[$ifname])) {
if (!file_exists("$rrddbpath$ifname$vpnusers")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$vpnusers --step $rrdvpninterval ";
$rrdcreate .= "DS:users:GAUGE:$vpnvalid:0:10000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$vpnusers N:U");
}
$rrdupdatesh .= "\n";
$rrdupdatesh .= "# polling vpn users for interface $ifname\n";
$rrdupdatesh .= "list_current_users() {\n";
$rrdupdatesh .= " sleep 0.2\n";
$rrdupdatesh .= " echo \"status 2\"\n";
$rrdupdatesh .= " sleep 0.2\n";
$rrdupdatesh .= " echo \"quit\"\n";
$rrdupdatesh .= "}\n";
$rrdupdatesh .= "OVPN=`list_current_users | nc -U {$ovpn_servers[$ifname]['sockFilename']} | awk -F\",\" '/^CLIENT_LIST/ {print \$2}' | wc -l | awk '{print $1}'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$vpnusers N:\${OVPN}\n";
}
}
/* System only statistics */
$ifname = "system";
/* STATES, create pf states database */
if (! file_exists("$rrddbpath$ifname$states")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
}
/* the pf states gathering function. */
$rrdupdatesh .= "\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:`/usr/local/opnsense/scripts/system/rrd_pfstate_info.py`\n\n";
/* End pf states statistics */
/* CPU, create CPU statistics database */
if (!file_exists("$rrddbpath$ifname$proc")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
}
/* the CPU stats gathering function. */
$rrdupdatesh .= "CPU=`$cpustats | cut -f1-4 -d':'`\n";
/* Using ps uxaH will count all processes including system threads. Top was undercounting. */
$rrdupdatesh .= "PROCS=`ps uxaH | wc -l | awk '{print \$1;}'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$proc N:\${CPU}:\${PROCS}\n";
/* End CPU statistics */
/* Memory, create Memory statistics database */
if (!file_exists("$rrddbpath$ifname$mem")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
$rrdcreate .= "RRA:MIN:0.5:5:720 ";
$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
$rrdcreate .= "RRA:MAX:0.5:5:720 ";
$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
$rrdcreate .= "RRA:MAX:0.5:1440:2284";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
}
/* the Memory stats gathering function. */
$rrdupdatesh .= "MEM=`$sysctl -n vm.stats.vm.v_page_count vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count vm.stats.vm.v_free_count vm.stats.vm.v_cache_count vm.stats.vm.v_wire_count | ";
$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf ";
$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mem N:\${MEM}\n";
/* End Memory statistics */
/* mbuf, create mbuf statistics database */
if (!file_exists("$rrddbpath$ifname$mbuf")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$mbuf --step $rrdmbufinterval ";
$rrdcreate .= "DS:current:GAUGE:$mbufvalid:0:10000000 ";
$rrdcreate .= "DS:cache:GAUGE:$mbufvalid:0:10000000 ";
$rrdcreate .= "DS:total:GAUGE:$mbufvalid:0:10000000 ";
$rrdcreate .= "DS:max:GAUGE:$mbufvalid:0:10000000 ";
$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
$rrdcreate .= "RRA:MIN:0.5:5:720 ";
$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
$rrdcreate .= "RRA:MAX:0.5:5:720 ";
$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
$rrdcreate .= "RRA:MAX:0.5:1440:2284";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$mbuf N:U:U:U:U");
}
/* the mbuf stats gathering function. */
$rrdupdatesh .= "MBUF=`$netstat -m | ";
$rrdupdatesh .= " $awk '/mbuf clusters in use/ { gsub(/\//, \":\", $1); print $1; }'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$mbuf N:\${MBUF}\n";
/* End mbuf statistics */
/* End System statistics */
/* NTP, set up the ntpd rrd file */
if (isset($config['ntpd']['statsgraph'])) {
/* set up the ntpd rrd file */
if (!file_exists("$rrddbpath$ntpd")) {
$rrdcreate = "$rrdtool create $rrddbpath$ntpd --step $rrdntpdinterval ";
$rrdcreate .= "DS:offset:GAUGE:$ntpdvalid:-1000:1000 ";
$rrdcreate .= "DS:sjit:GAUGE:$ntpdvalid:0:1000 ";
$rrdcreate .= "DS:cjit:GAUGE:$ntpdvalid:0:1000 ";
$rrdcreate .= "DS:wander:GAUGE:$ntpdvalid:0:1000 ";
$rrdcreate .= "DS:freq:GAUGE:$ntpdvalid:0:1000 ";
$rrdcreate .= "DS:disp:GAUGE:$ntpdvalid:0:1000 ";
$rrdcreate .= "RRA:MIN:0.5:1:1200 ";
$rrdcreate .= "RRA:MIN:0.5:5:720 ";
$rrdcreate .= "RRA:MIN:0.5:60:1860 ";
$rrdcreate .= "RRA:MIN:0.5:1440:2284 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
$rrdcreate .= "RRA:MAX:0.5:1:1200 ";
$rrdcreate .= "RRA:MAX:0.5:5:720 ";
$rrdcreate .= "RRA:MAX:0.5:60:1860 ";
$rrdcreate .= "RRA:MAX:0.5:1440:2284 ";
rrd_create($rrdcreate);
unset($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ntpd N:U:U:U:U:U:U");
}
/* the ntp stats gathering function. */
$rrdupdatesh .= "\n";
$rrdupdatesh .= "$ntpq -c rv | $awk 'BEGIN{ RS=\",\"}{ print }' >> /tmp/ntp-rrdstats.$$\n";
$rrdupdatesh .= "NOFFSET=`grep offset /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
$rrdupdatesh .= "NFREQ=`grep frequency /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
$rrdupdatesh .= "NSJIT=`grep sys_jitter /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
$rrdupdatesh .= "NCJIT=`grep clk_jitter /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
$rrdupdatesh .= "NWANDER=`grep clk_wander /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
$rrdupdatesh .= "NDISPER=`grep rootdisp /tmp/ntp-rrdstats.$$ | awk 'BEGIN{FS=\"=\"}{print $2}'`\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ntpd \N:\${NOFFSET}:\${NSJIT}:\${NCJIT}:\${NWANDER}:\${NFREQ}:\${NDISPER}\n";
$rrdupdatesh .= "rm /tmp/ntp-rrdstats.$$\n";
$rrdupdatesh .= "\n";
}
/* End NTP statistics */
/* CPU Temperature */
/* the CPU Temperature gathering Function. */
/* Cpu Temp, create CPU Temperature database */
if (!file_exists("$rrddbpath$ifname$cputemp")) {
$rrdcreate = "$rrdtool create $rrddbpath$ifname$cputemp --step $rrdcputempinterval ";
$rrdcreate .= "DS:cpu0temp:GAUGE:$cputempvalid:-273:5000 ";
$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
$rrdcreate .= "RRA:LAST:0.5:1:1000 ";
$rrdcreate .= "RRA:LAST:0.5:5:1000 ";
$rrdcreate .= "RRA:LAST:0.5:60:1000 ";
$rrdcreate .= "RRA:LAST:0.5:720:3000 ";
rrd_create($rrdcreate);
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($bootup) {
mwexec("$rrdtool update $rrddbpath$ifname$cputemp N:U");
}
/* the CPU Temperature gathering function */
$rrdupdatesh .= "CPUTEMP=\$(/usr/local/opnsense/scripts/system/temperature.sh rrd)\n";
$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$cputemp N:\${CPUTEMP}\n";
/* end CPU Temp gathering */
/* Start gateway quality */
$rrdupdatesh .= <<<EOD
# Gateway quality graphs
for sock in /var/run/dpinger_*.sock;do
if [ ! -S "\$sock" ]; then
continue
fi
t=\$(/usr/bin/nc -U \$sock)
if [ -z "\$t" ]; then
continue
fi
gw=\$(echo "\$t" | awk '{ print \$1 }')
delay=\$(echo "\$t" | awk '{ print \$2 }')
stddev=\$(echo "\$t" | awk '{ print \$3 }')
loss=\$(echo "\$t" | awk '{ print \$4 }')
if echo "\$loss" | grep -Eqv '^[0-9]+\$'; then
loss="U"
fi
if echo "\$delay" | grep -Eqv '^[0-9]+\$'; then
delay="U"
else
# Convert delay from microseconds to seconds
delay=\$(echo "scale=7; \$delay / 1000 / 1000" | /usr/bin/bc)
fi
if echo "\$stddev" | grep -Eqv '^[0-9]+\$'; then
stddev="U"
else
# Convert stddev from microseconds to seconds
stddev=\$(echo "scale=7; \$stddev / 1000 / 1000" | /usr/bin/bc)
fi
{$rrdtool} update {$rrddbpath}\$gw-quality.rrd -t loss:delay:stddev N:\$loss:\$delay:\$stddev
done
EOD;
/* write the rrd update script */
$fobj->seek(0)->truncate(0)->write($rrdupdatesh);
unset($fobj);
} elseif (file_exists('/var/db/rrd/updaterrd.sh')) {
/* remove script, stop collecting. cron checks for existence if this file */
unlink('/var/db/rrd/updaterrd.sh');
}
$databases = glob("{$rrddbpath}/*.rrd");
foreach ($databases as $database) {
chown($database, "nobody");
}
service_log("done.\n", $verbose);
}
function rrd_create_gateway_quality($rrd_file, $unknown = false)
{
$rrdtool = '/usr/local/bin/rrdtool';
$rrdinterval = 60;
$valid = $rrdinterval * 2;
/* GATEWAY QUALITY, set up the rrd file */
if (!file_exists("$rrd_file")) {
$rrdcreate = "$rrdtool create $rrd_file --step $rrdinterval ";
$rrdcreate .= "DS:loss:GAUGE:$valid:0:100 ";
$rrdcreate .= "DS:delay:GAUGE:$valid:0:100000 ";
$rrdcreate .= "DS:stddev:GAUGE:$valid:0:100000 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1:1200 ";
$rrdcreate .= "RRA:AVERAGE:0.5:5:720 ";
$rrdcreate .= "RRA:AVERAGE:0.5:60:1860 ";
$rrdcreate .= "RRA:AVERAGE:0.5:1440:2284 ";
rrd_create($rrdcreate);
$unknown = true;
}
/* enter UNKNOWN values in the RRD so it knows we rebooted. */
if ($unknown) {
mwexec("$rrdtool update $rrd_file N:U:U:U");
}
}
function rrd_export()
{
$rrddbpath = '/var/db/rrd';

View File

@ -101,7 +101,6 @@ filter_configure_sync(true);
plugins_configure('monitor', true, [null, true]);
plugins_configure('vpn_map', true);
plugins_configure('bootup', true);
rrd_configure(true, true);
system_powerd_configure(true); /* XXX this seems misplaced */

View File

@ -117,4 +117,3 @@ if (is_ipaddr($cacheip) && $ip != $cacheip) {
plugins_configure('vpn_map', false, [$interface, 'inet']);
plugins_configure('newwanip_map', false, [$interface, 'inet']);
rrd_configure();

View File

@ -128,4 +128,3 @@ foreach ($interfaces as $interface) {
filter_configure_sync();
plugins_configure('vpn_map', false, [join(',', $interfaces), 'inet6']);
plugins_configure('newwanip_map', false, [join(',', $interfaces), 'inet6']);
rrd_configure();

View File

@ -56,7 +56,6 @@ system_routing_configure(true);
filter_configure_sync(true);
plugins_configure('local', true);
plugins_configure('vpn_map', true);
rrd_configure(true);
/* plugins service reload */
passthru('/usr/local/etc/rc.freebsd stop');

View File

@ -18,4 +18,3 @@ if (count($argv) > 1) {
}
webgui_configure_do(true);
rrd_configure(true);

View File

@ -0,0 +1,154 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD;
use ReflectionClass;
class TypeNotFound extends \Exception { }
/**
* RRD Factory class, offers access to RRD types and statistics.
*/
class Factory
{
/**
* gathered statistics
*/
private $stats = [];
/**
* @param string $type type of rrd graph to get
* @param string $target filename to store data in
* @return \OPNsense\RRD\Types\Base
* @throws TypeNotFound if the class is not found or has an improper type
*/
public function get(string $type, string $target)
{
try {
$cls = new ReflectionClass('\\OPNsense\\RRD\\Types\\'. $type);
if (!$cls->isInstantiable() || !$cls->isSubclassOf('OPNsense\\RRD\\Types\\Base')) {
throw new TypeNotFound(sprintf("%s not found", $type));
}
} catch (ReflectionException) {
throw new TypeNotFound(sprintf("%s not found", $type));
}
return $cls->newInstance($target);
}
/**
* collect statistics to feed to rrd, generates an array containing classnames including runtimes and payload
* for example: ['Mbuf'] => ['data' => [], 'runtime' => 0.1555]
* @return $this
*/
public function collect()
{
$this->stats = [];
foreach (glob(sprintf("%s/Stats/*.php", __DIR__)) as $filename) {
$classname = substr(basename($filename),0, -4);
$cls = new ReflectionClass('\\OPNsense\\RRD\\Stats\\'. $classname);
if ($cls->isInstantiable() && $cls->isSubclassOf('OPNsense\\RRD\\Stats\\Base')) {
try {
$start_time = microtime(true);
$obj = $cls->newInstance();
$tmp = $obj->run();
$this->stats[$classname] = [
'data' => $tmp,
'runtime' => microtime(true) - $start_time
];
} catch (\Error | \Exception $e) {
echo $e;
syslog(LOG_ERR, sprintf("Error collecting %s [%s]", $classname, $e));
}
}
}
return $this;
}
/**
* get gathered statistics for a specific collector
* @param string $name name of the collector, e.g. Mbuf
* @return array
*/
public function getData(string $name)
{
return isset($this->stats[$name]) ? $this->stats[$name]['data'] : [];
}
/**
* @return array collected statistics
*/
public function getRawStats()
{
return $this->stats;
}
/**
* update all registered RRD graphs
* @return $this
*/
public function updateAll($debug=false)
{
foreach (glob(sprintf("%s/Types/*.php", __DIR__)) as $filename) {
$classname = substr(basename($filename),0, -4);
$fclassname = '\\OPNsense\\RRD\\Types\\'. $classname;
try {
$cls = new ReflectionClass($fclassname);
if ($cls->isInstantiable() && $cls->isSubclassOf('OPNsense\\RRD\\Types\\Base')) {
$wants = call_user_func([$fclassname, 'wantsStats']);
$the_data = $this->getData($wants);
if (empty($the_data)) {
continue;
}
/**
* Because some data sets should be split into multiple targets, we need a facility to map
* (a part) of the dataset to the target.
*
* In most cases an RRD type results in a single target, in which case the 'type' knows where
* it should render the content to by default.
*
* If the type+stats combination results in multiple targets we need to leave this mapping
* somewhere, in which case the 'Type' is the most logical place
* as being responsible for the actual output.
*/
foreach (call_user_func([$fclassname, 'payloadSplitter'], $the_data) as $tfilename => $data) {
$obj = $cls->newInstance($tfilename);
$obj->create(); /* only creates when no target exists yet */
$obj->update($data, $debug);
}
}
} catch (\Error | \Exception $e) {
echo $e;
syslog(LOG_ERR, sprintf("Error instantiating %s [%s]", $classname, $e));
}
}
return $this;
}
}

View File

@ -0,0 +1,105 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
use OPNsense\Core\Config;
/**
* Stats collection
*/
abstract class Base
{
static array $metadata = [];
/**
* run simple shell command, expected to return json output
*/
protected function jsonShellCmd($cmd)
{
exec($cmd . ' 2>&1', $payload, $returncode);
if ($returncode == 0 && !empty($payload[0])) {
return json_decode($payload[0], true) ?? [];
}
return null;
}
/**
* run simple shell command
* @param string $cmd command to execute
* @return array output lines when returnvalue equals 0
*/
protected function shellCmd(string $cmd)
{
exec($cmd . ' 2>&1', $payload, $returncode);
if ($returncode == 0 && !empty($payload[0])) {
return $payload;
}
return [];
}
/**
* collect static generic metadata on init
*/
public function __construct()
{
if (empty(self::$metadata)) {
self::$metadata['interfaces'] = [];
self::$metadata['interfaces']['ipsec'] = ['name' => 'IPsec', 'if' => 'enc0'];
foreach (Config::getInstance()->object()->interfaces->children() as $ifname => $node) {
if (isset($node->enable)) {
self::$metadata['interfaces'][$ifname] = [
'name' => !empty((string)$node->descr) ? (string)$node->descr : $ifname,
'if' => (string)$node->if
];
/* relevant parts from get_real_interface() using in old rrd.inc */
if (isset($node->wireless) && !strstr((string)$node->if, '_wlan')) {
self::$metadata['interfaces'][$ifname]['if'] .= '_wlan0';
}
}
}
foreach ((new \OPNsense\OpenVPN\OpenVPN())->serverDevices() as $ifname => $data) {
self::$metadata['interfaces'][$ifname] = [
'name' => $data['descr'],
'if' => $ifname,
'openvpn_socket' => $data['sockFilename']
];
}
self::$metadata['ntp_statsgraph'] = empty((string)Config::getInstance()->object()->ntp->statsgraph);
}
}
/**
* run
*/
public function run()
{
throw new \Exception("Need to implement run()");
}
}

View File

@ -0,0 +1,57 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class GatewayQuality extends Base
{
public function run()
{
$result = [];
foreach (glob('/var/run/dpinger_*.sock') as $filename) {
$fp = @stream_socket_client("unix://{$filename}", $errno, $errstr, 1);
if (!$fp) {
continue;
}
$dinfo = '';
while (!feof($fp)) {
$dinfo .= fgets($fp, 1024);
}
fclose($fp);
$record = explode(' ', trim($dinfo));
$result[$record[0]] = [
'gwname' => $record[0],
'delay' => sprintf('%.07f', $record[1] / 1000.0 / 1000.0),
'stddev' => sprintf('%.07f', $record[2] / 1000.0 / 1000.0),
'loss' => $record[3]
];
}
return $result;
}
}

View File

@ -0,0 +1,47 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class Interfaces extends Base
{
public function run()
{
$result = [];
$data = $this->jsonShellCmd('/usr/local/opnsense/scripts/filter/pfstatistics.py interfaces');
if (!empty($data) && !empty($data['interfaces'])) {
$data = $data['interfaces'];
foreach (self::$metadata['interfaces'] as $ifname => $ifdata) {
if (isset($ifdata['if']) && !empty($data[$ifdata['if']])) {
$result[$ifname] = $data[$ifdata['if']];
}
}
}
return $result;
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class Mbuf extends Base
{
public function run()
{
$netstat = $this->shellCmd('/usr/bin/netstat -m');
if (!empty($netstat)) {
foreach ($netstat as $line) {
if (strpos($line, 'mbuf clusters in use') !== false) {
$tmp = explode('/', explode(' ', $line)[0]);
return [
'current' => $tmp[0],
'cache' => $tmp[1],
'total' => $tmp[2],
'max' => $tmp[3]
];
}
}
}
return [];
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class Memory extends Base
{
public function run()
{
$sysctls = [
'vm.stats.vm.v_page_count',
'vm.stats.vm.v_active_count',
'vm.stats.vm.v_inactive_count',
'vm.stats.vm.v_free_count',
'vm.stats.vm.v_cache_count',
'vm.stats.vm.v_wire_count'
];
$memory = $this->shellCmd('/sbin/sysctl ' . implode(' ', $sysctls));
if (!empty($memory)) {
$percentages = [];
$data = [];
foreach ($memory as $idx => $item) {
// strip vm.stats.vm.v_ and collect into $result
$tmp = explode(':', substr($item, 14));
$data[$tmp[0]] = trim($tmp[1]);
if ($idx > 0) {
$percentages[explode('_', $tmp[0])[0]] = ($data[$tmp[0]] / $data['page_count']) * 100.0;
}
}
return $percentages;
}
return [];
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class Ntp extends Base
{
public function run()
{
if (!self::$metadata['ntp_statsgraph']) {
return;
}
$data = [];
$ntpq = $this->shellCmd('/usr/local/sbin/ntpq -c rv');
if (!empty($ntpq)) {
$fieldmap = [
'offset' => 'offset',
'frequency' => 'freq',
'sys_jitter' => 'sjit',
'clk_jitter' => 'cjit',
'clk_wander' => 'wander',
'rootdisp' => 'disp'
];
foreach ($ntpq as $idx => $item) {
foreach (explode(',', $item) as $part) {
$tmp = explode('=', trim($part));
if (isset($fieldmap[$tmp[0]])) {
$data[$fieldmap[$tmp[0]]] = $tmp[1];
}
}
}
}
return $data;
}
}

View File

@ -0,0 +1,56 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class OpenVPN extends Base
{
public function run()
{
$result = [];
$data = $this->jsonShellCmd('/usr/local/opnsense/scripts/openvpn/ovpn_status.py --options server');
if (!empty($data) && !empty($data['server'])) {
$data = $data['server'];
foreach (self::$metadata['interfaces'] as $ifname => $ifdata) {
if (isset($ifdata['openvpn_socket'])) {
foreach ($data as $ovpn) {
if ($ovpn['socket'] == $ifdata['openvpn_socket']) {
$result[$ifname] = [
'users' => !empty($ovpn['client_list']) ? count($ovpn['client_list']) : 0
];
}
}
}
}
}
return $result;
}
}

View File

@ -0,0 +1,52 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class Processor extends Base
{
public function run()
{
$cpustats = $this->shellCmd('/usr/local/sbin/cpustats');
$ps = $this->shellCmd('/bin/ps uxaH');
if (!empty($cpustats) && !empty($ps)) {
$tmp = explode(':', $cpustats[0]);
return [
'user' => $tmp[0],
'nice' => $tmp[1],
'system' => $tmp[2],
'interrupt' => $tmp[3],
'processes' => count($ps)-1
];
}
return [];
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class States extends Base
{
public function run()
{
$data = $this->shellCmd('/usr/local/opnsense/scripts/system/rrd_pfstate_info.py');
if (!empty($data)) {
return explode(':', $data[0]);
}
return [];
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Stats;
class Temperature extends Base
{
public function run()
{
$data = $this->shellCmd(
'/sbin/sysctl -n dev.cpu.0.temperature hw.acpi.thermal.tz0.temperature hw.temperature.CPU'
);
if (!empty($data)) {
return [$data[0]];
}
return [];
}
}

View File

@ -0,0 +1,208 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
abstract class Base
{
/**
* standard dataset values when undefined.
*/
protected int $ds_heartbeat = 20;
protected int $ds_min = 0;
protected int $ds_max = 1000000000;
private string $filename;
protected static string $basedir = '/var/db/rrd/';
protected static string $stdfilename = '';
/**
* DS:ds-name:{GAUGE | COUNTER | DERIVE | DCOUNTER | DDERIVE | ABSOLUTE}:heartbeat:min:max
*/
private array $datasets = [];
/**
* RRA:{AVERAGE | MIN | MAX | LAST}:xff:steps:rows
*/
private array $round_robin_archives = [
['AVERAGE', 0.5, 1, 1200],
['AVERAGE', 0.5, 5, 720],
['AVERAGE', 0.5, 60, 1860],
['AVERAGE', 0.5, 1440, 2284],
];
/**
* @param array $ds datasets
*/
protected function setDatasets($ds)
{
$this->datasets = $ds;
}
/**
* @param array $rra datasets
*/
protected function setRRA($rra)
{
$this->round_robin_archives = $rra;
}
/**
* @param string $filename filename to link to this collection
*/
public function __construct(string $filename)
{
$this->filename = $filename;
}
/**
* Maps datasets (stats) to input a new type object requires
*
* @param array collected stats for the type
* @return \Iterator<string, array>
*/
public static function payloadSplitter(array $payload)
{
if (!empty(static::$stdfilename)) {
yield static::$basedir . static::$stdfilename => $payload;
}
}
/**
* @param string $name dataset name
* @param string $opp operation to use
* @param int $heartbeat heartbeat to use, default when null
* @param int $min min value to use, default when null
* @param int $max max value to use, default when null
* @return $this
*/
public function addDataset(
string $name,
string $opp,
?int $heartbeat=null,
?int $min=null,
?int $max=null
){
$this->datasets[] = [
$name,
$opp,
$heartbeat != null ? $heartbeat : $this->ds_heartbeat,
$min != null ? $min : $this->ds_min,
$max != null ? $max : $this->ds_max
];
return $this;
}
/**
* @param array $names list of names to add
* @param string $opp operation to use
* @param int $heartbeat heartbeat to use, default when null
* @param int $min min value to use, default when null
* @param int $max max value to use, default when null
* @return $this
*/
public function addDatasets(
array $names,
string $opp,
?int $heartbeat=null,
?int $min=null,
?int $max=null
){
foreach ($names as $name) {
$this->addDataset($name, $opp, $heartbeat, $min, $max);
}
return $this;
}
/**
* create or replace RRD database
* @param bool $overwrite overwrite when file exists
* @return $this
*/
public function create($overwrite=false)
{
if (!$overwrite && file_exists($this->filename)) {
return $this;
}
$cmd_text = sprintf('/usr/local/bin/rrdtool create %s --step %d ', $this->filename, 60);
foreach ($this->datasets as $dataset) {
$cmd_text .= 'DS:' . implode(':', $dataset) . ' ';
}
foreach ($this->round_robin_archives as $rra)
{
$cmd_text .= 'RRA:' . implode(':', $rra) . ' ';
}
$cmd_text .= ' 2>&1';
exec($cmd_text, $rrdcreateoutput, $rrdcreatereturn);
if ($rrdcreatereturn != 0) {
$rrdcreateoutput = implode(" ", $rrdcreateoutput);
syslog(
LOG_ERR,
sprintf('RRD create failed exited with %s, the error is: %s', $rrdcreatereturn, $rrdcreateoutput)
);
}
return $this;
}
/**
* update the dataset
* @param array $dataset [named] dataset to use
* @param bool $debug throw debug messages to stdout
* @return $this
*/
public function update(array $dataset = [], bool $debug=false)
{
$values = [];
$map_by_name = count($dataset) > 0 && !isset($dataset[0]);
foreach ($this->datasets as $idx => $ds) {
if ($map_by_name) {
$value = isset($dataset[$ds[0]]) ? $dataset[$ds[0]] : 'U';
} else {
$value = !empty($dataset) && isset($dataset[$idx]) ? $dataset[$idx] : 'U';
}
$values[] = $value;
if ($value == 'U' && $debug) {
echo sprintf("[%s] '%s' missing in datafeed\n", get_class($this), $ds[0]);
}
}
$cmd_text = sprintf('/usr/local/bin/rrdtool update %s N:%s 2>&1', $this->filename, implode(':', $values));
exec($cmd_text, $rrdcreateoutput, $rrdcreatereturn);
if ($rrdcreatereturn != 0 && $debug) {
echo sprintf("[cmd failed] %s\n", $cmd_text);
}
return $this;
}
/**
* @return string name of the Stats class this type requires data from.
*/
public static function wantsStats()
{
$tmp = explode('\\', static::class);
return array_pop($tmp);
}
}

View File

@ -0,0 +1,59 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class GatewayQuality extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 2500000000;
protected static string $stdfilename = '%s-quality.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['loss','delay','stddev'], 'GAUGE');
}
/**
* @inheritdoc
*/
public static function payloadSplitter(array $payload)
{
foreach ($payload as $gw => $data) {
yield static::$basedir . sprintf(static::$stdfilename, $gw) => $data;
}
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Mbuf extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 10000000;
protected static string $stdfilename = 'system-mbuf.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['current', 'cache', 'total', 'max'], 'GAUGE');
$this->setRRA([
['MIN', 0.5, 1, 1200],
['MIN', 0.5, 5, 720],
['MIN', 0.5, 60, 1860],
['MIN', 0.5, 1440, 2284],
['AVERAGE', 0.5, 1, 1200],
['AVERAGE', 0.5, 5, 720],
['AVERAGE', 0.5, 60, 1860],
['AVERAGE', 0.5, 1440, 2284],
['MAX', 0.5, 1, 1200],
['MAX', 0.5, 5, 720],
['MAX', 0.5, 60, 1860],
['MAX', 0.5, 1440, 2284],
]);
}
}

View File

@ -0,0 +1,63 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Memory extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 10000000;
protected static string $stdfilename = 'system-memory.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['active', 'inactive', 'free', 'cache', 'wire'], 'GAUGE');
$this->setRRA([
['MIN', 0.5, 1, 1200],
['MIN', 0.5, 5, 720],
['MIN', 0.5, 60, 1860],
['MIN', 0.5, 1440, 2284],
['AVERAGE', 0.5, 1, 1200],
['AVERAGE', 0.5, 5, 720],
['AVERAGE', 0.5, 60, 1860],
['AVERAGE', 0.5, 1440, 2284],
['MAX', 0.5, 1, 1200],
['MAX', 0.5, 5, 720],
['MAX', 0.5, 60, 1860],
['MAX', 0.5, 1440, 2284],
]);
}
}

View File

@ -0,0 +1,64 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Ntp extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 1000;
protected static string $stdfilename = 'ntpd.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDataset('offset', 'GAUGE', 120, -1000, 1000);
$this->addDatasets(['sjit', 'cjit', 'wander', 'freq', 'disp'], 'GAUGE');
$this->setRRA([
['MIN', 0.5, 1, 1200],
['MIN', 0.5, 5, 720],
['MIN', 0.5, 60, 1860],
['MIN', 0.5, 1440, 2284],
['AVERAGE', 0.5, 1, 1200],
['AVERAGE', 0.5, 5, 720],
['AVERAGE', 0.5, 60, 1860],
['AVERAGE', 0.5, 1440, 2284],
['MAX', 0.5, 1, 1200],
['MAX', 0.5, 5, 720],
['MAX', 0.5, 60, 1860],
['MAX', 0.5, 1440, 2284],
]);
}
}

View File

@ -0,0 +1,60 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class OpenVPN extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 10000;
protected static string $stdfilename = '%s-vpnusers.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['users'], 'GAUGE');
}
/**
* @inheritdoc
*/
public static function payloadSplitter(array $payload)
{
foreach ($payload as $intf => $data) {
yield static::$basedir . sprintf(static::$stdfilename, $intf) => $data;
}
}
}

View File

@ -0,0 +1,80 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Packets extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 2500000000;
protected static string $stdfilename = '%s-packets.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(
['inpass','outpass','inblock','outblock','inpass6','outpass6','inblock6','outblock6'],
'COUNTER'
);
}
/**
* Packets is a subcollection of Interfaces
*/
public static function wantsStats()
{
return 'Interfaces';
}
/**
* @inheritdoc
*/
public static function payloadSplitter(array $payload)
{
foreach ($payload as $intf => $data) {
$tmp = [
'inpass' => $data['in4_pass_packets'],
'outpass' => $data['out4_pass_packets'],
'inblock' => $data['in4_block_packets'],
'outblock' => $data['out4_block_packets'],
'inpass6' => $data['in6_pass_packets'],
'outpass6' => $data['out6_pass_packets'],
'inblock6' => $data['in6_block_packets'],
'outblock6' => $data['out6_block_packets']
];
yield static::$basedir . sprintf(static::$stdfilename, $intf) => $tmp;
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Processor extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 10000000;
protected static string $stdfilename = 'system-processor.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['user', 'nice', 'system', 'interrupt', 'processes'], 'GAUGE');
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class States extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 10000000;
protected static string $stdfilename = 'system-states.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['pfrate', 'pfstates', 'pfnat', 'srcip', 'dstip'], 'GAUGE');
}
}

View File

@ -0,0 +1,66 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Temperature extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = -273;
protected int $ds_max = 5000;
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['cpu0temp'], 'GAUGE');
$this->setRRA([
['MIN', 0.5, 1, 1200],
['MIN', 0.5, 5, 720],
['MIN', 0.5, 60, 1860],
['MIN', 0.5, 1440, 2284],
['AVERAGE', 0.5, 1, 1200],
['AVERAGE', 0.5, 5, 720],
['AVERAGE', 0.5, 60, 1860],
['AVERAGE', 0.5, 1440, 2284],
['MAX', 0.5, 1, 1200],
['MAX', 0.5, 5, 720],
['MAX', 0.5, 60, 1860],
['MAX', 0.5, 1440, 2284],
['LAST', 0.5, 1, 1200],
['LAST', 0.5, 5, 720],
['LAST', 0.5, 60, 1860],
['LAST', 0.5, 1440, 2284],
]);
}
}

View File

@ -0,0 +1,80 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Traffic extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 2500000000;
protected static string $stdfilename = '%s-traffic.rrd';
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(
['inpass','outpass','inblock','outblock','inpass6','outpass6','inblock6','outblock6'],
'COUNTER'
);
}
/**
* Traffic is a subcollection of Interfaces
*/
public static function wantsStats()
{
return 'Interfaces';
}
/**
* @inheritdoc
*/
public static function payloadSplitter(array $payload)
{
foreach ($payload as $intf => $data) {
$tmp = [
'inpass' => $data['in4_pass_bytes'],
'outpass' => $data['out4_pass_bytes'],
'inblock' => $data['in4_block_bytes'],
'outblock' => $data['out4_block_bytes'],
'inpass6' => $data['in6_pass_bytes'],
'outpass6' => $data['out6_pass_bytes'],
'inblock6' => $data['in6_block_bytes'],
'outblock6' => $data['out6_block_bytes']
];
yield static::$basedir . sprintf(static::$stdfilename, $intf) => $tmp;
}
}
}

View File

@ -0,0 +1,48 @@
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\RRD\Types;
class Wireless extends Base
{
/**
* {@inheritdoc}
*/
protected int $ds_heartbeat = 120;
protected int $ds_min = 0;
protected int $ds_max = 1000;
/**
* {@inheritdoc}
*/
public function __construct(string $filename)
{
parent::__construct($filename);
$this->addDatasets(['snr','rate','channel'], 'GAUGE');
}
}

View File

@ -0,0 +1,73 @@
#!/usr/local/bin/php
<?php
/*
* Copyright (C) 2024 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* loader : add library path in this directory to our normal path */
require_once('/usr/local/opnsense/mvc/app/library/OPNsense/Autoload/Loader.php');
$phalcon_config = include('/usr/local/opnsense/mvc/app/config/config.php');
(new OPNsense\Autoload\Loader([
$phalcon_config->application->modelsDir,
$phalcon_config->application->libraryDir,
__DIR__ . '/library/'])
)->register();
/* end loader */
$opts = getopt('hd', [], $optind);
$args = array_slice($argv, $optind);
if (isset($opts['h'])) {
echo "Usage: updaterrd.php [-h] [-d]\n\n";
echo "\t-d debug mode, output errors to stdout\n";
exit(0);
}
$rrdcnf = OPNsense\Core\Config::getInstance()->object()->rrd;
if ($rrdcnf === null || !isset($rrdcnf->enable)) {
echo "RRD statistics disabled... exit\n";
exit(0);
}
$start_time = microtime(True);
if (!is_dir('/var/db/rrd')) {
@mkdir('/var/db/rrd', 0775);
@chown('/var/db/rrd', 'nobody');
}
$rrd_factory = new \OPNsense\RRD\Factory();
$rrd_factory->collect()->updateAll(isset($opts['d']));
if (isset($opts['d'])) {
$collect_time = 0.0;
echo sprintf("total runtime [seconds] \t: %0.2f\n", microtime(True) - $start_time);
foreach ($rrd_factory->getRawStats() as $name => $payload) {
$collect_time += $payload['runtime'];
}
echo sprintf("total collection [seconds] \t: %0.2f\n", $collect_time);
}

View File

@ -57,7 +57,7 @@ def ovpn_cmd(filename, cmd):
def ovpn_status(filename):
response = {}
response = {'socket': filename}
buffer = ovpn_cmd(filename, 'status 3')
if buffer is None:
return {'status': 'failed'}

View File

@ -46,5 +46,6 @@ if (set_networking_interfaces_ports()) {
filter_configure_sync(true);
plugins_configure('local', true);
plugins_configure('vpn_map', true);
rrd_configure(true);
/* rrd graphs depend on a cronjob */
system_cron_configure();
}

View File

@ -577,7 +577,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
system_routing_configure();
filter_configure();
plugins_configure('newwanip_map', false, [join(',', array_keys($toapplylist))]);
rrd_configure();
}
clear_subsystem_dirty('interfaces');

View File

@ -302,7 +302,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($changes > 0) {
// reload filter, rrd when interfaces have changed (original from apply action)
filter_configure();
rrd_configure();
}
header(url_safe('Location: /interfaces_assign.php'));
exit;

View File

@ -76,8 +76,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
unbound_configure_do();
} else {
plugins_configure('monitor');
rrd_configure();
/* XXX: rrd graphs depend on a cronjob, we can probably remove this in a future version when the job is unconditional */
/* rrd graphs depend on a cronjob */
system_cron_configure();
}
}

View File

@ -149,7 +149,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
write_config("Updated NTP Server Settings");
rrd_configure();
ntpd_configure_do();
system_cron_configure();