dd9309c15e
Initial vendor list validated with empty $GOPATH and only master checked out; followed by `make` and verified that all binaries build properly. Updates require github.com/LK4D4/vndr tool. Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
115 lines
2 KiB
Go
115 lines
2 KiB
Go
// Copyright 2015 Apcera Inc. All rights reserved.
|
|
|
|
package pse
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"sync/atomic"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
procStatFile string
|
|
ticks int64
|
|
lastTotal int64
|
|
lastSeconds int64
|
|
ipcpu int64
|
|
)
|
|
|
|
const (
|
|
utimePos = 13
|
|
stimePos = 14
|
|
startPos = 21
|
|
vssPos = 22
|
|
rssPos = 23
|
|
)
|
|
|
|
func init() {
|
|
// Avoiding to generate docker image without CGO
|
|
ticks = 100 // int64(C.sysconf(C._SC_CLK_TCK))
|
|
procStatFile = fmt.Sprintf("/proc/%d/stat", os.Getpid())
|
|
periodic()
|
|
}
|
|
|
|
// Sampling function to keep pcpu relevant.
|
|
func periodic() {
|
|
contents, err := ioutil.ReadFile(procStatFile)
|
|
if err != nil {
|
|
return
|
|
}
|
|
fields := bytes.Fields(contents)
|
|
|
|
// PCPU
|
|
pstart := parseInt64(fields[startPos])
|
|
utime := parseInt64(fields[utimePos])
|
|
stime := parseInt64(fields[stimePos])
|
|
total := utime + stime
|
|
|
|
var sysinfo syscall.Sysinfo_t
|
|
if err := syscall.Sysinfo(&sysinfo); err != nil {
|
|
return
|
|
}
|
|
|
|
seconds := int64(sysinfo.Uptime) - (pstart / ticks)
|
|
|
|
// Save off temps
|
|
lt := lastTotal
|
|
ls := lastSeconds
|
|
|
|
// Update last sample
|
|
lastTotal = total
|
|
lastSeconds = seconds
|
|
|
|
// Adjust to current time window
|
|
total -= lt
|
|
seconds -= ls
|
|
|
|
if seconds > 0 {
|
|
atomic.StoreInt64(&ipcpu, (total*1000/ticks)/seconds)
|
|
}
|
|
|
|
time.AfterFunc(1*time.Second, periodic)
|
|
}
|
|
|
|
func ProcUsage(pcpu *float64, rss, vss *int64) error {
|
|
contents, err := ioutil.ReadFile(procStatFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fields := bytes.Fields(contents)
|
|
|
|
// Memory
|
|
*rss = (parseInt64(fields[rssPos])) << 12
|
|
*vss = parseInt64(fields[vssPos])
|
|
|
|
// PCPU
|
|
// We track this with periodic sampling, so just load and go.
|
|
*pcpu = float64(atomic.LoadInt64(&ipcpu)) / 10.0
|
|
|
|
return nil
|
|
}
|
|
|
|
// Ascii numbers 0-9
|
|
const (
|
|
asciiZero = 48
|
|
asciiNine = 57
|
|
)
|
|
|
|
// parseInt64 expects decimal positive numbers. We
|
|
// return -1 to signal error
|
|
func parseInt64(d []byte) (n int64) {
|
|
if len(d) == 0 {
|
|
return -1
|
|
}
|
|
for _, dec := range d {
|
|
if dec < asciiZero || dec > asciiNine {
|
|
return -1
|
|
}
|
|
n = n*10 + (int64(dec) - asciiZero)
|
|
}
|
|
return n
|
|
}
|