mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-24 13:48:56 +08:00
Merge pull request #1579 from shirou/feature/enable_cache_on_host_boottime
[host]: add EnableBootTimeCache function
This commit is contained in:
commit
9627f199e2
11
README.md
11
README.md
@ -109,6 +109,17 @@ As of v3.23.6, it is now possible to pass a path location using `context`: impor
|
||||
|
||||
First priority is given to the value set in `context`, then the value from the environment variable, and finally the default location.
|
||||
|
||||
### Caching
|
||||
|
||||
As of v3.24.1, it is now possible to cached some values. These values default to false, not cached.
|
||||
|
||||
Be very careful that enabling the cache may cause inconsistencies. For example, if you enable caching of boottime on Linux, be aware that unintended values may be returned if [the boottime is changed by NTP after booted](https://github.com/shirou/gopsutil/issues/1070#issuecomment-842512782).
|
||||
|
||||
- `host`
|
||||
- EnableBootTimeCache
|
||||
- `process`
|
||||
- EnableBootTimeCache
|
||||
|
||||
## Documentation
|
||||
|
||||
See https://pkg.go.dev/github.com/shirou/gopsutil/v3 or https://godocs.io/github.com/shirou/gopsutil/v3
|
||||
|
@ -62,6 +62,13 @@ func (t TemperatureStat) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
var enableBootTimeCache bool
|
||||
|
||||
// EnableBootTimeCache change cache behavior of BootTime. If true, cache BootTime value. Default is false.
|
||||
func EnableBootTimeCache(enable bool) {
|
||||
enableBootTimeCache = enable
|
||||
}
|
||||
|
||||
func Info() (*InfoStat, error) {
|
||||
return InfoWithContext(context.Background())
|
||||
}
|
||||
|
@ -14,16 +14,20 @@ import (
|
||||
var cachedBootTime uint64
|
||||
|
||||
func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
t := atomic.LoadUint64(&cachedBootTime)
|
||||
if t != 0 {
|
||||
return t, nil
|
||||
if enableBootTimeCache {
|
||||
t := atomic.LoadUint64(&cachedBootTime)
|
||||
if t != 0 {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
tv, err := unix.SysctlTimeval("kern.boottime")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
atomic.StoreUint64(&cachedBootTime, uint64(tv.Sec))
|
||||
if enableBootTimeCache {
|
||||
atomic.StoreUint64(&cachedBootTime, uint64(tv.Sec))
|
||||
}
|
||||
|
||||
return uint64(tv.Sec), nil
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func numProcs(ctx context.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
return common.BootTimeWithContext(ctx)
|
||||
return common.BootTimeWithContext(ctx, enableBootTimeCache)
|
||||
}
|
||||
|
||||
func UptimeWithContext(ctx context.Context) (uint64, error) {
|
||||
|
@ -195,3 +195,17 @@ func TestPlatformInformation(t *testing.T) {
|
||||
|
||||
t.Logf("PlatformInformation(): %v, %v, %v", platform, family, version)
|
||||
}
|
||||
|
||||
func BenchmarkBootTimeWithCache(b *testing.B) {
|
||||
EnableBootTimeCache(true)
|
||||
for i := 0; i < b.N; i++ {
|
||||
BootTime()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBootTimeWithoutCache(b *testing.B) {
|
||||
EnableBootTimeCache(false)
|
||||
for i := 0; i < b.N; i++ {
|
||||
BootTime()
|
||||
}
|
||||
}
|
||||
|
@ -127,16 +127,20 @@ func uptimeMillis() (uint64, error) {
|
||||
var cachedBootTime uint64
|
||||
|
||||
func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
t := atomic.LoadUint64(&cachedBootTime)
|
||||
if t != 0 {
|
||||
return t, nil
|
||||
if enableBootTimeCache {
|
||||
t := atomic.LoadUint64(&cachedBootTime)
|
||||
if t != 0 {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
up, err := uptimeMillis()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
t = uint64((time.Duration(timeSinceMillis(up)) * time.Millisecond).Seconds())
|
||||
atomic.StoreUint64(&cachedBootTime, t)
|
||||
t := uint64((time.Duration(timeSinceMillis(up)) * time.Millisecond).Seconds())
|
||||
if enableBootTimeCache {
|
||||
atomic.StoreUint64(&cachedBootTime, t)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,14 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// cachedBootTime must be accessed via atomic.Load/StoreUint64
|
||||
var cachedBootTime uint64
|
||||
|
||||
func DoSysctrl(mib string) ([]string, error) {
|
||||
cmd := exec.Command("sysctl", "-n", mib)
|
||||
cmd.Env = getSysctrlEnv(os.Environ())
|
||||
@ -56,7 +60,14 @@ func NumProcsWithContext(ctx context.Context) (uint64, error) {
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
func BootTimeWithContext(ctx context.Context, enableCache bool) (uint64, error) {
|
||||
if enableCache {
|
||||
t := atomic.LoadUint64(&cachedBootTime)
|
||||
if t != 0 {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
|
||||
system, role, err := VirtualizationWithContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -72,7 +83,13 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
if useStatFile {
|
||||
return readBootTimeStat(ctx)
|
||||
t, err := readBootTimeStat(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if enableCache {
|
||||
atomic.StoreUint64(&cachedBootTime, t)
|
||||
}
|
||||
}
|
||||
|
||||
filename := HostProcWithContext(ctx, "uptime")
|
||||
@ -90,6 +107,11 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
}
|
||||
currentTime := float64(time.Now().UnixNano()) / float64(time.Second)
|
||||
t := currentTime - b
|
||||
|
||||
if enableCache {
|
||||
atomic.StoreUint64(&cachedBootTime, uint64(t))
|
||||
}
|
||||
|
||||
return uint64(t), nil
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,13 @@ func (p NumCtxSwitchesStat) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
var enableBootTimeCache bool
|
||||
|
||||
// EnableBootTimeCache change cache behavior of BootTime. If true, cache BootTime value. Default is false.
|
||||
func EnableBootTimeCache(enable bool) {
|
||||
enableBootTimeCache = enable
|
||||
}
|
||||
|
||||
// Pids returns a slice of process ID list which are running now.
|
||||
func Pids() ([]int32, error) {
|
||||
return PidsWithContext(context.Background())
|
||||
|
@ -1071,7 +1071,7 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
|
||||
Iowait: iotime / float64(clockTicks),
|
||||
}
|
||||
|
||||
bootTime, _ := common.BootTimeWithContext(ctx)
|
||||
bootTime, _ := common.BootTimeWithContext(ctx, enableBootTimeCache)
|
||||
t, err := strconv.ParseUint(fields[22], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, nil, 0, 0, 0, nil, err
|
||||
|
Loading…
x
Reference in New Issue
Block a user