mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-16 11:04:42 -07:00
removal of need for ps
This commit is contained in:
62
server/pse_linux.go
Normal file
62
server/pse_linux.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
package server
|
||||
|
||||
/*
|
||||
#include <unistd.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var procStatFile string
|
||||
var ticks int64
|
||||
|
||||
const (
|
||||
utimePos = 13
|
||||
stimePos = 14
|
||||
startPos = 21
|
||||
vssPos = 22
|
||||
rssPos = 23
|
||||
)
|
||||
|
||||
func init() {
|
||||
ticks = int64(C.sysconf(C._SC_CLK_TCK))
|
||||
procStatFile = fmt.Sprintf("/proc/%d/stat", os.Getpid())
|
||||
}
|
||||
|
||||
func procUsage(pcpu *float64, rss, vss *int64) error {
|
||||
contents, err := ioutil.ReadFile(procStatFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields := bytes.Fields(contents)
|
||||
|
||||
*rss = (parseInt64(fields[rssPos])) << 12
|
||||
*vss = parseInt64(fields[vssPos])
|
||||
|
||||
startTime := parseInt64(fields[startPos])
|
||||
utime := parseInt64(fields[utimePos])
|
||||
stime := parseInt64(fields[stimePos])
|
||||
totalTime := utime + stime
|
||||
|
||||
sysinfo := syscall.Sysinfo_t{}
|
||||
if err := syscall.Sysinfo(&sysinfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seconds := sysinfo.Uptime - (startTime / ticks)
|
||||
|
||||
if seconds > 0 {
|
||||
ipcpu := (totalTime * 1000 / ticks) / seconds
|
||||
*pcpu = float64(ipcpu) / 10.0
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
49
server/pse_test.go
Normal file
49
server/pse_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPSEmulation(t *testing.T) {
|
||||
var rss, vss, psRss, psVss int64
|
||||
var pcpu, psPcpu float64
|
||||
|
||||
// PS version first
|
||||
pidStr := fmt.Sprintf("%d", os.Getpid())
|
||||
out, err := exec.Command("ps", "o", "pcpu=,rss=,vsz=", "-p", pidStr).Output()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to execute ps command: %v\n", err)
|
||||
}
|
||||
|
||||
fmt.Sscanf(string(out), "%f %d %d", &psPcpu, &psRss, &psVss)
|
||||
psRss *= 1024 // 1k blocks, want bytes.
|
||||
psVss *= 1024 // 1k blocks, want bytes.
|
||||
|
||||
// Our internal version
|
||||
procUsage(&pcpu, &rss, &vss)
|
||||
|
||||
if pcpu != psPcpu {
|
||||
delta := int64(pcpu - psPcpu)
|
||||
if delta < 0 {
|
||||
delta = -delta
|
||||
}
|
||||
if delta > 5 { // 5%
|
||||
t.Fatalf("CPUs did not match close enough: %f vs %f", pcpu, psPcpu)
|
||||
}
|
||||
}
|
||||
if rss != psRss {
|
||||
delta := rss - psRss
|
||||
if delta < 0 {
|
||||
delta = -delta
|
||||
}
|
||||
t.Logf("delta is %d\n", delta)
|
||||
if delta > 200*1024 { // 200k
|
||||
t.Fatalf("RSSs did not match close enough: %d vs %d", rss, psRss)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user