fix(inputs.temp): Recover pre-v1.22.4 temperature sensor readings (#14575)
This commit is contained in:
parent
03bcd859d5
commit
9aee2681bb
|
|
@ -168,7 +168,14 @@ func TestUsageFlag(t *testing.T) {
|
||||||
ExpectedOutput: `
|
ExpectedOutput: `
|
||||||
# Read metrics about temperature
|
# Read metrics about temperature
|
||||||
[[inputs.temp]]
|
[[inputs.temp]]
|
||||||
# no configuration
|
## Desired output format (Linux only)
|
||||||
|
## Available values are
|
||||||
|
## v1 -- use pre-v1.22.4 sensor naming, e.g. coretemp_core0_input
|
||||||
|
## v2 -- use v1.22.4+ sensor naming, e.g. coretemp_core_0_input
|
||||||
|
# metric_format = "v2"
|
||||||
|
|
||||||
|
## Add device tag to distinguish devices with the same name (Linux only)
|
||||||
|
# add_device_tag = false
|
||||||
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/v3/cpu"
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
"github.com/shirou/gopsutil/v3/disk"
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
"github.com/shirou/gopsutil/v3/host"
|
|
||||||
"github.com/shirou/gopsutil/v3/mem"
|
"github.com/shirou/gopsutil/v3/mem"
|
||||||
"github.com/shirou/gopsutil/v3/net"
|
"github.com/shirou/gopsutil/v3/net"
|
||||||
|
|
||||||
|
|
@ -26,7 +25,6 @@ type PS interface {
|
||||||
SwapStat() (*mem.SwapMemoryStat, error)
|
SwapStat() (*mem.SwapMemoryStat, error)
|
||||||
NetConnections() ([]net.ConnectionStat, error)
|
NetConnections() ([]net.ConnectionStat, error)
|
||||||
NetConntrack(perCPU bool) ([]net.ConntrackStat, error)
|
NetConntrack(perCPU bool) ([]net.ConntrackStat, error)
|
||||||
Temperature() ([]host.TemperatureStat, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PSDiskDeps interface {
|
type PSDiskDeps interface {
|
||||||
|
|
@ -214,17 +212,6 @@ func (s *SystemPS) SwapStat() (*mem.SwapMemoryStat, error) {
|
||||||
return mem.SwapMemory()
|
return mem.SwapMemory()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SystemPS) Temperature() ([]host.TemperatureStat, error) {
|
|
||||||
temp, err := host.SensorsTemperatures()
|
|
||||||
if err != nil {
|
|
||||||
var hostWarnings *host.Warnings
|
|
||||||
if !errors.As(err, &hostWarnings) {
|
|
||||||
return temp, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return temp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SystemPSDisk) Partitions(all bool) ([]disk.PartitionStat, error) {
|
func (s *SystemPSDisk) Partitions(all bool) ([]disk.PartitionStat, error) {
|
||||||
return disk.Partitions(all)
|
return disk.Partitions(all)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,14 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
```toml @sample.conf
|
```toml @sample.conf
|
||||||
# Read metrics about temperature
|
# Read metrics about temperature
|
||||||
[[inputs.temp]]
|
[[inputs.temp]]
|
||||||
# no configuration
|
## Desired output format (Linux only)
|
||||||
|
## Available values are
|
||||||
|
## v1 -- use pre-v1.22.4 sensor naming, e.g. coretemp_core0_input
|
||||||
|
## v2 -- use v1.22.4+ sensor naming, e.g. coretemp_core_0_input
|
||||||
|
# metric_format = "v2"
|
||||||
|
|
||||||
|
## Add device tag to distinguish devices with the same name (Linux only)
|
||||||
|
# add_device_tag = false
|
||||||
```
|
```
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
# Read metrics about temperature
|
# Read metrics about temperature
|
||||||
[[inputs.temp]]
|
[[inputs.temp]]
|
||||||
# no configuration
|
## Desired output format (Linux only)
|
||||||
|
## Available values are
|
||||||
|
## v1 -- use pre-v1.22.4 sensor naming, e.g. coretemp_core0_input
|
||||||
|
## v2 -- use v1.22.4+ sensor naming, e.g. coretemp_core_0_input
|
||||||
|
# metric_format = "v2"
|
||||||
|
|
||||||
|
## Add device tag to distinguish devices with the same name (Linux only)
|
||||||
|
# add_device_tag = false
|
||||||
|
|
|
||||||
|
|
@ -3,47 +3,26 @@ package temp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
"github.com/influxdata/telegraf/plugins/inputs"
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
"github.com/influxdata/telegraf/plugins/inputs/system"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed sample.conf
|
//go:embed sample.conf
|
||||||
var sampleConfig string
|
var sampleConfig string
|
||||||
|
|
||||||
type Temperature struct {
|
type Temperature struct {
|
||||||
ps system.PS
|
MetricFormat string `toml:"metric_format"`
|
||||||
|
DeviceTag bool `toml:"add_device_tag"`
|
||||||
|
Log telegraf.Logger `toml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Temperature) SampleConfig() string {
|
func (*Temperature) SampleConfig() string {
|
||||||
return sampleConfig
|
return sampleConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Temperature) Gather(acc telegraf.Accumulator) error {
|
|
||||||
temps, err := t.ps.Temperature()
|
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), "not implemented yet") {
|
|
||||||
return fmt.Errorf("plugin is not supported on this platform: %w", err)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("error getting temperatures info: %w", err)
|
|
||||||
}
|
|
||||||
for _, temp := range temps {
|
|
||||||
tags := map[string]string{
|
|
||||||
"sensor": temp.SensorKey,
|
|
||||||
}
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"temp": temp.Temperature,
|
|
||||||
}
|
|
||||||
acc.AddFields("temp", fields, tags)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("temp", func() telegraf.Input {
|
inputs.Add("temp", func() telegraf.Input {
|
||||||
return &Temperature{ps: system.NewSystemPS()}
|
return &Temperature{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package temp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf"
|
||||||
|
)
|
||||||
|
|
||||||
|
const scalingFactor = float64(1000.0)
|
||||||
|
|
||||||
|
type TemperatureStat struct {
|
||||||
|
Name string
|
||||||
|
Label string
|
||||||
|
Device string
|
||||||
|
Temperature float64
|
||||||
|
Additional map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) Init() error {
|
||||||
|
switch t.MetricFormat {
|
||||||
|
case "":
|
||||||
|
t.MetricFormat = "v2"
|
||||||
|
case "v1", "v2":
|
||||||
|
// Do nothing as those are valid
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid 'metric_format' %q", t.MetricFormat)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) Gather(acc telegraf.Accumulator) error {
|
||||||
|
// Get all sensors and honor the HOST_SYS environment variable
|
||||||
|
path := os.Getenv("HOST_SYS")
|
||||||
|
if path == "" {
|
||||||
|
path = "/sys"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to use the hwmon interface
|
||||||
|
temperatures, err := t.gatherHwmon(path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting temperatures failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(temperatures) == 0 {
|
||||||
|
// There is no hwmon interface, fallback to thermal-zone parsing
|
||||||
|
temperatures, err = t.gatherThermalZone(path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("getting temperatures (via fallback) failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, temp := range temperatures {
|
||||||
|
acc.AddFields(
|
||||||
|
"temp",
|
||||||
|
map[string]interface{}{"temp": temp.Temperature},
|
||||||
|
t.getTagsForTemperature(temp, "_input"),
|
||||||
|
)
|
||||||
|
|
||||||
|
for measurement, value := range temp.Additional {
|
||||||
|
fieldname := "temp"
|
||||||
|
if measurement == "alarm" {
|
||||||
|
fieldname = "active"
|
||||||
|
}
|
||||||
|
acc.AddFields(
|
||||||
|
"temp",
|
||||||
|
map[string]interface{}{fieldname: value},
|
||||||
|
t.getTagsForTemperature(temp, "_"+measurement),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) gatherHwmon(syspath string) ([]TemperatureStat, error) {
|
||||||
|
// Get all hwmon devices
|
||||||
|
sensors, err := filepath.Glob(filepath.Join(syspath, "class", "hwmon", "hwmon*", "temp*_input"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("getting sensors failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle CentOS special path containing an additional "device" directory
|
||||||
|
// see https://github.com/shirou/gopsutil/blob/master/host/host_linux.go
|
||||||
|
if len(sensors) == 0 {
|
||||||
|
sensors, err = filepath.Glob(filepath.Join(syspath, "class", "hwmon", "hwmon*", "device", "temp*_input"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("getting sensors on CentOS failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit early if we cannot find any device
|
||||||
|
if len(sensors) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the sensor information
|
||||||
|
stats := make([]TemperatureStat, 0, len(sensors))
|
||||||
|
for _, s := range sensors {
|
||||||
|
// Get the sensor directory and the temperature prefix from the path
|
||||||
|
path := filepath.Dir(s)
|
||||||
|
prefix := strings.SplitN(filepath.Base(s), "_", 2)[0]
|
||||||
|
|
||||||
|
// Read the sensor and device name
|
||||||
|
deviceName, err := os.Readlink(filepath.Join(path, "device"))
|
||||||
|
if err == nil {
|
||||||
|
deviceName = filepath.Base(deviceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the sensor name and use the device name as fallback
|
||||||
|
name := deviceName
|
||||||
|
n, err := os.ReadFile(filepath.Join(path, "name"))
|
||||||
|
if err == nil {
|
||||||
|
name = strings.TrimSpace(string(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the sensor label
|
||||||
|
var label string
|
||||||
|
if buf, err := os.ReadFile(filepath.Join(path, prefix+"_label")); err == nil {
|
||||||
|
label = strings.TrimSpace(string(buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the actual sensor readings
|
||||||
|
temp := TemperatureStat{
|
||||||
|
Name: name,
|
||||||
|
Label: strings.ToLower(label),
|
||||||
|
Device: deviceName,
|
||||||
|
Additional: make(map[string]interface{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temperature (mandatory)
|
||||||
|
fn := filepath.Join(path, prefix+"_input")
|
||||||
|
buf, err := os.ReadFile(fn)
|
||||||
|
if err != nil {
|
||||||
|
t.Log.Warnf("Couldn't read temperature from %q: %v", fn, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v, err := strconv.ParseFloat(strings.TrimSpace(string(buf)), 64); err == nil {
|
||||||
|
temp.Temperature = v / scalingFactor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alarm (optional)
|
||||||
|
fn = filepath.Join(path, prefix+"_alarm")
|
||||||
|
buf, err = os.ReadFile(fn)
|
||||||
|
if err == nil {
|
||||||
|
if a, err := strconv.ParseBool(strings.TrimSpace(string(buf))); err == nil {
|
||||||
|
temp.Additional["alarm"] = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all possible values of the sensor
|
||||||
|
matches, err := filepath.Glob(filepath.Join(path, prefix+"_*"))
|
||||||
|
if err != nil {
|
||||||
|
t.Log.Warnf("Couldn't read files from %q: %v", filepath.Join(path, prefix+"_*"), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, fn := range matches {
|
||||||
|
buf, err = os.ReadFile(fn)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
parts := strings.SplitN(filepath.Base(fn), "_", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
measurement := parts[1]
|
||||||
|
|
||||||
|
// Skip already added values
|
||||||
|
switch measurement {
|
||||||
|
case "label", "input", "alarm":
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := strconv.ParseFloat(strings.TrimSpace(string(buf)), 64)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
temp.Additional[measurement] = v / scalingFactor
|
||||||
|
}
|
||||||
|
|
||||||
|
stats = append(stats, temp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) gatherThermalZone(syspath string) ([]TemperatureStat, error) {
|
||||||
|
// For file layout see https://www.kernel.org/doc/Documentation/thermal/sysfs-api.txt
|
||||||
|
zones, err := filepath.Glob(filepath.Join(syspath, "class", "thermal", "thermal_zone*"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("getting thermal zones failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit early if we cannot find any zone
|
||||||
|
if len(zones) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the sensor information
|
||||||
|
stats := make([]TemperatureStat, 0, len(zones))
|
||||||
|
for _, path := range zones {
|
||||||
|
// Type of the zone corresponding to the sensor name in our nomenclature
|
||||||
|
buf, err := os.ReadFile(filepath.Join(path, "type"))
|
||||||
|
if err != nil {
|
||||||
|
t.Log.Errorf("Cannot read name of zone %q", path)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := strings.TrimSpace(string(buf))
|
||||||
|
|
||||||
|
// Actual temperature
|
||||||
|
buf, err = os.ReadFile(filepath.Join(path, "temp"))
|
||||||
|
if err != nil {
|
||||||
|
t.Log.Errorf("Cannot read temperature of zone %q", path)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, err := strconv.ParseFloat(strings.TrimSpace(string(buf)), 64)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
temp := TemperatureStat{Name: name, Temperature: v / scalingFactor}
|
||||||
|
stats = append(stats, temp)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) getTagsForTemperature(temp TemperatureStat, suffix string) map[string]string {
|
||||||
|
sensor := temp.Name
|
||||||
|
if temp.Label != "" && suffix != "" {
|
||||||
|
switch t.MetricFormat {
|
||||||
|
case "v1":
|
||||||
|
sensor += "_" + strings.ReplaceAll(temp.Label, " ", "") + suffix
|
||||||
|
case "v2":
|
||||||
|
sensor += "_" + strings.ReplaceAll(temp.Label, " ", "_") + suffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags := map[string]string{"sensor": sensor}
|
||||||
|
if t.DeviceTag {
|
||||||
|
tags["device"] = temp.Device
|
||||||
|
}
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
//go:build !linux
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package temp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/v3/host"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *Temperature) Init() error {
|
||||||
|
if t.MetricFormat != "" {
|
||||||
|
t.Log.Warn("Ignoring 'metric_format' on non-Linux platforms!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.DeviceTag {
|
||||||
|
t.Log.Warn("Ignoring 'add_device_tag' on non-Linux platforms!")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) Gather(acc telegraf.Accumulator) error {
|
||||||
|
temps, err := host.SensorsTemperatures()
|
||||||
|
if err != nil {
|
||||||
|
var hostWarnings *host.Warnings
|
||||||
|
if !errors.As(err, &hostWarnings) {
|
||||||
|
if strings.Contains(err.Error(), "not implemented yet") {
|
||||||
|
return fmt.Errorf("plugin is not supported on this platform: %w", err)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("getting temperatures failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, temp := range temps {
|
||||||
|
acc.AddFields(
|
||||||
|
"temp",
|
||||||
|
map[string]interface{}{"temp": temp.Temperature},
|
||||||
|
map[string]string{"sensor": temp.SensorKey},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -1,37 +1,473 @@
|
||||||
|
//go:build linux
|
||||||
|
|
||||||
package temp
|
package temp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/v3/host"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf/plugins/inputs/system"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/metric"
|
||||||
"github.com/influxdata/telegraf/testutil"
|
"github.com/influxdata/telegraf/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTemperature(t *testing.T) {
|
func TestTemperatureInvaldiMetricFormat(t *testing.T) {
|
||||||
var mps system.MockPS
|
plugin := &Temperature{
|
||||||
var err error
|
MetricFormat: "foo",
|
||||||
defer mps.AssertExpectations(t)
|
Log: &testutil.Logger{},
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
ts := host.TemperatureStat{
|
|
||||||
SensorKey: "coretemp_sensor1_crit",
|
|
||||||
Temperature: 60.5,
|
|
||||||
}
|
}
|
||||||
|
require.ErrorContains(t, plugin.Init(), "invalid 'metric_format'")
|
||||||
mps.On("Temperature").Return([]host.TemperatureStat{ts}, nil)
|
}
|
||||||
|
|
||||||
err = (&Temperature{ps: &mps}).Gather(&acc)
|
func TestTemperatureMetricV1(t *testing.T) {
|
||||||
require.NoError(t, err)
|
expected := []telegraf.Metric{
|
||||||
|
// hwmon0 / temp1
|
||||||
expectedFields := map[string]interface{}{
|
metric.New(
|
||||||
"temp": float64(60.5),
|
"temp",
|
||||||
}
|
map[string]string{"sensor": "nvme_composite_alarm"},
|
||||||
|
map[string]interface{}{"active": false},
|
||||||
expectedTags := map[string]string{
|
time.Unix(0, 0),
|
||||||
"sensor": "coretemp_sensor1_crit",
|
),
|
||||||
}
|
metric.New(
|
||||||
acc.AssertContainsTaggedFields(t, "temp", expectedFields, expectedTags)
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_crit"},
|
||||||
|
map[string]interface{}{"temp": 84.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_input"},
|
||||||
|
map[string]interface{}{"temp": 35.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_max"},
|
||||||
|
map[string]interface{}{"temp": 81.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_min"},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon0 / temp2
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor1_input"},
|
||||||
|
map[string]interface{}{"temp": 35.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor1_max"},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor1_min"},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon0 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor2_input"},
|
||||||
|
map[string]interface{}{"temp": 38.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor2_max"},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor2_min"},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp1
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "k10temp_tctl_input"},
|
||||||
|
map[string]interface{}{"temp": 33.25},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "k10temp_tccd1_input"},
|
||||||
|
map[string]interface{}{"temp": 33.25},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, os.Setenv("HOST_SYS", filepath.Join("testdata", "general", "sys")))
|
||||||
|
|
||||||
|
plugin := &Temperature{
|
||||||
|
MetricFormat: "v1",
|
||||||
|
Log: &testutil.Logger{},
|
||||||
|
}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
require.NoError(t, plugin.Gather(&acc))
|
||||||
|
actual := acc.GetTelegrafMetrics()
|
||||||
|
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTemperature(t *testing.T) {
|
||||||
|
expected := []telegraf.Metric{
|
||||||
|
// hwmon0 / temp1
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_alarm"},
|
||||||
|
map[string]interface{}{"active": false},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_crit"},
|
||||||
|
map[string]interface{}{"temp": 84.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_input"},
|
||||||
|
map[string]interface{}{"temp": 35.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_max"},
|
||||||
|
map[string]interface{}{"temp": 81.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_composite_min"},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon0 / temp2
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor_1_input"},
|
||||||
|
map[string]interface{}{"temp": 35.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor_1_max"},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor_1_min"},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon0 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor_2_input"},
|
||||||
|
map[string]interface{}{"temp": 38.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor_2_max"},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "nvme_sensor_2_min"},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp1
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "k10temp_tctl_input"},
|
||||||
|
map[string]interface{}{"temp": 33.25},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{"sensor": "k10temp_tccd1_input"},
|
||||||
|
map[string]interface{}{"temp": 33.25},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, os.Setenv("HOST_SYS", filepath.Join("testdata", "general", "sys")))
|
||||||
|
plugin := &Temperature{Log: &testutil.Logger{}}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
require.NoError(t, plugin.Gather(&acc))
|
||||||
|
actual := acc.GetTelegrafMetrics()
|
||||||
|
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTemperatureNameCollisions(t *testing.T) {
|
||||||
|
require.NoError(t, os.Setenv("HOST_SYS", filepath.Join("testdata", "with_name", "sys")))
|
||||||
|
plugin := &Temperature{Log: &testutil.Logger{}}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
require.NoError(t, plugin.Gather(&acc))
|
||||||
|
require.Len(t, acc.GetTelegrafMetrics(), 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTemperatureWithDeviceTag(t *testing.T) {
|
||||||
|
expected := []telegraf.Metric{
|
||||||
|
// hwmon0 / temp1
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_input",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 32.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_alarm",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"active": false},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_crit",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 84.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_min",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_max",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 81.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon0 / temp2
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_1_input",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 32.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_1_min",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_1_max",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon0 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_2_input",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 36.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_2_min",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_2_max",
|
||||||
|
"device": "nvme0",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp1
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_input",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 35.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_alarm",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"active": false},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_crit",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 84.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_min",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_composite_max",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 81.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp2
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_1_input",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 35.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_1_min",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_1_max",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon1 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_2_input",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 37.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_2_min",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": -273.15},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "nvme_sensor_2_max",
|
||||||
|
"device": "nvme1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 65261.85},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon2 / temp1
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "k10temp_tctl_input",
|
||||||
|
"device": "0000:00:18.3",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 31.875},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
// hwmon2 / temp3
|
||||||
|
metric.New(
|
||||||
|
"temp",
|
||||||
|
map[string]string{
|
||||||
|
"sensor": "k10temp_tccd1_input",
|
||||||
|
"device": "0000:00:18.3",
|
||||||
|
},
|
||||||
|
map[string]interface{}{"temp": 30.75},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, os.Setenv("HOST_SYS", filepath.Join("testdata", "with_name", "sys")))
|
||||||
|
plugin := &Temperature{
|
||||||
|
DeviceTag: true,
|
||||||
|
Log: &testutil.Logger{},
|
||||||
|
}
|
||||||
|
require.NoError(t, plugin.Init())
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
require.NoError(t, plugin.Gather(&acc))
|
||||||
|
actual := acc.GetTelegrafMetrics()
|
||||||
|
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime(), testutil.SortMetrics())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
nvme
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
84850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
35850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Composite
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
81850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
35850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Sensor 1
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
65261850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
38850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Sensor 2
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
65261850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
k10temp
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
33250
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Tctl
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
33250
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Tccd1
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../nvme0/
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
nvme
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
84850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
32850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Composite
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
81850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
32850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Sensor 1
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
65261850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
36850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Sensor 2
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
65261850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../nvme1/
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
nvme
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
84850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
35850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Composite
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
81850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
35850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Sensor 1
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
65261850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
37850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Sensor 2
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
65261850
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
-273150
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../../../0000:00:18.3/
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
k10temp
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
31875
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Tctl
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
30750
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Tccd1
|
||||||
Loading…
Reference in New Issue