Skip to content

Commit

Permalink
- added types_windows.go file which includes the exports for windows …
Browse files Browse the repository at this point in the history
…functions since these functions are global per package

- added windows version of the diskspace module
- cleaned up some of the sys call functions
  • Loading branch information
wackoisgod committed Jan 5, 2015
1 parent e1e9dfd commit b81f625
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 164 deletions.
139 changes: 0 additions & 139 deletions diskspace.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
package main

import (
"fmt"
"golang.org/x/sys/unix" //see https://godoc.org/golang.org/x/sys/unix
"io/ioutil"
"log"
"path/filepath"
"strings"
"time"
)

type Filesystem struct {
Expand Down Expand Up @@ -54,136 +48,3 @@ func (m *DiskspaceInputModule) Init(config *Config, moduleConfig *ModuleConfig)
func (m *DiskspaceInputModule) TearDown() error {
return nil
}

func (m *DiskspaceInputModule) GetMetrics() ([]Metric, error) {
metrics := make([]Metric, 0, 50)
now := time.Now()

filesystems, err := GetFileSystems(m)
if err != nil {
log.Printf("Error retrieving filesystems: %v", err)
return nil, err
}
stats, err := GetFilesystemStats(filesystems)
if err != nil {
log.Printf("Error retrieving filesystem stats: %v", err)
return nil, err
}

for _, stat := range stats {
used := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.used", stat.DeviceName),
value: stat.Used,
timestamp: now,
}
free := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.free", stat.DeviceName),
value: stat.Free,
timestamp: now,
}
reserved := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.reserved", stat.DeviceName),
value: stat.Reserved,
timestamp: now,
}
available := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.available", stat.DeviceName),
value: stat.Available,
timestamp: now,
}
metrics = append(metrics, used)
metrics = append(metrics, free)
metrics = append(metrics, reserved)
metrics = append(metrics, available)
}

return metrics, nil
}

func GetFileSystems(m *DiskspaceInputModule) ([]Filesystem, error) {
b, err := ioutil.ReadFile("/proc/mounts")
if err != nil {
return nil, err
}
content := string(b)
lines := strings.Split(content, "\n")

filesystems := make([]Filesystem, 0, len(lines))

for _, line := range lines {
fields := strings.Fields(line)

if len(fields) < 3 {
continue
}

device := fields[0]
mount := fields[1]
fsType := fields[2]

if !m.CheckTypes.Contains(fsType) {
continue
}

mountPrefix := strings.Split(mount, "/")[1]
if mountPrefix == "proc" || mountPrefix == "dev" || mountPrefix == "sys" {
continue
}

deviceSym, err := filepath.EvalSymlinks(device)
if err == nil {
device = deviceSym
}

stat := unix.Stat_t{}
err = unix.Stat(mount, &stat)
if err != nil {
// filesystem likely not mounted
continue
}

fs := Filesystem{
Device: device,
Mount: mount,
Type: fsType,
}

filesystems = append(filesystems, fs)
}

return filesystems, nil
}

func GetFilesystemStats(filesystems []Filesystem) ([]FilesystemStats, error) {
stats := make([]FilesystemStats, 0, len(filesystems))

for _, fs := range filesystems {
stat := unix.Statfs_t{}
err := unix.Statfs(fs.Mount, &stat)
if err != nil {
continue
}

// change /dev/sda1 to sda1
var name string
if fs.Device[:1] == "/" {
_, name = filepath.Split(fs.Device)
}
if name == "" {
name = strings.Replace(fs.Mount[1:], "/", "_", -1)
}

used := float64(stat.Bsize) * float64(stat.Blocks-stat.Bfree)
free := float64(stat.Bsize) * float64(stat.Bfree)
reserved := float64(stat.Bsize) * float64(stat.Bfree-stat.Bavail)
available := float64(stat.Bsize) * float64(stat.Bavail)

stats = append(stats, FilesystemStats{DeviceName: name, Used: used, Free: free, Reserved: reserved, Available: available})
}

return stats, nil
}
146 changes: 146 additions & 0 deletions diskspace_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// +build linux

package main

import (
"fmt"
"golang.org/x/sys/unix" //see https://godoc.org/golang.org/x/sys/unix
"io/ioutil"
"log"
"path/filepath"
"strings"
"time"
)

func (m *DiskspaceInputModule) GetMetrics() ([]Metric, error) {
metrics := make([]Metric, 0, 50)
now := time.Now()

filesystems, err := GetFileSystems(m)
if err != nil {
log.Printf("Error retrieving filesystems: %v", err)
return nil, err
}
stats, err := GetFilesystemStats(filesystems)
if err != nil {
log.Printf("Error retrieving filesystem stats: %v", err)
return nil, err
}

for _, stat := range stats {
used := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.used", stat.DeviceName),
value: stat.Used,
timestamp: now,
}
free := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.free", stat.DeviceName),
value: stat.Free,
timestamp: now,
}
reserved := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.reserved", stat.DeviceName),
value: stat.Reserved,
timestamp: now,
}
available := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.available", stat.DeviceName),
value: stat.Available,
timestamp: now,
}
metrics = append(metrics, used)
metrics = append(metrics, free)
metrics = append(metrics, reserved)
metrics = append(metrics, available)
}

return metrics, nil
}

func GetFileSystems(m *DiskspaceInputModule) ([]Filesystem, error) {
b, err := ioutil.ReadFile("/proc/mounts")
if err != nil {
return nil, err
}
content := string(b)
lines := strings.Split(content, "\n")

filesystems := make([]Filesystem, 0, len(lines))

for _, line := range lines {
fields := strings.Fields(line)

if len(fields) < 3 {
continue
}

device := fields[0]
mount := fields[1]
fsType := fields[2]

if !m.CheckTypes.Contains(fsType) {
continue
}

mountPrefix := strings.Split(mount, "/")[1]
if mountPrefix == "proc" || mountPrefix == "dev" || mountPrefix == "sys" {
continue
}

deviceSym, err := filepath.EvalSymlinks(device)
if err == nil {
device = deviceSym
}

stat := unix.Stat_t{}
err = unix.Stat(mount, &stat)
if err != nil {
// filesystem likely not mounted
continue
}

fs := Filesystem{
Device: device,
Mount: mount,
Type: fsType,
}

filesystems = append(filesystems, fs)
}

return filesystems, nil
}

func GetFilesystemStats(filesystems []Filesystem) ([]FilesystemStats, error) {
stats := make([]FilesystemStats, 0, len(filesystems))

for _, fs := range filesystems {
stat := unix.Statfs_t{}
err := unix.Statfs(fs.Mount, &stat)
if err != nil {
continue
}

// change /dev/sda1 to sda1
var name string
if fs.Device[:1] == "/" {
_, name = filepath.Split(fs.Device)
}
if name == "" {
name = strings.Replace(fs.Mount[1:], "/", "_", -1)
}

used := float64(stat.Bsize) * float64(stat.Blocks-stat.Bfree)
free := float64(stat.Bsize) * float64(stat.Bfree)
reserved := float64(stat.Bsize) * float64(stat.Bfree-stat.Bavail)
available := float64(stat.Bsize) * float64(stat.Bavail)

stats = append(stats, FilesystemStats{DeviceName: name, Used: used, Free: free, Reserved: reserved, Available: available})
}

return stats, nil
}
85 changes: 85 additions & 0 deletions diskspace_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// +build windows

package main

import (
"fmt"
"strconv"
"syscall"
"time"
"unsafe"
)

func (m *DiskspaceInputModule) GetMetrics() ([]Metric, error) {

metrics := make([]Metric, 0, 50)
now := time.Now()

// we grab all the drives
drives := m.GetLogicalDrives()

for _, drive := range drives {

lpFreeBytesAvailable := int64(0)
lpTotalNumberOfBytes := int64(0)
lpTotalNumberOfFreeBytes := int64(0)

_, _, _ = _getDiskFreeSpaceEx.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(drive))),
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))

usedBytes := lpTotalNumberOfBytes - lpTotalNumberOfFreeBytes

used := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.used", drive[:1]),
value: float64(usedBytes),
timestamp: now,
}
free := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.free", drive[:1]),
value: float64(lpTotalNumberOfFreeBytes),
timestamp: now,
}
available := Metric{
module: m.Name(),
name: fmt.Sprintf("%s.available", drive[:1]),
value: float64(lpFreeBytesAvailable),
timestamp: now,
}
metrics = append(metrics, used)
metrics = append(metrics, free)
metrics = append(metrics, available)
}

return metrics, nil
}

func (m *DiskspaceInputModule) GetLogicalDrives() []string {

_getLogicalDrives := kernel32.NewProc("GetLogicalDrives")

n, _, _ := _getLogicalDrives.Call()
s := strconv.FormatInt(int64(n), 2)

var drives_all = []string{"A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:"}
temp := drives_all[0:len(s)]

var d []string
for i, v := range s {

if v == 49 {
l := len(s) - i - 1
d = append(d, temp[l])
}
}

var drives []string
for i, v := range d {
drives = append(drives[i:], append([]string{v}, drives[:i]...)...)
}
return drives

}
Loading

0 comments on commit b81f625

Please sign in to comment.