API returns billing traffic from interface when interface is not reachable

This librenms crontab job uses the getValue function for picking up data traffic with snmp_get:
*/5 * * * * librenms /opt/librenms/poll-billing.php >> /dev/null 2>&1

And sometimes it runs into a device that has no reachability and when it does, it looks to reference a last value for the interface’s octet traffic and reports traffic when it should report 0 traffic.

Well, I looked at the getValue function code in /opt/librenms/poll-billing.php for a few minutes, and it looks like it needs an else or additional “if(! is_numeric($value))” for when the interface was not reachable, so no traffic would be reported while the interface was not reachable with snmp_get.

First check for in/out traffic in octets with 64-bit counters (high capacity (HC)), (ifHCInOctets/ifHCOutOctets), and if no value, then check octet traffic for 32-bit counters (ifInOctets/ifOutOctets), but if still no value, librenms evidently is looking at ifSpeed and returns calculated values using previous octet in/out numbers… So, that’s why I am thinking we need to add an additional if to value the $value variable to 0.

function getValue($host, $port, $id, $inout)
{
$oid = ‘IF-MIB::ifHC’ . $inout . ‘Octets.’ . $id;
$device = dbFetchRow(‘SELECT * from devices WHERE hostname = ? LIMIT 1’, [$host]);
$value = snmp_get($device, $oid, ‘-Oqv’);
if (! is_numeric($value)) {
$oid = ‘IF-MIB::if’ . $inout . ‘Octets.’ . $id;
$value = snmp_get($device, $oid, ‘-Oqv’);
}
if (! is_numeric($value)) {. //<=====================
$value = 0; //<=====================
} //<=====================
return $value;
}//end getValue()

Let me know what you think about this, because it is challenging the reputation of librenms’s billing module.

See the attached example for when the billing module reports 2.13TB usage for a period, but when I look the interface that’s used in the bill, the interface reports 18.09GB for the same period. For 20 hours (December 11 12:00 to December 12 09:00), neither graph shows traffic, but the billing graph and API reports the false 2.13TB total_data traffic for the current billing month. During that 20 hour period, librenms billing module reported total data used by that interface as 104,658,565,644 octets per hour - exactly the same number of octets for each of those 20 hours. And, please understand - that interface was down, 100% off-line.

Please let me know if I can get you anything else on this.

librenms poller running the crontab job:
Version 1.70.1-6-g9ccb707 - Thu Dec 17 2020 15:17:59 GMT-0600
Database Schema 2020_11_02_164331_add_powerstate_enum_to_vminfo (191)
Web Server nginx/1.16.1
PHP 7.4.13
MySQL 10.4.12-MariaDB
Laravel 8.11.2
RRDtool 1.6.0

Thanks,
Kevin Crothers
Billing_vs_Interface_octets_lte1

I edited /opt/librenms/includes/billing.php on the poller that runs the /opt/librenms/poll-billing.php and /opt/librenms/billing-calculate.php scripts so the getValue function is this:

function getValue($host, $port, $id, $inout)
{
    $oid = 'IF-MIB::ifHC' . $inout . 'Octets.' . $id;
    $device = dbFetchRow('SELECT * from `devices` WHERE `hostname` = ? LIMIT 1', [$host]);
    $value = snmp_get($device, $oid, '-Oqv');

    if (! is_numeric($value)) {
        $oid = 'IF-MIB::if' . $inout . 'Octets.' . $id;
        $value = snmp_get($device, $oid, '-Oqv');
    }

    if (! is_numeric($value)) {
        $value = 0;
    }
        
    return $value;
}//end getValue()

and all is working where when an interface is not reachable the in and out octets for that interface are reported as 0.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.