More collectd and pfSense Fun!

By · Published · collectd, pfsense, networking, php

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:

$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";

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";


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).

( Comments )

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 wishlist.

Related Posts

Collecting Data From pfSense Using collectd

Collecting Unifi controller data with collectd

comments powered by Disqus