diff --git a/agent/sensors.go b/agent/sensors.go index 4265cc616..a50e99d4d 100644 --- a/agent/sensors.go +++ b/agent/sensors.go @@ -151,12 +151,24 @@ func (a *Agent) updateTemperatures(systemStats *system.Stats) { } systemStats.Temperatures = make(map[string]float64, len(temps)) + // claimed tracks every name handed out, including names of sensors that are + // dropped below, so a sensor's key never depends on which sensors were filtered + claimed := make(map[string]struct{}, len(temps)) for i, sensor := range temps { // check for malformed strings on darwin (gopsutil/issues/1832) if runtime.GOOS == "darwin" && !utf8.ValidString(sensor.SensorKey) { continue } + // claim a name before any filtering, so excluding a sensor does not + // rename the sensors after it + sensorName := sensor.SensorKey + if _, ok := claimed[sensorName]; ok { + // if key already claimed, append int to key + sensorName = sensorName + "_" + strconv.Itoa(i) + } + claimed[sensorName] = struct{}{} + // scale temperature if sensor.Temperature != 0 && sensor.Temperature < 1 { sensor.Temperature = scaleTemperature(sensor.Temperature) @@ -165,11 +177,6 @@ func (a *Agent) updateTemperatures(systemStats *system.Stats) { if sensor.Temperature <= 0 || sensor.Temperature >= 200 { continue } - sensorName := sensor.SensorKey - if _, ok := systemStats.Temperatures[sensorName]; ok { - // if key already exists, append int to key - sensorName = sensorName + "_" + strconv.Itoa(i) - } // skip if not in whitelist or blacklist if !isValidSensor(sensorName, a.sensorConfig) { continue diff --git a/agent/sensors_test.go b/agent/sensors_test.go index 2a3ace60c..6229761f8 100644 --- a/agent/sensors_test.go +++ b/agent/sensors_test.go @@ -798,3 +798,51 @@ func TestUpdateTemperaturesSkipGpu(t *testing.T) { newAgent(false).updateTemperatures(stats) assert.Len(t, stats.Temperatures, 2) } + +func TestUpdateTemperaturesExcludedSensorKeepsNames(t *testing.T) { + originalGetSensorTemps := getSensorTemps + t.Cleanup(func() { + getSensorTemps = originalGetSensorTemps + }) + // two drives that report the same SensorKey, plus an unrelated sensor + getSensorTemps = func(ctx context.Context) ([]sensors.TemperatureStat, error) { + return []sensors.TemperatureStat{ + {SensorKey: "nvme_sensor_2", Temperature: 74.85}, + {SensorKey: "nvme_sensor_2", Temperature: 41}, + {SensorKey: "coretemp_core_0", Temperature: 55}, + }, nil + } + + newAgent := func(exclude string) *Agent { + config := map[string]struct{}{} + if exclude != "" { + config[exclude] = struct{}{} + } + return &Agent{ + systemInfo: system.Info{}, + sensorConfig: &SensorConfig{ + context: context.Background(), + timeout: 2 * time.Second, + sensors: config, + isBlacklist: exclude != "", + }, + } + } + + // unfiltered: the second duplicate is suffixed with its index + stats := &system.Stats{} + newAgent("").updateTemperatures(stats) + assert.Equal(t, map[string]float64{ + "nvme_sensor_2": 74.85, + "nvme_sensor_2_1": 41, + "coretemp_core_0": 55, + }, stats.Temperatures) + + // excluding the first duplicate keeps the second one's name + stats = &system.Stats{} + newAgent("nvme_sensor_2").updateTemperatures(stats) + assert.Equal(t, map[string]float64{ + "nvme_sensor_2_1": 41, + "coretemp_core_0": 55, + }, stats.Temperatures) +}