diff --git a/plugins/inputs/diskio/README.md b/plugins/inputs/diskio/README.md index 8f87935a7..762717bab 100644 --- a/plugins/inputs/diskio/README.md +++ b/plugins/inputs/diskio/README.md @@ -10,7 +10,9 @@ The diskio input plugin gathers metrics about disk traffic and timing. ## By default, telegraf will gather stats for all devices including ## disk partitions. ## Setting devices will restrict the stats to the specified devices. - # devices = ["sda", "sdb", "vd*"] + ## NOTE: Globbing expressions (e.g. asterix) are not supported for + ## disk synonyms like '/dev/disk/by-id'. + # devices = ["sda", "sdb", "vd*", "/dev/disk/by-id/nvme-eui.00123deadc0de123"] ## Uncomment the following line if you need disk serial numbers. # skip_serial_number = false # diff --git a/plugins/inputs/diskio/diskio.go b/plugins/inputs/diskio/diskio.go index 8ded40793..fac62e81c 100644 --- a/plugins/inputs/diskio/diskio.go +++ b/plugins/inputs/diskio/diskio.go @@ -57,9 +57,11 @@ func (d *DiskIO) Init() error { } func (d *DiskIO) Gather(acc telegraf.Accumulator) error { - devices := []string{} + var devices []string if d.deviceFilter == nil { - devices = d.Devices + for _, dev := range d.Devices { + devices = append(devices, resolveName(dev)) + } } diskio, err := d.ps.DiskIO(devices) @@ -77,6 +79,10 @@ func (d *DiskIO) Gather(acc telegraf.Accumulator) error { var devLinks []string tags["name"], devLinks = d.diskName(io.Name) + if wwid := getDeviceWWID(io.Name); wwid != "" { + tags["wwid"] = wwid + } + if d.deviceFilter != nil && !match { for _, devLink := range devLinks { if d.deviceFilter.Match(devLink) { diff --git a/plugins/inputs/diskio/diskio_linux.go b/plugins/inputs/diskio/diskio_linux.go index c356d49cb..1fde7925d 100644 --- a/plugins/inputs/diskio/diskio_linux.go +++ b/plugins/inputs/diskio/diskio_linux.go @@ -3,8 +3,11 @@ package diskio import ( "bufio" "bytes" + "errors" "fmt" + "io/fs" "os" + "path/filepath" "strings" "golang.org/x/sys/unix" @@ -105,3 +108,29 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) { return di, nil } + +func resolveName(name string) string { + resolved, err := filepath.EvalSymlinks(name) + if err == nil { + return resolved + } + if err != nil && !errors.Is(err, fs.ErrNotExist) { + return name + } + // Try to prepend "/dev" + resolved, err = filepath.EvalSymlinks(filepath.Join("/dev", name)) + if err != nil { + return name + } + + return resolved +} + +func getDeviceWWID(name string) string { + path := fmt.Sprintf("/sys/block/%s/wwid", filepath.Base(name)) + buf, err := os.ReadFile(path) + if err != nil { + return "" + } + return strings.TrimSuffix(string(buf), "\n") +} diff --git a/plugins/inputs/diskio/diskio_other.go b/plugins/inputs/diskio/diskio_other.go index 40cf4ef7a..b277c390d 100644 --- a/plugins/inputs/diskio/diskio_other.go +++ b/plugins/inputs/diskio/diskio_other.go @@ -7,3 +7,11 @@ type diskInfoCache struct{} func (d *DiskIO) diskInfo(devName string) (map[string]string, error) { return nil, nil } + +func resolveName(name string) string { + return name +} + +func getDeviceWWID(name string) string { + return "" +} diff --git a/plugins/inputs/diskio/sample.conf b/plugins/inputs/diskio/sample.conf index ff5521d52..99ff4aa71 100644 --- a/plugins/inputs/diskio/sample.conf +++ b/plugins/inputs/diskio/sample.conf @@ -3,7 +3,9 @@ ## By default, telegraf will gather stats for all devices including ## disk partitions. ## Setting devices will restrict the stats to the specified devices. - # devices = ["sda", "sdb", "vd*"] + ## NOTE: Globbing expressions (e.g. asterix) are not supported for + ## disk synonyms like '/dev/disk/by-id'. + # devices = ["sda", "sdb", "vd*", "/dev/disk/by-id/nvme-eui.00123deadc0de123"] ## Uncomment the following line if you need disk serial numbers. # skip_serial_number = false #