Did something happen with LibreNMS on May 27 2026?

I have about 120 devices in LibreNMS and 4 of those devices are NTI environmental sensors that have been attached to LibreNMS for about 3 years. I’ve been able to previously see data from day 1 of adding those devices to Libre but all of a sudden I checked, today, and data for all 4 devices only goes back to May 27, 2026. The Recent events for one of the devices shows 2026-05-27 Sensor Added. I did not delete and re-add all the sensors on the 27th, if I did, I wouldn’t be here. I’m the only admin of this system.

I randomly checked other network devices and I have data that is several years old going back to day 1 of those specific devices. One was a random firewall I clicked on and the other was a random switch that I clicked on.

Whatever happened on 5-27-26 happened to all 4 of my NTI environmental devices.

Any ideas?

Thanks.

Most likely your device didn’t send the expected data back when discovery ran so the sensors were removed and then re-added.

Why would discovery run on May 27th? I just lost 3 years worth of stats, which is disappointing.

That doesn’t make sense. Graph data is stored in a way that if the sensor is removed and re-added it would still use the same data file.

The only thing I could think of is if the SNMP data from the device changed in some significant way.

You should check for the rrd files, you can rename or merge them to restore the data. Rrds are only deleted if you have rrd cleanup enabled.

Can you help me out? I did not change SNMP values or do anything with the devices. It is only these 4 devices (that I can tell, so far) that had their historical data wiped on 5-27. I’m not sure how to find the rrd files, rename/re-associate with the current devices. The handful of random devices that I have checked have all the historical data.

What NTI devices are you using?

Support was added for additional models and that merge took place on the 26th, but that shouldn’t have caused you to lose data for any existing ones. Were you using Custom OIDs to monitor them, or had you customized your nti.yaml file to add support and it was possibly overwritten?

No customizations were made that I recall, I really don’t modify the system because I’m clueless with coding, files, etc. I would only do something if someone provided cookbook instructions.

NTI device is e-micro-trh(p)

Thanks.

Interesting. My devices show up in librenms and I can get to the main device page for each NTI sensor, but when I click on the temp graph it takes me to a page that says “Whoops looks like something went wrong.”

I last checked this page on 7-3-26 and it was working so it looks like some type of update broke the graph page for temp data (at least for temperature, I will check other pages for this device).

24 hours later, the graphs are working again. No historical data, that is done, but the graphs appear.

It seems like you should probably change to the monthly release.

I’m fine with the defaults. If I can’t control features/issues then it doesn’t matter if I see the issue daily or the end of the month. Ironically, I was monitoring this specific device over the weekend, but aside from this one off, I don’t monitor the graphs that closely, but I do like the data to be there when I need it. Also, if something breaks on a monthly release I have to wait 1 more month for the fix if a fix is in the works. I prefer how it is today that way the fix arrives w/o having to wait a month. Obviously there are pros/cons to daily vs monthly.

Sure, you just seem sensitive to breakage and most breakage happens in daily and is resolved in a single day or a few. It is very rare a monthly release has a bad issue and we usually release a patch release if it is bad enough.

As for your data. Can you show the full log of both times the sensor was added. We need to know why your sensors changed.

As I mentioned, it is likely your data is in an RRD file on your system and could be recovered.

You did mention that but I don’t know how to recover RRD info. I have no idea when these sensors were added, its been years.

I did a little research for you.

It seems a contributor did change the indexes in this PR, but it was missed in review.

This PR by the same contributor attempted to change indexes again, but it was caught this time.

So you probably have rrd files named like this in the device rrd folder:
sensor-<class>-intSensorEntry.<number>.rrd
sensor-<class>-intSensorValue.<number>.rrd

The Entry one holds the old data.
I had an LLM write a merge script for you. No guarantees this won’t delete all your data, etc.

#!/usr/bin/env bash

set -e

CLASSES=("temperature" "humidity")

# Helper function to extract explicit timestamp and data pairs natively
extract_data_via_fetch() {
    local file="$1"
    
    # Extract the last 5 years of historical data to capture the entire timeline
    rrdtool fetch "$file" AVERAGE --start now-5years --end now | awk '
        /^[0-9]+/ {
            ts = $1
            sub(/:$/, "", ts) # Strip trailing colon from timestamp
            
            v = $2
            gsub(/^[ \t]+|[ \t]+$/, "", v)
            
            if (v != "" && tolower(v) != "nan" && v != "-nan") {
                print ts "," v
            }
        }
    '
}

for cls in "${CLASSES[@]}"; do
    for old in sensor-"$cls"-intSensorEntry.*.rrd; do
        [ -e "$old" ] || continue

        new="${old/intSensorEntry/intSensorValue}"
        bak="${new}.bak"

        if [ ! -f "$new" ] && [ ! -f "$bak" ]; then
            echo "Skipping ${old}: no matching new file or backup found"
            continue
        fi

        echo "Reconstructing and stitching layout for ${old} -> ${new}"

        # 1. Manage the pristine backup file safely
        if [ ! -f "$bak" ]; then
            cp -p "$new" "$bak"
        fi

        # 2. Extract and combine datasets into a single sorted sequential stream
        combined_data=$(mktemp)
        
        {
            extract_data_via_fetch "$old"
            extract_data_via_fetch "$bak"
        } | sort -nu -t',' -k1,1 > "$combined_data"

        if [ ! -s "$combined_data" ]; then
            echo "  Warning: No data found to merge for ${old}."
            rm -f "$combined_data"
            continue
        fi

        # 3. Find the oldest timestamp to use as the database birth date
        first_ts=$(head -n 1 "$combined_data" | cut -d',' -f1)
        start_origin=$((first_ts - 300))

        # 4. Clone exact core parameters from production file layout
        step_size=$(rrdtool info "$bak" | awk '/^step =/ {print $3}')
        heartbeat=$(rrdtool info "$bak" | awk -F'.' '/^ds\[sensor\].minimal_heartbeat =/ {print $2}' | awk '{print $3}')
        
        # 5. DYNAMICALLY HARVEST ALL 13 RRAs FROM PRODUCTION METADATA
        # This loops through all rra definitions and formats them back into RRDtool creation syntax
        rra_definitions=$(rrdtool info "$bak" | awk '
            /^rra\[[0-9]+\]\.cf =/ { rra=$1; cf=$3; gsub(/"/, "", cf) }
            /^rra\[[0-9]+\]\.rows =/ { rows=$3 }
            /^rra\[[0-9]+\]\.pdp_per_row =/ { pdp=$3 }
            /^rra\[[0-9]+\]\.xff =/ { xff=$3 
                printf "RRA:%s:%s:%s:%s ", cf, xff, pdp, rows
            }
        ')

        # 6. Build a temporary blank clone containing all 13 original archives
        tmp_rrd=$(mktemp --suffix=.rrd)
        rm -f "$tmp_rrd"

        # Dynamically execute the create string with all harvested RRAs
        rrdtool create "$tmp_rrd" --start "$start_origin" --step "$step_size" \
            DS:sensor:GAUGE:"$heartbeat":U:U \
            $rra_definitions

        # 7. Stream the chronological data securely straight into the clean structure
        # RRDtool will natively handle recalculating the averages, min, max, and last states
        while IFS=',' read -r ts val; do
            rrdtool update "$tmp_rrd" "${ts}:${val}" 2>/dev/null
        done < "$combined_data"

        # 8. Replace active file with the complete timeline history
        mv "$tmp_rrd" "$new"
        chmod 644 "$new"

        rm -f "$combined_data"
    done
done

echo "Done."
1 Like

Thanks for doing all that. I used an LLM to assist with the script and the LLM found HTML in the script but once you confirmed the data was likely still there and provided the script, I explained the issue to the LLM and it assisted me with merging the historical data and current data files and now everything is back to showing the historical data.

For anyone else reading, I can’t say that exact script ran and solved the issue, but it did get me in the right direction with the LLM so I’m going to mark that as the answer.

Thanks again for your assistance.

1 Like