More collectd and pfSense Fun!

This is an old post!

This post is over 2 years old. Solutions referenced in this article may no longer be valid. Please consider this when utilizing any information referenced here.

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

Did this article 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.

Comments (0)

Interested in why you can't leave comments on my blog? Read the article about why comments are uniquely terrible and need to die. If you are still interested in commenting on this article, feel free to reach out to me directly and/or share it on social media.

Contact Me
Share It

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!