Change duration -> internal and implement private gopsutil methods
This commit is contained in:
parent
a8bcc51071
commit
acf9c1141a
|
@ -171,11 +171,6 @@
|
||||||
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
"ImportPath": "github.com/samuel/go-zookeeper/zk",
|
||||||
"Rev": "5bb5cfc093ad18a28148c578f8632cfdb4d802e4"
|
"Rev": "5bb5cfc093ad18a28148c578f8632cfdb4d802e4"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/shirou/gopsutil/common",
|
|
||||||
"Comment": "1.0.0-161-g3303647",
|
|
||||||
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/shirou/gopsutil/cpu",
|
"ImportPath": "github.com/shirou/gopsutil/cpu",
|
||||||
"Comment": "1.0.0-161-g3303647",
|
"Comment": "1.0.0-161-g3303647",
|
||||||
|
|
|
@ -1,209 +0,0 @@
|
||||||
//
|
|
||||||
// gopsutil is a port of psutil(http://pythonhosted.org/psutil/).
|
|
||||||
// This covers these architectures.
|
|
||||||
// - linux (amd64, arm)
|
|
||||||
// - freebsd (amd64)
|
|
||||||
// - windows (amd64)
|
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Invoker interface {
|
|
||||||
Command(string, ...string) ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Invoke struct{}
|
|
||||||
|
|
||||||
func (i Invoke) Command(name string, arg ...string) ([]byte, error) {
|
|
||||||
return exec.Command(name, arg...).Output()
|
|
||||||
}
|
|
||||||
|
|
||||||
type FakeInvoke struct {
|
|
||||||
CommandExpectedDir string // CommandExpectedDir specifies dir which includes expected outputs.
|
|
||||||
Suffix string // Suffix species expected file name suffix such as "fail"
|
|
||||||
Error error // If Error specfied, return the error.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command in FakeInvoke returns from expected file if exists.
|
|
||||||
func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
|
|
||||||
if i.Error != nil {
|
|
||||||
return []byte{}, i.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
arch := runtime.GOOS
|
|
||||||
|
|
||||||
fname := strings.Join(append([]string{name}, arg...), "")
|
|
||||||
fname = url.QueryEscape(fname)
|
|
||||||
var dir string
|
|
||||||
if i.CommandExpectedDir == "" {
|
|
||||||
dir = "expected"
|
|
||||||
} else {
|
|
||||||
dir = i.CommandExpectedDir
|
|
||||||
}
|
|
||||||
fpath := path.Join(dir, arch, fname)
|
|
||||||
if i.Suffix != "" {
|
|
||||||
fpath += "_" + i.Suffix
|
|
||||||
}
|
|
||||||
if PathExists(fpath) {
|
|
||||||
return ioutil.ReadFile(fpath)
|
|
||||||
} else {
|
|
||||||
return exec.Command(name, arg...).Output()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var NotImplementedError = errors.New("not implemented yet")
|
|
||||||
|
|
||||||
// ReadLines reads contents from a file and splits them by new lines.
|
|
||||||
// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
|
|
||||||
func ReadLines(filename string) ([]string, error) {
|
|
||||||
return ReadLinesOffsetN(filename, 0, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadLines reads contents from file and splits them by new line.
|
|
||||||
// The offset tells at which line number to start.
|
|
||||||
// The count determines the number of lines to read (starting from offset):
|
|
||||||
// n >= 0: at most n lines
|
|
||||||
// n < 0: whole file
|
|
||||||
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return []string{""}, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
var ret []string
|
|
||||||
|
|
||||||
r := bufio.NewReader(f)
|
|
||||||
for i := 0; i < n+int(offset) || n < 0; i++ {
|
|
||||||
line, err := r.ReadString('\n')
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if i < int(offset) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ret = append(ret, strings.Trim(line, "\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func IntToString(orig []int8) string {
|
|
||||||
ret := make([]byte, len(orig))
|
|
||||||
size := -1
|
|
||||||
for i, o := range orig {
|
|
||||||
if o == 0 {
|
|
||||||
size = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ret[i] = byte(o)
|
|
||||||
}
|
|
||||||
if size == -1 {
|
|
||||||
size = len(orig)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(ret[0:size])
|
|
||||||
}
|
|
||||||
|
|
||||||
func ByteToString(orig []byte) string {
|
|
||||||
n := -1
|
|
||||||
l := -1
|
|
||||||
for i, b := range orig {
|
|
||||||
// skip left side null
|
|
||||||
if l == -1 && b == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if l == -1 {
|
|
||||||
l = i
|
|
||||||
}
|
|
||||||
|
|
||||||
if b == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n = i + 1
|
|
||||||
}
|
|
||||||
if n == -1 {
|
|
||||||
return string(orig)
|
|
||||||
}
|
|
||||||
return string(orig[l:n])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse to int32 without error
|
|
||||||
func mustParseInt32(val string) int32 {
|
|
||||||
vv, _ := strconv.ParseInt(val, 10, 32)
|
|
||||||
return int32(vv)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse to uint64 without error
|
|
||||||
func mustParseUint64(val string) uint64 {
|
|
||||||
vv, _ := strconv.ParseInt(val, 10, 64)
|
|
||||||
return uint64(vv)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse to Float64 without error
|
|
||||||
func mustParseFloat64(val string) float64 {
|
|
||||||
vv, _ := strconv.ParseFloat(val, 64)
|
|
||||||
return vv
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringsHas checks the target string slice containes src or not
|
|
||||||
func StringsHas(target []string, src string) bool {
|
|
||||||
for _, t := range target {
|
|
||||||
if strings.TrimSpace(t) == src {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringsContains checks the src in any string of the target string slice
|
|
||||||
func StringsContains(target []string, src string) bool {
|
|
||||||
for _, t := range target {
|
|
||||||
if strings.Contains(t, src) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// get struct attributes.
|
|
||||||
// This method is used only for debugging platform dependent code.
|
|
||||||
func attributes(m interface{}) map[string]reflect.Type {
|
|
||||||
typ := reflect.TypeOf(m)
|
|
||||||
if typ.Kind() == reflect.Ptr {
|
|
||||||
typ = typ.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
attrs := make(map[string]reflect.Type)
|
|
||||||
if typ.Kind() != reflect.Struct {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
|
||||||
p := typ.Field(i)
|
|
||||||
if !p.Anonymous {
|
|
||||||
attrs[p.Name] = p.Type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return attrs
|
|
||||||
}
|
|
||||||
|
|
||||||
func PathExists(filename string) bool {
|
|
||||||
if _, err := os.Stat(filename); err == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
// +build darwin
|
|
||||||
|
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DoSysctrl(mib string) ([]string, error) {
|
|
||||||
out, err := exec.Command("/usr/sbin/sysctl", "-n", mib).Output()
|
|
||||||
if err != nil {
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
v := strings.Replace(string(out), "{ ", "", 1)
|
|
||||||
v = strings.Replace(string(v), " }", "", 1)
|
|
||||||
values := strings.Fields(string(v))
|
|
||||||
|
|
||||||
return values, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
|
||||||
miblen := uint64(len(mib))
|
|
||||||
|
|
||||||
// get required buffer size
|
|
||||||
length := uint64(0)
|
|
||||||
_, _, err := syscall.Syscall6(
|
|
||||||
syscall.SYS___SYSCTL,
|
|
||||||
uintptr(unsafe.Pointer(&mib[0])),
|
|
||||||
uintptr(miblen),
|
|
||||||
0,
|
|
||||||
uintptr(unsafe.Pointer(&length)),
|
|
||||||
0,
|
|
||||||
0)
|
|
||||||
if err != 0 {
|
|
||||||
var b []byte
|
|
||||||
return b, length, err
|
|
||||||
}
|
|
||||||
if length == 0 {
|
|
||||||
var b []byte
|
|
||||||
return b, length, err
|
|
||||||
}
|
|
||||||
// get proc info itself
|
|
||||||
buf := make([]byte, length)
|
|
||||||
_, _, err = syscall.Syscall6(
|
|
||||||
syscall.SYS___SYSCTL,
|
|
||||||
uintptr(unsafe.Pointer(&mib[0])),
|
|
||||||
uintptr(miblen),
|
|
||||||
uintptr(unsafe.Pointer(&buf[0])),
|
|
||||||
uintptr(unsafe.Pointer(&length)),
|
|
||||||
0,
|
|
||||||
0)
|
|
||||||
if err != 0 {
|
|
||||||
return buf, length, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf, length, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
|
|
||||||
var cmd []string
|
|
||||||
if pid == 0 { // will get from all processes.
|
|
||||||
cmd = []string{"-a", "-n", "-P"}
|
|
||||||
} else {
|
|
||||||
cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
|
|
||||||
}
|
|
||||||
cmd = append(cmd, args...)
|
|
||||||
lsof, err := exec.LookPath("lsof")
|
|
||||||
if err != nil {
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
out, err := invoke.Command(lsof, cmd...)
|
|
||||||
if err != nil {
|
|
||||||
// if not pid found, lsof returnes code 1
|
|
||||||
if err.Error() == "exit status 1" && len(out) == 0 {
|
|
||||||
return []string{}, nil
|
|
||||||
}
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
lines := strings.Split(string(out), "\n")
|
|
||||||
|
|
||||||
var ret []string
|
|
||||||
for _, l := range lines[1:] {
|
|
||||||
if len(l) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ret = append(ret, l)
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
// +build freebsd
|
|
||||||
|
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func DoSysctrl(mib string) ([]string, error) {
|
|
||||||
out, err := exec.Command("/sbin/sysctl", "-n", mib).Output()
|
|
||||||
if err != nil {
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
v := strings.Replace(string(out), "{ ", "", 1)
|
|
||||||
v = strings.Replace(string(v), " }", "", 1)
|
|
||||||
values := strings.Fields(string(v))
|
|
||||||
|
|
||||||
return values, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
|
||||||
miblen := uint64(len(mib))
|
|
||||||
|
|
||||||
// get required buffer size
|
|
||||||
length := uint64(0)
|
|
||||||
_, _, err := syscall.Syscall6(
|
|
||||||
syscall.SYS___SYSCTL,
|
|
||||||
uintptr(unsafe.Pointer(&mib[0])),
|
|
||||||
uintptr(miblen),
|
|
||||||
0,
|
|
||||||
uintptr(unsafe.Pointer(&length)),
|
|
||||||
0,
|
|
||||||
0)
|
|
||||||
if err != 0 {
|
|
||||||
var b []byte
|
|
||||||
return b, length, err
|
|
||||||
}
|
|
||||||
if length == 0 {
|
|
||||||
var b []byte
|
|
||||||
return b, length, err
|
|
||||||
}
|
|
||||||
// get proc info itself
|
|
||||||
buf := make([]byte, length)
|
|
||||||
_, _, err = syscall.Syscall6(
|
|
||||||
syscall.SYS___SYSCTL,
|
|
||||||
uintptr(unsafe.Pointer(&mib[0])),
|
|
||||||
uintptr(miblen),
|
|
||||||
uintptr(unsafe.Pointer(&buf[0])),
|
|
||||||
uintptr(unsafe.Pointer(&length)),
|
|
||||||
0,
|
|
||||||
0)
|
|
||||||
if err != 0 {
|
|
||||||
return buf, length, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf, length, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CallLsof invokes lsof to get connection informations.
|
|
||||||
// This is same as darwin currently.
|
|
||||||
func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
|
|
||||||
var cmd []string
|
|
||||||
if pid == 0 { // will get from all processes.
|
|
||||||
cmd = []string{"-a", "-n", "-P"}
|
|
||||||
} else {
|
|
||||||
cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
|
|
||||||
}
|
|
||||||
cmd = append(cmd, args...)
|
|
||||||
lsof, err := exec.LookPath("lsof")
|
|
||||||
if err != nil {
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
out, err := invoke.Command(lsof, cmd...)
|
|
||||||
if err != nil {
|
|
||||||
// if not pid found, lsof returnes code 1
|
|
||||||
if err.Error() == "exit status 1" && len(out) == 0 {
|
|
||||||
return []string{}, nil
|
|
||||||
}
|
|
||||||
return []string{}, err
|
|
||||||
}
|
|
||||||
lines := strings.Split(string(out), "\n")
|
|
||||||
|
|
||||||
var ret []string
|
|
||||||
for _, l := range lines[1:] {
|
|
||||||
if len(l) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ret = append(ret, l)
|
|
||||||
}
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestReadlines(t *testing.T) {
|
|
||||||
ret, err := ReadLines("common_test.go")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if !strings.Contains(ret[0], "package common") {
|
|
||||||
t.Error("could not read correctly")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadLinesOffsetN(t *testing.T) {
|
|
||||||
ret, err := ReadLinesOffsetN("common_test.go", 2, 1)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
fmt.Println(ret[0])
|
|
||||||
if !strings.Contains(ret[0], `import (`) {
|
|
||||||
t.Error("could not read correctly")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIntToString(t *testing.T) {
|
|
||||||
src := []int8{65, 66, 67}
|
|
||||||
dst := IntToString(src)
|
|
||||||
if dst != "ABC" {
|
|
||||||
t.Error("could not convert")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestByteToString(t *testing.T) {
|
|
||||||
src := []byte{65, 66, 67}
|
|
||||||
dst := ByteToString(src)
|
|
||||||
if dst != "ABC" {
|
|
||||||
t.Error("could not convert")
|
|
||||||
}
|
|
||||||
|
|
||||||
src = []byte{0, 65, 66, 67}
|
|
||||||
dst = ByteToString(src)
|
|
||||||
if dst != "ABC" {
|
|
||||||
t.Error("could not convert")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestmustParseInt32(t *testing.T) {
|
|
||||||
ret := mustParseInt32("11111")
|
|
||||||
if ret != int32(11111) {
|
|
||||||
t.Error("could not parse")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestmustParseUint64(t *testing.T) {
|
|
||||||
ret := mustParseUint64("11111")
|
|
||||||
if ret != uint64(11111) {
|
|
||||||
t.Error("could not parse")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestmustParseFloat64(t *testing.T) {
|
|
||||||
ret := mustParseFloat64("11111.11")
|
|
||||||
if ret != float64(11111.11) {
|
|
||||||
t.Error("could not parse")
|
|
||||||
}
|
|
||||||
ret = mustParseFloat64("11111")
|
|
||||||
if ret != float64(11111) {
|
|
||||||
t.Error("could not parse")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func TestStringsContains(t *testing.T) {
|
|
||||||
target, err := ReadLines("common_test.go")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if !StringsContains(target, "func TestStringsContains(t *testing.T) {") {
|
|
||||||
t.Error("cloud not test correctly")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPathExists(t *testing.T) {
|
|
||||||
if !PathExists("common_test.go") {
|
|
||||||
t.Error("exists but return not exists")
|
|
||||||
}
|
|
||||||
if PathExists("should_not_exists.go") {
|
|
||||||
t.Error("not exists but return exists")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package common
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// for double values
|
|
||||||
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
|
|
||||||
CStatus uint32
|
|
||||||
DoubleValue float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// for 64 bit integer values
|
|
||||||
type PDH_FMT_COUNTERVALUE_LARGE struct {
|
|
||||||
CStatus uint32
|
|
||||||
LargeValue int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// for long values
|
|
||||||
type PDH_FMT_COUNTERVALUE_LONG struct {
|
|
||||||
CStatus uint32
|
|
||||||
LongValue int32
|
|
||||||
padding [4]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// windows system const
|
|
||||||
const (
|
|
||||||
ERROR_SUCCESS = 0
|
|
||||||
ERROR_FILE_NOT_FOUND = 2
|
|
||||||
DRIVE_REMOVABLE = 2
|
|
||||||
DRIVE_FIXED = 3
|
|
||||||
HKEY_LOCAL_MACHINE = 0x80000002
|
|
||||||
RRF_RT_REG_SZ = 0x00000002
|
|
||||||
RRF_RT_REG_DWORD = 0x00000010
|
|
||||||
PDH_FMT_LONG = 0x00000100
|
|
||||||
PDH_FMT_DOUBLE = 0x00000200
|
|
||||||
PDH_FMT_LARGE = 0x00000400
|
|
||||||
PDH_INVALID_DATA = 0xc0000bc6
|
|
||||||
PDH_INVALID_HANDLE = 0xC0000bbc
|
|
||||||
PDH_NO_DATA = 0x800007d5
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
ModNt = syscall.NewLazyDLL("ntdll.dll")
|
|
||||||
ModPdh = syscall.NewLazyDLL("pdh.dll")
|
|
||||||
|
|
||||||
ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes")
|
|
||||||
ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
|
|
||||||
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
|
||||||
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
|
||||||
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
|
||||||
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
|
||||||
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
|
||||||
)
|
|
||||||
|
|
||||||
type FILETIME struct {
|
|
||||||
DwLowDateTime uint32
|
|
||||||
DwHighDateTime uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// borrowed from net/interface_windows.go
|
|
||||||
func BytePtrToString(p *uint8) string {
|
|
||||||
a := (*[10000]uint8)(unsafe.Pointer(p))
|
|
||||||
i := 0
|
|
||||||
for a[i] != 0 {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
return string(a[:i])
|
|
||||||
}
|
|
||||||
|
|
||||||
// CounterInfo
|
|
||||||
// copied from https://github.com/mackerelio/mackerel-agent/
|
|
||||||
type CounterInfo struct {
|
|
||||||
PostName string
|
|
||||||
CounterName string
|
|
||||||
Counter syscall.Handle
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateQuery XXX
|
|
||||||
// copied from https://github.com/mackerelio/mackerel-agent/
|
|
||||||
func CreateQuery() (syscall.Handle, error) {
|
|
||||||
var query syscall.Handle
|
|
||||||
r, _, err := PdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query)))
|
|
||||||
if r != 0 {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return query, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateCounter XXX
|
|
||||||
func CreateCounter(query syscall.Handle, pname, cname string) (*CounterInfo, error) {
|
|
||||||
var counter syscall.Handle
|
|
||||||
r, _, err := PdhAddCounter.Call(
|
|
||||||
uintptr(query),
|
|
||||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(cname))),
|
|
||||||
0,
|
|
||||||
uintptr(unsafe.Pointer(&counter)))
|
|
||||||
if r != 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &CounterInfo{
|
|
||||||
PostName: pname,
|
|
||||||
CounterName: cname,
|
|
||||||
Counter: counter,
|
|
||||||
}, nil
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package telegraf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -107,7 +108,10 @@ func (ac *accumulator) AddFields(
|
||||||
measurement = ac.prefix + measurement
|
measurement = ac.prefix + measurement
|
||||||
}
|
}
|
||||||
|
|
||||||
pt := client.NewPoint(measurement, tags, fields, timestamp)
|
pt, err := client.NewPoint(measurement, tags, fields, timestamp)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error adding point [%s]: %s\n", measurement, err.Error())
|
||||||
|
}
|
||||||
if ac.debug {
|
if ac.debug {
|
||||||
fmt.Println("> " + pt.String())
|
fmt.Println("> " + pt.String())
|
||||||
}
|
}
|
||||||
|
|
14
agent.go
14
agent.go
|
@ -10,7 +10,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
"github.com/influxdb/telegraf/plugins"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
|
|
||||||
|
@ -32,20 +32,20 @@ type runningPlugin struct {
|
||||||
type Agent struct {
|
type Agent struct {
|
||||||
|
|
||||||
// Interval at which to gather information
|
// Interval at which to gather information
|
||||||
Interval duration.Duration
|
Interval internal.Duration
|
||||||
|
|
||||||
// RoundInterval rounds collection interval to 'interval'.
|
// RoundInterval rounds collection interval to 'interval'.
|
||||||
// ie, if Interval=10s then always collect on :00, :10, :20, etc.
|
// ie, if Interval=10s then always collect on :00, :10, :20, etc.
|
||||||
RoundInterval bool
|
RoundInterval bool
|
||||||
|
|
||||||
// Interval at which to flush data
|
// Interval at which to flush data
|
||||||
FlushInterval duration.Duration
|
FlushInterval internal.Duration
|
||||||
|
|
||||||
// FlushRetries is the number of times to retry each data flush
|
// FlushRetries is the number of times to retry each data flush
|
||||||
FlushRetries int
|
FlushRetries int
|
||||||
|
|
||||||
// FlushJitter tells
|
// FlushJitter tells
|
||||||
FlushJitter duration.Duration
|
FlushJitter internal.Duration
|
||||||
|
|
||||||
// TODO(cam): Remove UTC and Precision parameters, they are no longer
|
// TODO(cam): Remove UTC and Precision parameters, they are no longer
|
||||||
// valid for the agent config. Leaving them here for now for backwards-
|
// valid for the agent config. Leaving them here for now for backwards-
|
||||||
|
@ -72,11 +72,11 @@ type Agent struct {
|
||||||
func NewAgent(config *Config) (*Agent, error) {
|
func NewAgent(config *Config) (*Agent, error) {
|
||||||
agent := &Agent{
|
agent := &Agent{
|
||||||
Tags: make(map[string]string),
|
Tags: make(map[string]string),
|
||||||
Interval: duration.Duration{10 * time.Second},
|
Interval: internal.Duration{10 * time.Second},
|
||||||
RoundInterval: true,
|
RoundInterval: true,
|
||||||
FlushInterval: duration.Duration{10 * time.Second},
|
FlushInterval: internal.Duration{10 * time.Second},
|
||||||
FlushRetries: 2,
|
FlushRetries: 2,
|
||||||
FlushJitter: duration.Duration{5 * time.Second},
|
FlushJitter: internal.Duration{5 * time.Second},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the toml table to the agent config, overriding defaults
|
// Apply the toml table to the agent config, overriding defaults
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
|
|
||||||
// needing to load the plugins
|
// needing to load the plugins
|
||||||
_ "github.com/influxdb/telegraf/plugins/all"
|
_ "github.com/influxdb/telegraf/plugins/all"
|
||||||
|
@ -61,8 +61,8 @@ func TestAgent_LoadOutput(t *testing.T) {
|
||||||
|
|
||||||
func TestAgent_ZeroJitter(t *testing.T) {
|
func TestAgent_ZeroJitter(t *testing.T) {
|
||||||
a := &Agent{
|
a := &Agent{
|
||||||
FlushInterval: duration.Duration{10 * time.Second},
|
FlushInterval: internal.Duration{10 * time.Second},
|
||||||
FlushJitter: duration.Duration{0 * time.Second},
|
FlushJitter: internal.Duration{0 * time.Second},
|
||||||
}
|
}
|
||||||
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
||||||
a.FlushJitter.Duration)
|
a.FlushJitter.Duration)
|
||||||
|
@ -81,8 +81,8 @@ func TestAgent_ZeroInterval(t *testing.T) {
|
||||||
|
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
a := &Agent{
|
a := &Agent{
|
||||||
FlushInterval: duration.Duration{0 * time.Second},
|
FlushInterval: internal.Duration{0 * time.Second},
|
||||||
FlushJitter: duration.Duration{5 * time.Second},
|
FlushJitter: internal.Duration{5 * time.Second},
|
||||||
}
|
}
|
||||||
|
|
||||||
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
||||||
|
@ -102,8 +102,8 @@ func TestAgent_ZeroInterval(t *testing.T) {
|
||||||
|
|
||||||
func TestAgent_ZeroBoth(t *testing.T) {
|
func TestAgent_ZeroBoth(t *testing.T) {
|
||||||
a := &Agent{
|
a := &Agent{
|
||||||
FlushInterval: duration.Duration{0 * time.Second},
|
FlushInterval: internal.Duration{0 * time.Second},
|
||||||
FlushJitter: duration.Duration{0 * time.Second},
|
FlushJitter: internal.Duration{0 * time.Second},
|
||||||
}
|
}
|
||||||
|
|
||||||
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
||||||
|
@ -122,8 +122,8 @@ func TestAgent_JitterMax(t *testing.T) {
|
||||||
|
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
a := &Agent{
|
a := &Agent{
|
||||||
FlushInterval: duration.Duration{30 * time.Second},
|
FlushInterval: internal.Duration{30 * time.Second},
|
||||||
FlushJitter: duration.Duration{2 * time.Second},
|
FlushJitter: internal.Duration{2 * time.Second},
|
||||||
}
|
}
|
||||||
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
||||||
a.FlushJitter.Duration)
|
a.FlushJitter.Duration)
|
||||||
|
@ -140,8 +140,8 @@ func TestAgent_JitterMin(t *testing.T) {
|
||||||
|
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
a := &Agent{
|
a := &Agent{
|
||||||
FlushInterval: duration.Duration{30 * time.Second},
|
FlushInterval: internal.Duration{30 * time.Second},
|
||||||
FlushJitter: duration.Duration{2 * time.Second},
|
FlushJitter: internal.Duration{2 * time.Second},
|
||||||
}
|
}
|
||||||
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
flushinterval := jitterInterval(a.FlushInterval.Duration,
|
||||||
a.FlushJitter.Duration)
|
a.FlushJitter.Duration)
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package duration
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// Duration just wraps time.Duration
|
|
||||||
type Duration struct {
|
|
||||||
time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalTOML parses the duration from the TOML config file
|
|
||||||
func (d *Duration) UnmarshalTOML(b []byte) error {
|
|
||||||
dur, err := time.ParseDuration(string(b[1 : len(b)-1]))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Duration = dur
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Duration just wraps time.Duration
|
||||||
|
type Duration struct {
|
||||||
|
time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalTOML parses the duration from the TOML config file
|
||||||
|
func (d *Duration) UnmarshalTOML(b []byte) error {
|
||||||
|
dur, err := time.ParseDuration(string(b[1 : len(b)-1]))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Duration = dur
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var NotImplementedError = errors.New("not implemented yet")
|
||||||
|
|
||||||
|
// ReadLines reads contents from a file and splits them by new lines.
|
||||||
|
// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
|
||||||
|
func ReadLines(filename string) ([]string, error) {
|
||||||
|
return ReadLinesOffsetN(filename, 0, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadLines reads contents from file and splits them by new line.
|
||||||
|
// The offset tells at which line number to start.
|
||||||
|
// The count determines the number of lines to read (starting from offset):
|
||||||
|
// n >= 0: at most n lines
|
||||||
|
// n < 0: whole file
|
||||||
|
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return []string{""}, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var ret []string
|
||||||
|
|
||||||
|
r := bufio.NewReader(f)
|
||||||
|
for i := 0; i < n+int(offset) || n < 0; i++ {
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i < int(offset) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = append(ret, strings.Trim(line, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
|
@ -9,14 +9,14 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Amon struct {
|
type Amon struct {
|
||||||
ServerKey string
|
ServerKey string
|
||||||
AmonInstance string
|
AmonInstance string
|
||||||
Timeout duration.Duration
|
Timeout internal.Duration
|
||||||
|
|
||||||
client *http.Client
|
client *http.Client
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Datadog struct {
|
type Datadog struct {
|
||||||
Apikey string
|
Apikey string
|
||||||
Timeout duration.Duration
|
Timeout internal.Duration
|
||||||
|
|
||||||
apiUrl string
|
apiUrl string
|
||||||
client *http.Client
|
client *http.Client
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ type InfluxDB struct {
|
||||||
Database string
|
Database string
|
||||||
UserAgent string
|
UserAgent string
|
||||||
Precision string
|
Precision string
|
||||||
Timeout duration.Duration
|
Timeout internal.Duration
|
||||||
|
|
||||||
conns []client.Client
|
conns []client.Client
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ type Librato struct {
|
||||||
ApiUser string
|
ApiUser string
|
||||||
ApiToken string
|
ApiToken string
|
||||||
SourceTag string
|
SourceTag string
|
||||||
Timeout duration.Duration
|
Timeout internal.Duration
|
||||||
|
|
||||||
apiUrl string
|
apiUrl string
|
||||||
client *http.Client
|
client *http.Client
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
paho "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
|
paho "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/duration"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ type MQTT struct {
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
Database string
|
Database string
|
||||||
Timeout duration.Duration
|
Timeout internal.Duration
|
||||||
TopicPrefix string
|
TopicPrefix string
|
||||||
|
|
||||||
Client *paho.Client
|
Client *paho.Client
|
||||||
|
|
|
@ -13,8 +13,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
common "github.com/shirou/gopsutil/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Lustre proc files can change between versions, so we want to future-proof
|
// Lustre proc files can change between versions, so we want to future-proof
|
||||||
|
@ -144,7 +144,7 @@ func (l *Lustre2) GetLustreProcStats(fileglob string, wanted_fields []*mapping,
|
||||||
"name": name,
|
"name": name,
|
||||||
}
|
}
|
||||||
|
|
||||||
lines, err := common.ReadLines(file)
|
lines, err := internal.ReadLines(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
dc "github.com/fsouza/go-dockerclient"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
"github.com/shirou/gopsutil/common"
|
|
||||||
|
dc "github.com/fsouza/go-dockerclient"
|
||||||
"github.com/shirou/gopsutil/cpu"
|
"github.com/shirou/gopsutil/cpu"
|
||||||
"github.com/shirou/gopsutil/disk"
|
"github.com/shirou/gopsutil/disk"
|
||||||
"github.com/shirou/gopsutil/docker"
|
"github.com/shirou/gopsutil/docker"
|
||||||
|
@ -97,7 +98,7 @@ func (s *systemPS) NetConnections() ([]net.NetConnectionStat, error) {
|
||||||
|
|
||||||
func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) {
|
func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) {
|
||||||
m, err := disk.DiskIOCounters()
|
m, err := disk.DiskIOCounters()
|
||||||
if err == common.NotImplementedError {
|
if err == internal.NotImplementedError {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
"github.com/shirou/gopsutil/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Zfs struct {
|
type Zfs struct {
|
||||||
|
@ -60,7 +60,7 @@ func (z *Zfs) Gather(acc plugins.Accumulator) error {
|
||||||
tags := getTags(kstatPath)
|
tags := getTags(kstatPath)
|
||||||
|
|
||||||
for _, metric := range kstatMetrics {
|
for _, metric := range kstatMetrics {
|
||||||
lines, err := common.ReadLines(kstatPath + "/" + metric)
|
lines, err := internal.ReadLines(kstatPath + "/" + metric)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue