Skip to content

thermal_zone: Skip zones with per-zone read errors - #3807

Open
neoLsH wants to merge 1 commit into
prometheus:masterfrom
neoLsH:thermal-readerrors
Open

thermal_zone: Skip zones with per-zone read errors#3807
neoLsH wants to merge 1 commit into
prometheus:masterfrom
neoLsH:thermal-readerrors

Conversation

@neoLsH

@neoLsH neoLsH commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Makes the thermal_zone collector respect procfs' per-zone ReadErrors, so a thermal zone whose sysfs attributes could not be read is skipped instead of being exported as a bogus 0°C.

Background

procfs.ClassThermalZoneStats returns every globbed thermal_zone<N> and records per-zone sysfs read failures in the ReadErrors field (an errors.Join of the type/policy/temp/mode/passive read errors). This is the outcome of prometheus/procfs#712 ("skip failed zones") and the later refactor in prometheus/procfs#794.

The collector currently ignores ReadErrors and unconditionally emits float64(stats.Temp)/1000.0. When a zone's temp read fails (offline zone, transient driver error, permission issue, etc.), procfs leaves Temp at 0, so node_exporter exports node_thermal_zone_temp 0 — a silently wrong reading that can trigger false "low temperature" alerts.

The fix

for _, stats := range thermalZones {
    if stats.ReadErrors != nil {
        c.logger.Debug("Skipping thermal zone with read errors", ...)
        continue
    }
    ch <- ...Temp...
}

Only zones whose attributes were read successfully are exported.

Interaction with #3657

#3657 added syscall.EINVAL to the whole-collector error path. This PR is complementary and does not change that behavior: procfs deliberately does not record EINVAL from a temp read in ReadErrors (see the !errors.Is(err, os.ErrInvalid) guard in parseClassThermalZone), so an EINVAL zone still has ReadErrors == nil and continues to be reported with Temp == 0, exactly as #3657 intended. This PR only affects zones with genuine read failures that procfs does flag in ReadErrors.

Testing

  • GOOS=linux go build ./... && go vet ./collector && go test -c ./collector are clean.
  • The existing e2e fixture (thermal_zone0, a healthy zone with ReadErrors == nil) is unaffected: it still exports node_thermal_zone_temp{...} 12.376, so the e2e golden output does not change.
  • Note: thermal_zone has no unit test today and procfs/sysfs is Linux-only, so a macOS-local runtime test isn't possible; verification relies on Linux CI (build + e2e). I kept the change minimal and did not add a failed-zone fixture to the shared fixtures/sys tree to avoid perturbing the e2e golden output. Happy to add a dedicated Linux unit test using a temp-dir sysfs fixture if reviewers prefer.

Signed-off-by: neoLsH 43921685+neoLsH@users.noreply.github.com

procfs surfaces per-zone sysfs read failures via the ReadErrors field of
ClassThermalZoneStats, following the original "skip failed zones" intent
of prometheus/procfs#712 and the later error-handling refactor in
prometheus/procfs#794. The thermal_zone collector ignored this field and
unconditionally reported stats.Temp, so a zone whose temp file could not
be read (offline zone, transient driver error, permission issue, etc.)
was exported as a bogus 0 Celsius instead of being dropped. Such a fake
reading can trigger false low-temperature alerts.

Skip zones with a non-nil ReadErrors and log them at debug level, so only
zones whose temperature was read successfully are exported.

This is complementary to prometheus#3657 and does not change its behavior: procfs
deliberately does not record EINVAL from a temp read in ReadErrors, so an
EINVAL zone still has ReadErrors == nil and keeps being reported with
Temp == 0, exactly as prometheus#3657 intended. Only genuine per-zone read failures
that procfs flags in ReadErrors are affected here.

Signed-off-by: neoLsH <43921685+neoLsH@users.noreply.github.com>
@neoLsH

neoLsH commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@SuperQ friendly ping — small fix so thermal zones with sysfs read errors get skipped instead of exported as a bogus 0°C. Complements #3657 (EINVAL zones are unaffected). CI is green.

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.

1 participant