1
0
Fork 0
telegraf/plugins/inputs/disk/disk.go

118 lines
2.5 KiB
Go
Raw Permalink Normal View History

//go:generate ../../../tools/readme_config_includer/generator
package disk
import (
_ "embed"
"fmt"
"strings"
"github.com/shirou/gopsutil/v4/disk"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/common/psutil"
"github.com/influxdata/telegraf/plugins/inputs"
)
//go:embed sample.conf
var sampleConfig string
type Disk struct {
MountPoints []string `toml:"mount_points"`
IgnoreFS []string `toml:"ignore_fs"`
IgnoreMountOpts []string `toml:"ignore_mount_opts"`
Log telegraf.Logger `toml:"-"`
ps psutil.PS
}
func (*Disk) SampleConfig() string {
return sampleConfig
}
func (ds *Disk) Init() error {
ps := psutil.NewSystemPS()
ps.Log = ds.Log
ds.ps = ps
return nil
}
func (ds *Disk) Gather(acc telegraf.Accumulator) error {
disks, partitions, err := ds.ps.DiskUsage(ds.MountPoints, ds.IgnoreMountOpts, ds.IgnoreFS)
if err != nil {
return fmt.Errorf("error getting disk usage info: %w", err)
}
for i, du := range disks {
if du.Total == 0 {
// Skip dummy filesystem (procfs, cgroupfs, ...)
continue
}
device := partitions[i].Device
mountOpts := mountOptions(partitions[i].Opts)
tags := map[string]string{
"path": du.Path,
"device": strings.ReplaceAll(device, "/dev/", ""),
"fstype": du.Fstype,
"mode": mountOpts.mode(),
}
label, err := disk.Label(strings.TrimPrefix(device, "/dev/"))
if err == nil && label != "" {
tags["label"] = label
}
var usedPercent float64
if du.Used+du.Free > 0 {
usedPercent = float64(du.Used) /
(float64(du.Used) + float64(du.Free)) * 100
}
var inodesUsedPercent float64
if du.InodesUsed+du.InodesFree > 0 {
inodesUsedPercent = float64(du.InodesUsed) /
(float64(du.InodesUsed) + float64(du.InodesFree)) * 100
}
fields := map[string]interface{}{
"total": du.Total,
"free": du.Free,
"used": du.Used,
"used_percent": usedPercent,
"inodes_total": du.InodesTotal,
"inodes_free": du.InodesFree,
"inodes_used": du.InodesUsed,
"inodes_used_percent": inodesUsedPercent,
}
acc.AddGauge("disk", fields, tags)
}
return nil
}
type mountOptions []string
func (opts mountOptions) mode() string {
if opts.exists("rw") {
return "rw"
} else if opts.exists("ro") {
return "ro"
}
return "unknown"
}
func (opts mountOptions) exists(opt string) bool {
for _, o := range opts {
if o == opt {
return true
}
}
return false
}
func init() {
inputs.Add("disk", func() telegraf.Input {
return &Disk{}
})
}