Skip to content

Log NUT query failures and save the UPS Poller ID - #58

Merged
bmfmancini merged 2 commits into
developfrom
fix/nut-failure-logging-poller-id
Oct 16, 2026
Merged

bmfmancini merged 2 commits into
developfrom
fix/nut-failure-logging-poller-id

Conversation

@TheWitness

@TheWitness TheWitness commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Description

Two fixes found while investigating #57, where newly added NUT UPSes stay "Unknown" with nothing in the Cacti log:

  1. Log NUT query failures. collect_nut_ups_data() stored the reason a NUT query failed in apcupsd_ups.error_message and printed it only with -d. The poller runs from the poller_bottom hook with its output discarded, so an unreachable or misconfigured upsd left nothing in the Cacti log. It now writes WARNING: NUT query for UPS <name> (<host>:<port>) failed: <reason> (log type APCUPSD) before recording the failure. The NUT username and password are never included.
  2. Save the Poller ID. The UPS edit form displays a Poller ID field but form_save() never read it, so the choice was discarded and every UPS used the column default (poller 1). It is now validated (digits only) and stored when the field is posted. Changing the Poller ID of a UPS that is already linked to a Cacti Device is refused with an explanatory message: moving a device between pollers needs Cacti's own device handling (poller cache and remote replication), so the poller has to be changed on the device itself.

Both changes are in poller_apcupsd.php and upses.php, with source-assertion tests in tests/Unit/NutWiringTest.php, CHANGELOG entries under 1.4.0, and the new message added to locales/po/cacti.pot.

Related Issue

Fixes #57

Motivation and Context

"Unknown" is status 0, which means neither the success path (status 3) nor the failure path (status 1) of the NUT poll has run for that row. Every completed poller run also writes an APCUPSD STATS: line, so its absence points at the poller script not completing a run. With this change, failures that do occur are visible in the Cacti log, which makes the next report diagnosable. I checked develop's NUT client against a scripted fake upsd and it connected, parsed the variables and reported ONLINE, so the NUT protocol code itself looks sound.

If #57 persists after this change, run php plugins/apcupsd/poller_apcupsd.php -d as the Cacti poller user and look for the APCUPSD STATS: line in the Cacti log.

How Has This Been Tested?

  • php -l is clean on all changed PHP files.
  • Pest (Windows, PHP 8.4, Pest 5): 221 passed. The only other output is 4 socket-timeout warnings from NutClientTest, which exercises includes/nut.php and is unchanged by this PR.
  • New tests cover the log line (present, ordered before the status write, no credentials), the Poller ID save (validated and stored before sql_save()), and the linked-device guard.
  • Not tested against a live Cacti poller or a real upsd; the changes are small and covered by source-level assertions only.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation repository accordingly.

A failed NUT query only wrote to the UPS error_message column and -d output, so an unreachable upsd left nothing in the Cacti log; log a WARNING with the UPS, host, port and reason (never credentials). The UPS form displayed a Poller ID field that form_save() never stored; validate and save it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 20:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Linked-device reassignment remains unresolved, and distributed-poller behavior needs integration verification before approval.

1 open finding
What changed in this PR

Improves NUT failure diagnostics and saves UPS poller selections without claiming to resolve the reported “Unknown” status.

Changes:

  • Logs failed NUT queries to the Cacti log.
  • Validates and saves submitted Poller IDs.
  • Adds source-assertion tests and changelog entries.
File Description
upses.php Validates and stores Poller ID selections.
tests/​Unit/​NutWiringTest.php Adds logging and Poller ID source assertions.
poller_apcupsd.php Logs NUT query failures.
CHANGELOG.md Documents both fixes under 1.4.0.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread upses.php
Changing a UPS's Poller ID updated apcupsd_ups but left the linked device on the old poller, so collection and the device assignment could disagree. Moving a device between pollers needs Cacti's own device handling, so reject the change with an explanation and have the user change the poller on the device. Compare against the UPS's stored value so a device already moved elsewhere does not block unrelated edits.

Restructure the new tests as a compact dataset to avoid duplicating the neighbouring source-assertion tests (SonarCloud duplication gate), and add the new message to cacti.pot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sonarqubecloud

Copy link
Copy Markdown

@sonarqubecloud

Copy link
Copy Markdown

@bmfmancini
bmfmancini merged commit 4e2f670 into develop Oct 16, 2026
5 checks passed
@bmfmancini
bmfmancini deleted the fix/nut-failure-logging-poller-id branch October 16, 2026 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NUT UPSes polling is not working

3 participants