More collectd and pfSense Fun!

Extending my post from last year, here’s some additional data I’m grabbing from pfSense and stuffing into collectd via a script. I’m now grabbing:

  • DHCP Leases
  • CPU Temperature
  • Thermal Zone Temperature
  • SSD Drive Temperature
  • UPS information (via NUT)

Here’s the exec script:

<?php
$hostname = getenv("COLLECTD_HOSTNAME");
$interval = getenv("COLLECTD_INTERVAL");
$content = file_get_contents("/var/dhcpd/var/db/dhcpd.leases");

$leases = [];
$lease_count = 0;

if (preg_match_all("/lease (?<ip>[\d\.]+) \{\s+starts \d (?<starts>[\d\/]+\s[\d\:]+);\s+ends \d (?<ends>[\d\/]+\s[\d\:]+);/is", $content, $matches)) {
    foreach($matches["ip"] as $key => $ip) {
        $end_date = strtotime($matches["ends"][$key]);
        if ($end_date > time()) {
            $leases[$ip] = [$ip, $matches["starts"][$key], $matches["ends"][$key]];
        }
    }

    $lease_count = count($leases);
}

echo "PUTVAL \"$hostname/dhcp/gauge-dhcp_leases\" interval=$interval N:$lease_count\n";

$keys = ["dev.cpu.1.temperature", "dev.cpu.0.temperature"];

foreach ($keys as $key) {
    $temp = exec("sysctl $key");
    if (preg_match('!([0-9\.]+)C$!i', $temp, $matches)) {
        $temp = $matches[1];
        echo "PUTVAL \"$hostname/cpu_temp/gauge-$key\" interval=$interval N:$temp\n";
    }
}

$keys = ["hw.acpi.thermal.tz1.temperature", "hw.acpi.thermal.tz0.temperature"];

foreach ($keys as $key) {
    $temp = exec("sysctl $key");
    if (preg_match('!([0-9\.]+)C$!i', $temp, $matches)) {
        $temp = $matches[1];
        echo "PUTVAL \"$hostname/sensors/temperature-$key\" interval=$interval N:$temp\n";
    }
}

$temp = exec('sudo smartctl -a /dev/ada0 | grep 0x0022 | grep Temp | awk \'{print $10}\'');
echo "PUTVAL \"$hostname/hddtemp/temperature-ada0\" interval=$interval N:$temp\n";

ob_start();
passthru("upsc [email protected]");
$data = ob_get_clean();

if (preg_match_all("!(.*): (.*)!i", $data, $foo)) {
    $find_keys = ["battery.charge", "battery.runtime", "battery.voltage", "input.voltage", "ups.load"];

    $keyed = array_combine($foo[1], $foo[2]);
    foreach ($find_keys as $key) {
        if (isset($keyed[$key])) {
            $temp = $keyed[$key];
            echo "PUTVAL \"$hostname/ups/gauge-$key\" interval=$interval N:$temp\n";
        }
    }
}

fclose(STDOUT);

This combined with the data that collectd can natively collect you can assemble into a pretty neat dashboard using Grafana. Here’s one I’ve been building for the firewall.

Next step will be nagios or some other kind of alerting, especially on temperature. That’s the big thing I really want to monitor with a lot of this stuff, since my networking equipment is in an upstairs closet that does not hae the best ventilation (especially during the summer).

Did something I wrote help you out?

That's great! I don't earn any money from this site - I run no ads, sell no products and participate in no affiliate programs. I do this solely because it's fun; I enjoy writing and sharing what I learn.

All the same, if you found this article helpful and want to show your appreciation, here's my Amazon.com wishlist.

Read More

Collecting Data From pfSense Using collectd

So I’ve recently been on a graphing thing, wanting to collect all kind of data from my home network. And collectd seems to be a good candidate for doing that. With a huge number of plugins, it can collect and send just about anything you can think of to a time series database (I’m using InfluxDB for this). But, there’s a significant hole in my data collection: my pfSense firewall. Well, not anymore!