diff options
Diffstat (limited to 'src/go/plugins/vfs')
-rw-r--r-- | src/go/plugins/vfs/fs/fs.go | 29 | ||||
-rw-r--r-- | src/go/plugins/vfs/fs/fs_nix.go | 162 | ||||
-rw-r--r-- | src/go/plugins/vfs/fs/fs_windows.go | 19 |
3 files changed, 193 insertions, 17 deletions
diff --git a/src/go/plugins/vfs/fs/fs.go b/src/go/plugins/vfs/fs/fs.go index 2b609e202ee..db9d23f85df 100644 --- a/src/go/plugins/vfs/fs/fs.go +++ b/src/go/plugins/vfs/fs/fs.go @@ -1,5 +1,3 @@ -// +build windows - /* ** Zabbix ** Copyright (C) 2001-2020 Zabbix SIA @@ -53,6 +51,15 @@ type FsInfo struct { FsType *string `json:"{#FSTYPE},omitempty"` DriveType *string `json:"{#FSDRIVETYPE},omitempty"` Bytes *FsStats `json:"bytes,omitempty"` + Inodes *FsStats `json:"inodes,omitempty"` +} + +type FsInfoNew struct { + FsName *string `json:"fsname,omitempty"` + FsType *string `json:"fstype,omitempty"` + DriveType *string `json:"fsdrivetype,omitempty"` + Bytes *FsStats `json:"bytes,omitempty"` + Inodes *FsStats `json:"inodes,omitempty"` } type Plugin struct { @@ -80,7 +87,7 @@ func (p *Plugin) exportGet(params []string) (value interface{}, err error) { if len(params) != 0 { return nil, errors.New(errorInvalidParameters) } - var d []*FsInfo + var d []*FsInfoNew if d, err = p.getFsInfoStats(); err != nil { return } @@ -91,7 +98,7 @@ func (p *Plugin) exportGet(params []string) (value interface{}, err error) { return string(b), nil } -func (p *Plugin) exportSize(params []string) (value interface{}, err error) { +func (p *Plugin) export(params []string, getStats func(string) (*FsStats, error)) (value interface{}, err error) { if len(params) < 1 || params[0] == "" { return nil, errors.New("Invalid first parameter.") } @@ -115,7 +122,7 @@ func (p *Plugin) exportSize(params []string) (value interface{}, err error) { } } var stats *FsStats - if stats, err = getFsStats(params[0]); err != nil { + if stats, err = getStats(params[0]); err != nil { return } @@ -142,16 +149,10 @@ func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) case "vfs.fs.get": return p.exportGet(params) case "vfs.fs.size": - return p.exportSize(params) + return p.export(params, getFsStats) + case "vfs.fs.inode": + return p.export(params, getFsInode) default: return nil, plugin.UnsupportedMetricError } } - -func init() { - plugin.RegisterMetrics(&impl, "VfsFs", - "vfs.fs.discovery", "List of mounted filesystems. Used for low-level discovery.", - "vfs.fs.get", "List of mounted filesystems with statistics.", - "vfs.fs.size", "Disk space in bytes or in percentage from total.", - ) -} diff --git a/src/go/plugins/vfs/fs/fs_nix.go b/src/go/plugins/vfs/fs/fs_nix.go new file mode 100644 index 00000000000..99ea97f9fbf --- /dev/null +++ b/src/go/plugins/vfs/fs/fs_nix.go @@ -0,0 +1,162 @@ +// +build !windows + +/* +** Zabbix +** Copyright (C) 2001-2019 Zabbix SIA +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**/ + +package vfsfs + +import ( + "bufio" + "io" + "os" + "strings" + + "golang.org/x/sys/unix" + "zabbix.com/pkg/plugin" +) + +func (p *Plugin) getFsInfoStats() (data []*FsInfoNew, err error) { + allData, err := p.getFsInfo() + if err != nil { + return nil, err + } + + fsmap := make(map[string]*FsInfoNew) + for _, info := range allData { + bytes, err := getFsStats(*info.FsName) + if err != nil { + p.Debugf(`cannot discern stats for the mount: %s`, *info.FsName) + continue + } + + inodes, err := getFsInode(*info.FsName) + if err != nil { + p.Debugf(`cannot discern inode for the mount: %s`, *info.FsName) + continue + } + + if bytes.Total > 0 && inodes.Total > 0 { + fsmap[*info.FsName] = &FsInfoNew{info.FsName, info.FsType, nil, bytes, inodes} + } + } + + allData, err = p.getFsInfo() + if err != nil { + return nil, err + } + + for _, info := range allData { + if fsInfo, ok := fsmap[*info.FsName]; ok { + data = append(data, fsInfo) + } + } + + return +} + +func (p *Plugin) readMounts(file io.Reader) (data []*FsInfo, err error) { + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + mnt := strings.Split(line, " ") + if len(mnt) < 3 { + p.Debugf(`cannot discern the mount in given line: %s`, line) + continue + } + data = append(data, &FsInfo{FsName: &mnt[1], FsType: &mnt[2]}) + } + + if err = scanner.Err(); err != nil { + return nil, err + } + + return +} + +func (p *Plugin) getFsInfo() (data []*FsInfo, err error) { + file, err := os.Open("/proc/mounts") + if err != nil { + return nil, err + } + defer file.Close() + + data, err = p.readMounts(file) + if err != nil { + return nil, err + } + + return data, nil +} + +func getFsStats(path string) (stats *FsStats, err error) { + fs := unix.Statfs_t{} + err = unix.Statfs(path, &fs) + if err != nil { + return nil, err + } + + var avialable uint64 + if fs.Bavail > 0 { + avialable = fs.Bavail + } + + total := fs.Blocks * uint64(fs.Bsize) + free := avialable * uint64(fs.Bsize) + used := (fs.Blocks - fs.Bfree) * uint64(fs.Bsize) + pfree := 100.00 * float64(avialable) / float64(fs.Blocks-fs.Bfree+fs.Bavail) + stats = &FsStats{ + Total: total, + Free: free, + Used: used, + PFree: pfree, + PUsed: 100 - pfree, + } + + return +} + +func getFsInode(path string) (stats *FsStats, err error) { + fs := unix.Statfs_t{} + err = unix.Statfs(path, &fs) + if err != nil { + return nil, err + } + + total := fs.Files + free := fs.Ffree + used := fs.Files - fs.Ffree + stats = &FsStats{ + Total: total, + Free: free, + Used: used, + PFree: 100 * float64(free) / float64(total), + PUsed: 100 * float64(total-free) / float64(total), + } + + return +} + +func init() { + plugin.RegisterMetrics(&impl, "VfsFs", + "vfs.fs.discovery", "List of mounted filesystems. Used for low-level discovery.", + "vfs.fs.get", "List of mounted filesystems with statistics.", + "vfs.fs.size", "Disk space in bytes or in percentage from total.", + "vfs.fs.inode", "Disk space in bytes or in percentage from total.", + ) +} diff --git a/src/go/plugins/vfs/fs/fs_windows.go b/src/go/plugins/vfs/fs/fs_windows.go index 2cf2e1c4b96..05e41ecdedb 100644 --- a/src/go/plugins/vfs/fs/fs_windows.go +++ b/src/go/plugins/vfs/fs/fs_windows.go @@ -23,6 +23,7 @@ import ( "syscall" "golang.org/x/sys/windows" + "zabbix.com/pkg/plugin" ) func getMountPaths() (paths []string, err error) { @@ -145,14 +146,14 @@ func (p *Plugin) getFsInfo() (data []*FsInfo, err error) { return } -func (p *Plugin) getFsInfoStats() (data []*FsInfo, err error) { +func (p *Plugin) getFsInfoStats() (data []*FsInfoNew, err error) { var paths []string if paths, err = getMountPaths(); err != nil { return } - fsmap := make(map[string]*FsInfo) + fsmap := make(map[string]*FsInfoNew) for _, path := range paths { - var info FsInfo + var info FsInfoNew if fsname, fstype, drivetype, fserr := getFsInfo(path); fserr == nil { info.FsName = &fsname info.FsType = &fstype @@ -179,3 +180,15 @@ func (p *Plugin) getFsInfoStats() (data []*FsInfo, err error) { } return } + +func getFsInode(string) (*FsStats, error) { + return nil, plugin.UnsupportedMetricError +} + +func init() { + plugin.RegisterMetrics(&impl, "VfsFs", + "vfs.fs.discovery", "List of mounted filesystems. Used for low-level discovery.", + "vfs.fs.get", "List of mounted filesystems with statistics.", + "vfs.fs.size", "Disk space in bytes or in percentage from total.", + ) +} |