delete v2 directory, move v3 to top #1078

pull/1174/head
shirou 3 years ago
parent 3b417071a5
commit 0969c9436b

@ -1,10 +1,6 @@
version: 2
updates:
- package-ecosystem: gomod
directory: /v3
schedule:
interval: daily
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily

@ -1,32 +1,21 @@
v3:
- v3/**/*.go
package:cpu:
- cpu/*
- v3/cpu/*
package:disk:
- disk/*
- v3/disk/*
package:docker:
- docker/*
- v3/docker/*
package:host:
- host/*
- v3/host/*
package:load:
- load/*
- v3/load/*
package:mem:
- mem/*
- v3/mem/*
package:net:
- net/*
- v3/net/*
package:process:
- process/*
- v3/process/*
package:winservices:
- winservices/*
- v3/winservices/*
os:linux:
- ./**/*_linux.go
- ./**/*_linux_mips64.go

@ -1,38 +1,6 @@
on: [push, pull_request]
name: Build Test
jobs:
build_test_v2:
env:
GOPATH: ${{ github.workspace }}
GO111MODULE: off
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
runs-on: ubuntu-20.04
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/src/github.com/shirou/gopsutil
- name: Get dependencies
if: runner.os != 'Windows'
run: |
if ! command -v dep &>/dev/null; then
mkdir -p $GOPATH/bin
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
echo "PATH=$GOPATH/bin:$PATH" >> $GITHUB_PATH
fi
cd $GOPATH/src/github.com/shirou/gopsutil
dep ensure
# exclude v3 from being run with ./...
rm -rf $GOPATH/src/github.com/shirou/gopsutil/v3
- name: Build Test v2
run: |
cd $GOPATH/src/github.com/shirou/gopsutil && make build_test
build_test_v3:
strategy:
matrix:
@ -47,4 +15,4 @@ jobs:
uses: actions/checkout@v2
- name: Build Test v3
run: |
cd v3 && make build_test
make build_test

@ -16,76 +16,4 @@ jobs:
uses: actions/checkout@v2
- name: Test
run: |
cd ./v3/
go test ./...
test_v3_gopath:
env:
GOPATH: ${{ github.workspace }}
GO111MODULE: off
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
os: [ubuntu-20.04, ubuntu-18.04, windows-2019, windows-2016, macOS-10.15, macos-11]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/src/github.com/shirou/gopsutil
- name: Get dependencies
run: |
go get -t github.com/shirou/gopsutil/v3/...
- name: Test
run: |
go test github.com/shirou/gopsutil/v3/...
test_v2_gopath:
env:
GOPATH: ${{ github.workspace }}
GO111MODULE: off
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
os: [ubuntu-20.04, ubuntu-18.04, windows-2019, windows-2016, macOS-10.15, macos-11]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/src/github.com/shirou/gopsutil
- name: Get dependencies
if: runner.os == 'Windows'
run: |
go get -d -u github.com/golang/dep
cd $Env:GOPATH/src/github.com/golang/dep
git checkout v0.5.4
go install -ldflags="-X main.version=v0.5.4" ./cmd/dep
echo "$Env:GOPATH/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
cd $Env:GOPATH/src/github.com/shirou/gopsutil
dep ensure
# exclude v3 from being run with ./...
try { rm -ErrorAction:Stop -Recurse -Force $Env:GOPATH/src/github.com/shirou/gopsutil/v3 } catch [System.Management.Automation.ItemNotFoundException] {}
- name: Get dependencies
if: runner.os != 'Windows'
run: |
if ! command -v dep &>/dev/null; then
mkdir -p $GOPATH/bin
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
echo "PATH=$GOPATH/bin:$PATH" >> $GITHUB_PATH
fi
cd $GOPATH/src/github.com/shirou/gopsutil
dep ensure
# exclude v3 from being run with ./...
rm -rf $GOPATH/src/github.com/shirou/gopsutil/v3
- name: Test
run: |
go test github.com/shirou/gopsutil/...

@ -2,7 +2,6 @@
.DEFAULT_GOAL := help
SUBPKGS=cpu disk docker host internal load mem net process
TAG=$(shell date +'v3.%y.%-m' --date='last Month')
help: ## Show help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@ -29,6 +28,7 @@ build_test: ## test only buildable
GOOS=netbsd go test ./... | $(BUILD_FAIL_PATTERN)
# cross build to OpenBSD not worked since process has "C"
# GOOS=openbsd go test ./... | $(BUILD_FAIL_PATTERN)
GOOS=plan9 go test ./... | $(BUILD_FAIL_PATTERN)
ifeq ($(shell uname -s), Darwin)
CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN)
@ -68,6 +68,9 @@ vet:
GOOS=windows GOARCH=amd64 go vet ./...
GOOS=windows GOARCH=386 go vet ./...
GOOS=plan9 GOARCH=amd64 go vet ./...
GOOS=plan9 GOARCH=386 go vet ./...
macos_test:
CGO_ENABLED=0 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN)
CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN)
@ -75,6 +78,8 @@ macos_test:
init_tools:
go get github.com/golang/dep/cmd/dep
TAG=$(shell date +'v3.%y.%-m' --date='last Month')
release:
git tag $(TAG)
git push origin $(TAG)

@ -10,7 +10,7 @@ import (
"sync"
"time"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
// TimesStat contains the amounts of time the CPU has spent performing different

@ -14,11 +14,11 @@ import (
// sys/resource.h
const (
CPUser = 0
CPNice = 1
CPSys = 2
CPIntr = 3
CPIdle = 4
CPUStates = 5
cpNice = 1
cpSys = 2
cpIntr = 3
cpIdle = 4
cpUStates = 5
)
// default value. from time.h

@ -3,7 +3,7 @@
package cpu
import "github.com/shirou/gopsutil/internal/common"
import "github.com/shirou/gopsutil/v3/internal/common"
func perCPUTimes() ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError

@ -10,7 +10,7 @@ import (
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/tklauser/go-sysconf"
"golang.org/x/sys/unix"
)

@ -1,4 +1,4 @@
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!dragonfly
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!dragonfly,!plan9
package cpu
@ -6,7 +6,7 @@ import (
"context"
"runtime"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func Times(percpu bool) ([]TimesStat, error) {

@ -10,7 +10,7 @@ import (
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/tklauser/go-sysconf"
"golang.org/x/sys/unix"
)

@ -5,7 +5,7 @@ import (
"runtime"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func TestParseDmesgBoot(t *testing.T) {

@ -10,7 +10,7 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/tklauser/go-sysconf"
)

@ -12,7 +12,7 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/tklauser/go-sysconf"
"golang.org/x/sys/unix"
)
@ -20,20 +20,20 @@ import (
// sys/sched.h
var (
CPUser = 0
CPNice = 1
CPSys = 2
CPIntr = 3
CPIdle = 4
CPUStates = 5
cpNice = 1
cpSys = 2
cpIntr = 3
cpIdle = 4
cpUStates = 5
)
// sys/sysctl.h
const (
CTLKern = 1 // "high kernel": proc, limits
CTLHw = 6 // CTL_HW
SMT = 24 // HW_SMT
KernCptime = 40 // KERN_CPTIME
KernCptime2 = 71 // KERN_CPTIME2
ctlKern = 1 // "high kernel": proc, limits
ctlHw = 6 // CTL_HW
sMT = 24 // HW_sMT
kernCptime = 40 // KERN_CPTIME
kernCptime2 = 71 // KERN_CPTIME2
)
var ClocksPerSec = float64(128)
@ -56,15 +56,15 @@ func init() {
return
}
if version >= 6.4 {
CPIntr = 4
CPIdle = 5
CPUStates = 6
cpIntr = 4
cpIdle = 5
cpUStates = 6
}
}()
}
func smt() (bool, error) {
mib := []int32{CTLHw, SMT}
mib := []int32{ctlHw, sMT}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return false, err
@ -108,12 +108,12 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
j *= 2
}
var cpuTimes = make([]int32, CPUStates)
var cpuTimes = make([]int32, cpUStates)
var mib []int32
if percpu {
mib = []int32{CTLKern, KernCptime2, int32(j)}
mib = []int32{ctlKern, kernCptime2, int32(j)}
} else {
mib = []int32{CTLKern, KernCptime}
mib = []int32{ctlKern, kernCptime}
}
buf, _, err := common.CallSyscall(mib)
if err != nil {
@ -127,10 +127,10 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
}
c := TimesStat{
User: float64(cpuTimes[CPUser]) / ClocksPerSec,
Nice: float64(cpuTimes[CPNice]) / ClocksPerSec,
System: float64(cpuTimes[CPSys]) / ClocksPerSec,
Idle: float64(cpuTimes[CPIdle]) / ClocksPerSec,
Irq: float64(cpuTimes[CPIntr]) / ClocksPerSec,
Nice: float64(cpuTimes[cpNice]) / ClocksPerSec,
System: float64(cpuTimes[cpSys]) / ClocksPerSec,
Idle: float64(cpuTimes[cpIdle]) / ClocksPerSec,
Irq: float64(cpuTimes[cpIntr]) / ClocksPerSec,
}
if percpu {
c.CPU = fmt.Sprintf("cpu%d", j)

@ -7,7 +7,7 @@ import (
"testing"
"time"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/stretchr/testify/assert"
)

@ -1,3 +1,4 @@
//go:build windows
// +build windows
package cpu
@ -5,11 +6,10 @@ package cpu
import (
"context"
"fmt"
"strings"
"unsafe"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/yusufpapurcu/wmi"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/windows"
)
@ -18,15 +18,7 @@ var (
procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
)
type Win32_Processor struct {
Win32_ProcessorWithoutLoadPct
LoadPercentage *uint16
}
// LoadPercentage takes a linearly more time as the number of sockets increases.
// For vSphere by default corespersocket = 1, meaning for a 40 vCPU VM Get Processor Info
// could take more than half a minute.
type Win32_ProcessorWithoutLoadPct struct {
type win32_Processor struct {
Family uint16
Manufacturer string
Name string
@ -51,12 +43,6 @@ type win32_SystemProcessorPerformanceInformation struct {
InterruptCount uint32
}
// Win32_PerfFormattedData_PerfOS_System struct to have count of processes and processor queue length
type Win32_PerfFormattedData_PerfOS_System struct {
Processes uint32
ProcessorQueueLength uint32
}
const (
ClocksPerSec = 10000000.0
@ -112,9 +98,8 @@ func Info() ([]InfoStat, error) {
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
var ret []InfoStat
var dst []Win32_ProcessorWithoutLoadPct
var dst []win32_Processor
q := wmi.CreateQuery(&dst, "")
q = strings.ReplaceAll(q, "Win32_ProcessorWithoutLoadPct", "Win32_Processor")
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
return ret, err
}
@ -142,22 +127,6 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
return ret, nil
}
// ProcInfo returns processes count and processor queue length in the system.
// There is a single queue for processor even on multiprocessors systems.
func ProcInfo() ([]Win32_PerfFormattedData_PerfOS_System, error) {
return ProcInfoWithContext(context.Background())
}
func ProcInfoWithContext(ctx context.Context) ([]Win32_PerfFormattedData_PerfOS_System, error) {
var ret []Win32_PerfFormattedData_PerfOS_System
q := wmi.CreateQuery(&ret, "")
err := common.WMIQueryWithContext(ctx, q, &ret)
if err != nil {
return []Win32_PerfFormattedData_PerfOS_System{}, err
}
return ret, err
}
// perCPUTimes returns times stat per cpu, per core and overall for all CPUs
func perCPUTimes() ([]TimesStat, error) {
var ret []TimesStat
@ -251,9 +220,8 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) {
}
// physical cores https://github.com/giampaolo/psutil/blob/d01a9eaa35a8aadf6c519839e987a49d8be2d891/psutil/_psutil_windows.c#L499
// for the time being, try with unreliable and slow WMI call…
var dst []Win32_ProcessorWithoutLoadPct
var dst []win32_Processor
q := wmi.CreateQuery(&dst, "")
q = strings.ReplaceAll(q, "Win32_ProcessorWithoutLoadPct", "Win32_Processor")
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
return 0, err
}

@ -4,7 +4,7 @@ import (
"context"
"encoding/json"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var invoke common.Invoker = common.Invoke{}
@ -26,7 +26,7 @@ type PartitionStat struct {
Device string `json:"device"`
Mountpoint string `json:"mountpoint"`
Fstype string `json:"fstype"`
Opts string `json:"opts"`
Opts []string `json:"opts"`
}
type IOCountersStat struct {
@ -80,3 +80,17 @@ func Partitions(all bool) ([]PartitionStat, error) {
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
// SerialNumber returns Serial Number of given device or empty string
// on error. Name of device is expected, eg. /dev/sda
func SerialNumber(name string) (string, error) {
return SerialNumberWithContext(context.Background(), name)
}
// Label returns label of given device or empty string on error.
// Name of device is expected, eg. /dev/sda
// Supports label based on devicemapper name
// See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm
func Label(name string) (string, error) {
return LabelWithContext(context.Background(), name)
}

@ -5,7 +5,7 @@ package disk
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)
@ -23,42 +23,42 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
return ret, err
}
for _, stat := range fs {
opts := "rw"
opts := []string{"rw"}
if stat.Flags&unix.MNT_RDONLY != 0 {
opts = "ro"
opts = []string{"ro"}
}
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
opts += ",sync"
opts = append(opts, "sync")
}
if stat.Flags&unix.MNT_NOEXEC != 0 {
opts += ",noexec"
opts = append(opts, "noexec")
}
if stat.Flags&unix.MNT_NOSUID != 0 {
opts += ",nosuid"
opts = append(opts, "nosuid")
}
if stat.Flags&unix.MNT_UNION != 0 {
opts += ",union"
opts = append(opts, "union")
}
if stat.Flags&unix.MNT_ASYNC != 0 {
opts += ",async"
opts = append(opts, "async")
}
if stat.Flags&unix.MNT_DONTBROWSE != 0 {
opts += ",nobrowse"
opts = append(opts, "nobrowse")
}
if stat.Flags&unix.MNT_AUTOMOUNTED != 0 {
opts += ",automounted"
opts = append(opts, "automounted")
}
if stat.Flags&unix.MNT_JOURNALED != 0 {
opts += ",journaled"
opts = append(opts, "journaled")
}
if stat.Flags&unix.MNT_MULTILABEL != 0 {
opts += ",multilabel"
opts = append(opts, "multilabel")
}
if stat.Flags&unix.MNT_NOATIME != 0 {
opts += ",noatime"
opts = append(opts, "noatime")
}
if stat.Flags&unix.MNT_NODEV != 0 {
opts += ",nodev"
opts = append(opts, "nodev")
}
d := PartitionStat{
Device: common.ByteToString(stat.Mntfromname[:]),
@ -76,3 +76,11 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
func getFsType(stat unix.Statfs_t) string {
return common.ByteToString(stat.Fstypename[:])
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}

@ -14,12 +14,12 @@ import "C"
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
var buf [C.NDRIVE]C.DriveStats
n, err := C.readdrivestat(&buf[0], C.int(len(buf)))
n, err := C.v3readdrivestat(&buf[0], C.int(len(buf)))
if err != nil {
return nil, err
}

@ -6,7 +6,7 @@ package disk
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {

@ -5,7 +5,7 @@ package disk
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
@ -19,3 +19,11 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
return nil, common.ErrNotImplementedError
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}

@ -10,7 +10,7 @@ import (
"golang.org/x/sys/unix"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
// PartitionsWithContext returns disk partition.
@ -30,54 +30,54 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
}
for _, stat := range fs {
opts := "rw"
opts := []string{"rw"}
if stat.Flags&unix.MNT_RDONLY != 0 {
opts = "ro"
opts = []string{"ro"}
}
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
opts += ",sync"
opts = append(opts, "sync")
}
if stat.Flags&unix.MNT_NOEXEC != 0 {
opts += ",noexec"
opts = append(opts, "noexec")
}
if stat.Flags&unix.MNT_NOSUID != 0 {
opts += ",nosuid"
opts = append(opts, "nosuid")
}
if stat.Flags&unix.MNT_UNION != 0 {
opts += ",union"
opts = append(opts, "union")
}
if stat.Flags&unix.MNT_ASYNC != 0 {
opts += ",async"
opts = append(opts, "async")
}
if stat.Flags&unix.MNT_SUIDDIR != 0 {
opts += ",suiddir"
opts = append(opts, "suiddir")
}
if stat.Flags&unix.MNT_SOFTDEP != 0 {
opts += ",softdep"
opts = append(opts, "softdep")
}
if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 {
opts += ",nosymfollow"
opts = append(opts, "nosymfollow")
}
if stat.Flags&unix.MNT_GJOURNAL != 0 {
opts += ",gjournal"
opts = append(opts, "gjournal")
}
if stat.Flags&unix.MNT_MULTILABEL != 0 {
opts += ",multilabel"
opts = append(opts, "multilabel")
}
if stat.Flags&unix.MNT_ACLS != 0 {
opts += ",acls"
opts = append(opts, "acls")
}
if stat.Flags&unix.MNT_NOATIME != 0 {
opts += ",noatime"
opts = append(opts, "noatime")
}
if stat.Flags&unix.MNT_NOCLUSTERR != 0 {
opts += ",noclusterr"
opts = append(opts, "noclusterr")
}
if stat.Flags&unix.MNT_NOCLUSTERW != 0 {
opts += ",noclusterw"
opts = append(opts, "noclusterw")
}
if stat.Flags&unix.MNT_NFS4ACLS != 0 {
opts += ",nfsv4acls"
opts = append(opts, "nfsv4acls")
}
d := PartitionStat{
@ -105,13 +105,13 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
buf := []byte(r)
length := len(buf)
count := int(uint64(length) / uint64(sizeOfDevstat))
count := int(uint64(length) / uint64(sizeOfdevstat))
buf = buf[8:] // devstat.all has version in the head.
// parse buf to Devstat
// parse buf to devstat
for i := 0; i < count; i++ {
b := buf[i*sizeOfDevstat : i*sizeOfDevstat+sizeOfDevstat]
d, err := parseDevstat(b)
b := buf[i*sizeOfdevstat : i*sizeOfdevstat+sizeOfdevstat]
d, err := parsedevstat(b)
if err != nil {
continue
}
@ -123,12 +123,12 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
}
ds := IOCountersStat{
ReadCount: d.Operations[DEVSTAT_READ],
WriteCount: d.Operations[DEVSTAT_WRITE],
ReadBytes: d.Bytes[DEVSTAT_READ],
WriteBytes: d.Bytes[DEVSTAT_WRITE],
ReadTime: uint64(d.Duration[DEVSTAT_READ].Compute() * 1000),
WriteTime: uint64(d.Duration[DEVSTAT_WRITE].Compute() * 1000),
ReadCount: d.Operations[devstat_READ],
WriteCount: d.Operations[devstat_WRITE],
ReadBytes: d.Bytes[devstat_READ],
WriteBytes: d.Bytes[devstat_WRITE],
ReadTime: uint64(d.Duration[devstat_READ].Compute() * 1000),
WriteTime: uint64(d.Duration[devstat_WRITE].Compute() * 1000),
IoTime: uint64(d.Busy_time.Compute() * 1000),
Name: name,
}
@ -138,15 +138,15 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
return ret, nil
}
func (b Bintime) Compute() float64 {
func (b bintime) Compute() float64 {
BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20
return float64(b.Sec) + float64(b.Frac)*BINTIME_SCALE
}
// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE)
func parseDevstat(buf []byte) (Devstat, error) {
var ds Devstat
func parsedevstat(buf []byte) (devstat, error) {
var ds devstat
br := bytes.NewReader(buf)
// err := binary.Read(br, binary.LittleEndian, &ds)
err := common.Read(br, binary.LittleEndian, &ds)
@ -160,3 +160,11 @@ func parseDevstat(buf []byte) (Devstat, error) {
func getFsType(stat unix.Statfs_t) string {
return common.ByteToString(stat.Fstypename[:])
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}

@ -11,14 +11,14 @@ const (
sizeofLongLong = 0x8
sizeofLongDouble = 0x8
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
sizeOfDevstat = 0xf0
sizeOfdevstat = 0xf0
)
type (
@ -29,21 +29,21 @@ type (
_C_long_double int64
)
type Devstat struct {
type devstat struct {
Sequence0 uint32
Allocated int32
Start_count uint32
End_count uint32
Busy_from Bintime
Busy_from bintime
Dev_links _Ctype_struct___0
Device_number uint32
Device_name [16]int8
Unit_number int32
Bytes [4]uint64
Operations [4]uint64
Duration [4]Bintime
Busy_time Bintime
Creation_time Bintime
Duration [4]bintime
Busy_time bintime
Creation_time bintime
Block_size uint32
Tag_types [3]uint64
Flags uint32
@ -52,7 +52,7 @@ type Devstat struct {
Id *byte
Sequence1 uint32
}
type Bintime struct {
type bintime struct {
Sec int32
Frac uint64
}

@ -11,14 +11,14 @@ const (
sizeofLongLong = 0x8
sizeofLongDouble = 0x8
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
sizeOfDevstat = 0x120
sizeOfdevstat = 0x120
)
type (
@ -29,21 +29,21 @@ type (
_C_long_double int64
)
type Devstat struct {
type devstat struct {
Sequence0 uint32
Allocated int32
Start_count uint32
End_count uint32
Busy_from Bintime
Busy_from bintime
Dev_links _Ctype_struct___0
Device_number uint32
Device_name [16]int8
Unit_number int32
Bytes [4]uint64
Operations [4]uint64
Duration [4]Bintime
Busy_time Bintime
Creation_time Bintime
Duration [4]bintime
Busy_time bintime
Creation_time bintime
Block_size uint32
Pad_cgo_0 [4]byte
Tag_types [3]uint64
@ -55,7 +55,7 @@ type Devstat struct {
Sequence1 uint32
Pad_cgo_2 [4]byte
}
type Bintime struct {
type bintime struct {
Sec int64
Frac uint64
}

@ -11,14 +11,14 @@ const (
sizeofLongLong = 0x8
sizeofLongDouble = 0x8
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
sizeOfDevstat = 0xf0
sizeOfdevstat = 0xf0
)
type (
@ -29,21 +29,21 @@ type (
_C_long_double int64
)
type Devstat struct {
type devstat struct {
Sequence0 uint32
Allocated int32
Start_count uint32
End_count uint32
Busy_from Bintime
Busy_from bintime
Dev_links _Ctype_struct___0
Device_number uint32
Device_name [16]int8
Unit_number int32
Bytes [4]uint64
Operations [4]uint64
Duration [4]Bintime
Busy_time Bintime
Creation_time Bintime
Duration [4]bintime
Busy_time bintime
Creation_time bintime
Block_size uint32
Tag_types [3]uint64
Flags uint32
@ -52,7 +52,7 @@ type Devstat struct {
Id *byte
Sequence1 uint32
}
type Bintime struct {
type bintime struct {
Sec int32
Frac uint64
}

@ -13,14 +13,14 @@ const (
sizeofLongLong = 0x8
sizeofLongDouble = 0x8
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
sizeOfDevstat = 0x120
sizeOfdevstat = 0x120
)
type (
@ -31,21 +31,21 @@ type (
_C_long_double int64
)
type Devstat struct {
type devstat struct {
Sequence0 uint32
Allocated int32
Start_count uint32
End_count uint32
Busy_from Bintime
Busy_from bintime
Dev_links _Ctype_struct___0
Device_number uint32
Device_name [16]int8
Unit_number int32
Bytes [4]uint64
Operations [4]uint64
Duration [4]Bintime
Busy_time Bintime
Creation_time Bintime
Duration [4]bintime
Busy_time bintime
Creation_time bintime
Block_size uint32
Tag_types [3]uint64
Flags uint32
@ -55,7 +55,7 @@ type Devstat struct {
Sequence1 uint32
Pad_cgo_0 [4]byte
}
type Bintime struct {
type bintime struct {
Sec int64
Frac uint64
}

@ -13,12 +13,12 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)
const (
SectorSize = 512
sectorSize = 512
)
const (
// man statfs
@ -252,7 +252,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
Device: fields[0],
Mountpoint: unescapeFstab(fields[1]),
Fstype: fields[2],
Opts: fields[3],
Opts: strings.Fields(fields[3]),
}
if !all {
@ -274,14 +274,10 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
fields := strings.Fields(parts[0])
blockDeviceID := fields[2]
mountPoint := fields[4]
mountOpts := fields[5]
mountOpts := strings.Split(fields[5], ",")
if rootDir := fields[3]; rootDir != "" && rootDir != "/" {
if len(mountOpts) == 0 {
mountOpts = "bind"
} else {
mountOpts = "bind," + mountOpts
}
mountOpts = append(mountOpts, "bind")
}
fields = strings.Fields(parts[1])
@ -418,8 +414,8 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
return ret, err
}
d := IOCountersStat{
ReadBytes: rbytes * SectorSize,
WriteBytes: wbytes * SectorSize,
ReadBytes: rbytes * sectorSize,
WriteBytes: wbytes * sectorSize,
ReadCount: reads,
WriteCount: writes,
MergedReadCount: mergedReads,
@ -435,25 +431,19 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
}
d.Name = name
d.SerialNumber = GetDiskSerialNumber(name)
d.Label = GetLabel(name)
d.SerialNumber, _ = SerialNumberWithContext(ctx, name)
d.Label, _ = LabelWithContext(ctx, name)
ret[name] = d
}
return ret, nil
}
// GetDiskSerialNumber returns Serial Number of given device or empty string
// on error. Name of device is expected, eg. /dev/sda
func GetDiskSerialNumber(name string) string {
return GetDiskSerialNumberWithContext(context.Background(), name)
}
func GetDiskSerialNumberWithContext(ctx context.Context, name string) string {
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
var stat unix.Stat_t
err := unix.Stat(name, &stat)
if err != nil {
return ""
return "", err
}
major := unix.Major(uint64(stat.Rdev))
minor := unix.Minor(uint64(stat.Rdev))
@ -465,7 +455,7 @@ func GetDiskSerialNumberWithContext(ctx context.Context, name string) string {
for scanner.Scan() {
values := strings.Split(scanner.Text(), "=")
if len(values) == 2 && values[0] == "E:ID_SERIAL" {
return values[1]
return values[1], nil
}
}
}
@ -476,28 +466,24 @@ func GetDiskSerialNumberWithContext(ctx context.Context, name string) string {
model, _ := ioutil.ReadFile(filepath.Join(devicePath, "model"))
serial, _ := ioutil.ReadFile(filepath.Join(devicePath, "serial"))
if len(model) > 0 && len(serial) > 0 {
return fmt.Sprintf("%s_%s", string(model), string(serial))
return fmt.Sprintf("%s_%s", string(model), string(serial)), nil
}
return ""
return "", nil
}
// GetLabel returns label of given device or empty string on error.
// Name of device is expected, eg. /dev/sda
// Supports label based on devicemapper name
// See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm
func GetLabel(name string) string {
func LabelWithContext(ctx context.Context, name string) (string, error) {
// Try label based on devicemapper name
dmname_filename := common.HostSys(fmt.Sprintf("block/%s/dm/name", name))
if !common.PathExists(dmname_filename) {
return ""
return "", nil
}
dmname, err := ioutil.ReadFile(dmname_filename)
if err != nil {
return ""
return "", err
} else {
return strings.TrimSpace(string(dmname))
return strings.TrimSpace(string(dmname)), nil
}
}

@ -7,7 +7,7 @@ import (
"context"
"encoding/binary"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)
@ -26,33 +26,33 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
}
for _, stat := range fs {
opts := "rw"
opts := []string{"rw"}
if stat.F_flags&unix.MNT_RDONLY != 0 {
opts = "ro"
opts = []string{"rw"}
}
if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 {
opts += ",sync"
opts = append(opts, "sync")
}
if stat.F_flags&unix.MNT_NOEXEC != 0 {
opts += ",noexec"
opts = append(opts, "noexec")
}
if stat.F_flags&unix.MNT_NOSUID != 0 {
opts += ",nosuid"
opts = append(opts, "nosuid")
}
if stat.F_flags&unix.MNT_NODEV != 0 {
opts += ",nodev"
opts = append(opts, "nodev")
}
if stat.F_flags&unix.MNT_ASYNC != 0 {
opts += ",async"
opts = append(opts, "async")
}
if stat.F_flags&unix.MNT_SOFTDEP != 0 {
opts += ",softdep"
opts = append(opts, "softdep")
}
if stat.F_flags&unix.MNT_NOATIME != 0 {
opts += ",noatime"
opts = append(opts, "noatime")
}
if stat.F_flags&unix.MNT_WXALLOWED != 0 {
opts += ",wxallowed"
opts = append(opts, "wxallowed")
}
d := PartitionStat{
@ -148,3 +148,11 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
func getFsType(stat unix.Statfs_t) string {
return common.IntToString(stat.F_fstypename[:])
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}

@ -6,10 +6,10 @@
package disk
const (
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
@ -34,4 +34,4 @@ type Timeval struct {
}
type Diskstat struct{}
type Bintime struct{}
type bintime struct{}

@ -4,10 +4,10 @@
package disk
const (
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
@ -33,4 +33,4 @@ type Timeval struct {
}
type Diskstat struct{}
type Bintime struct{}
type bintime struct{}

@ -6,10 +6,10 @@
package disk
const (
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
@ -34,4 +34,4 @@ type Timeval struct {
}
type Diskstat struct{}
type Bintime struct{}
type bintime struct{}

@ -10,7 +10,7 @@ import (
"os"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)
@ -69,7 +69,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
Device: fields[0],
Mountpoint: fields[1],
Fstype: fields[2],
Opts: fields[3],
Opts: strings.Split(fields[3], ","),
})
}
if err := scanner.Err(); err != nil {
@ -113,3 +113,10 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
return usageStat, nil
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}

@ -6,7 +6,7 @@ import (
"sync"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func skipIfNotImplementedErr(t *testing.T, err error) {
@ -38,12 +38,11 @@ func TestDisk_partitions(t *testing.T) {
}
t.Log(ret)
empty := PartitionStat{}
if len(ret) == 0 {
t.Errorf("ret is empty")
}
for _, disk := range ret {
if disk == empty {
if disk.Device == "" {
t.Errorf("Could not get device info %v", disk)
}
}
@ -108,9 +107,9 @@ func TestDiskPartitionStat_String(t *testing.T) {
Device: "sd01",
Mountpoint: "/",
Fstype: "ext4",
Opts: "ro",
Opts: []string{"ro"},
}
e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":"ro"}`
e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":["ro"]}`
if e != fmt.Sprintf("%v", v) {
t.Errorf("DiskUsageStat string is invalid: %v", v)
}

@ -9,7 +9,7 @@ import (
"syscall"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/windows"
)
@ -21,8 +21,8 @@ var (
)
var (
FileFileCompression = int64(16) // 0x00000010
FileReadOnlyVolume = int64(524288) // 0x00080000
fileFileCompression = int64(16) // 0x00000010
fileReadOnlyVolume = int64(524288) // 0x00080000
)
// diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API.
@ -110,12 +110,12 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
}
return ret, err
}
opts := "rw"
if lpFileSystemFlags&FileReadOnlyVolume != 0 {
opts = "ro"
opts := []string{"rw"}
if lpFileSystemFlags&fileReadOnlyVolume != 0 {
opts = []string{"ro"}
}
if lpFileSystemFlags&FileFileCompression != 0 {
opts += ".compress"
if lpFileSystemFlags&fileFileCompression != 0 {
opts = append(opts, "compress")
}
d := PartitionStat{
@ -181,3 +181,11 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
}
return drivemap, nil
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}

@ -16,7 +16,7 @@ static int getdrivestat(io_registry_entry_t d, DriveStats *stat);
static int fillstat(io_registry_entry_t d, DriveStats *stat);
int
readdrivestat(DriveStats a[], int n)
v3readdrivestat(DriveStats a[], int n)
{
mach_port_t port;
CFMutableDictionaryRef match;

@ -29,5 +29,4 @@ struct CPUStats {
natural_t idle;
};
extern int readdrivestat(DriveStats a[], int n);
extern int readcpustat(CPUStats *cpu);
extern int v3readdrivestat(DriveStats a[], int n);

@ -38,14 +38,14 @@ const (
sizeofLongLong = C.sizeof_longlong
sizeofLongDouble = C.sizeof_longlong
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
sizeOfDevstat = C.sizeof_struct_devstat
sizeOfdevstat = C.sizeof_struct_devstat
)
// Basic types
@ -58,5 +58,5 @@ type (
_C_long_double C.longlong
)
type Devstat C.struct_devstat
type Bintime C.struct_bintime
type devstat C.struct_devstat
type bintime C.struct_bintime

@ -15,10 +15,10 @@ package disk
import "C"
const (
DEVSTAT_NO_DATA = 0x00
DEVSTAT_READ = 0x01
DEVSTAT_WRITE = 0x02
DEVSTAT_FREE = 0x03
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
@ -29,4 +29,4 @@ type Diskstats C.struct_diskstats
type Timeval C.struct_timeval
type Diskstat C.struct_diskstat
type Bintime C.struct_bintime
type bintime C.struct_bintime

@ -4,8 +4,8 @@ import (
"encoding/json"
"errors"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
)
var ErrDockerNotAvailable = errors.New("docker not available")
@ -51,7 +51,7 @@ type CgroupMemStat struct {
TotalUnevictable uint64 `json:"totalUnevictable"`
MemUsageInBytes uint64 `json:"memUsageInBytes"`
MemMaxUsageInBytes uint64 `json:"memMaxUsageInBytes"`
MemLimitInBytes uint64 `json:"memoryLimitInBbytes"`
MemLimitInBytes uint64 `json:"memoryLimitInBytes"`
MemFailCnt uint64 `json:"memoryFailcnt"`
}

@ -11,8 +11,8 @@ import (
"strconv"
"strings"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
cpu "github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
)
// GetDockerStat returns a list of Docker basic stats.
@ -89,7 +89,7 @@ func GetDockerIDListWithContext(ctx context.Context) ([]string, error) {
// containerID is same as docker id if you use docker.
// If you use container via systemd.slice, you could use
// containerID = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPU(containerID string, base string) (*cpu.TimesStat, error) {
func CgroupCPU(containerID string, base string) (*CgroupCPUStat, error) {
return CgroupCPUWithContext(context.Background(), containerID, base)
}
@ -101,7 +101,7 @@ func CgroupCPUUsage(containerID string, base string) (float64, error) {
return CgroupCPUUsageWithContext(context.Background(), containerID, base)
}
func CgroupCPUWithContext(ctx context.Context, containerID string, base string) (*cpu.TimesStat, error) {
func CgroupCPUWithContext(ctx context.Context, containerID string, base string) (*CgroupCPUStat, error) {
statfile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.stat")
lines, err := common.ReadLines(statfile)
if err != nil {
@ -111,7 +111,9 @@ func CgroupCPUWithContext(ctx context.Context, containerID string, base string)
if len(containerID) == 0 {
containerID = "all"
}
ret := &cpu.TimesStat{CPU: containerID}
ret := &CgroupCPUStat{}
ret.CPU = containerID
for _, line := range lines {
fields := strings.Split(line, " ")
if fields[0] == "user" {
@ -127,6 +129,11 @@ func CgroupCPUWithContext(ctx context.Context, containerID string, base string)
}
}
}
usage, err := CgroupCPUUsageWithContext(ctx, containerID, base)
if err != nil {
return nil, err
}
ret.Usage = usage
return ret, nil
}
@ -145,7 +152,7 @@ func CgroupCPUUsageWithContext(ctx context.Context, containerID, base string) (f
return ns / nanoseconds, nil
}
func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
func CgroupCPUDocker(containerid string) (*CgroupCPUStat, error) {
return CgroupCPUDockerWithContext(context.Background(), containerid)
}
@ -153,7 +160,7 @@ func CgroupCPUUsageDocker(containerid string) (float64, error) {
return CgroupCPUDockerUsageWithContext(context.Background(), containerid)
}
func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*cpu.TimesStat, error) {
func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*CgroupCPUStat, error) {
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
}
@ -249,11 +256,11 @@ func CgroupMemWithContext(ctx context.Context, containerID string, base string)
if err == nil {
ret.MemMaxUsageInBytes = r
}
r, err = getCgroupMemFile(containerID, base, "memoryLimitInBbytes")
r, err = getCgroupMemFile(containerID, base, "memory.limit_in_bytes")
if err == nil {
ret.MemLimitInBytes = r
}
r, err = getCgroupMemFile(containerID, base, "memoryFailcnt")
r, err = getCgroupMemFile(containerID, base, "memory.failcnt")
if err == nil {
ret.MemFailCnt = r
}

@ -5,8 +5,7 @@ package docker
import (
"context"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
// GetDockerStat returns a list of Docker basic stats.
@ -33,19 +32,19 @@ func GetDockerIDListWithContext(ctx context.Context) ([]string, error) {
// containerid is same as docker id if you use docker.
// If you use container via systemd.slice, you could use
// containerid = docker-<container id>.scope and base=/sys/fs/cgroup/cpuacct/system.slice/
func CgroupCPU(containerid string, base string) (*cpu.TimesStat, error) {
func CgroupCPU(containerid string, base string) (*CgroupCPUStat, error) {
return CgroupCPUWithContext(context.Background(), containerid, base)
}
func CgroupCPUWithContext(ctx context.Context, containerid string, base string) (*cpu.TimesStat, error) {
func CgroupCPUWithContext(ctx context.Context, containerid string, base string) (*CgroupCPUStat, error) {
return nil, ErrCgroupNotAvailable
}
func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) {
func CgroupCPUDocker(containerid string) (*CgroupCPUStat, error) {
return CgroupCPUDockerWithContext(context.Background(), containerid)
}
func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*cpu.TimesStat, error) {
func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*CgroupCPUStat, error) {
return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker"))
}

@ -7,7 +7,7 @@ import (
"runtime"
"time"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var invoke common.Invoker = common.Invoke{}
@ -27,7 +27,7 @@ type InfoStat struct {
KernelArch string `json:"kernelArch"` // native cpu architecture queried at runtime, as returned by `uname -m` or empty string in case of error
VirtualizationSystem string `json:"virtualizationSystem"`
VirtualizationRole string `json:"virtualizationRole"` // guest or host
HostID string `json:"hostid"` // ex: uuid
HostID string `json:"hostId"` // ex: uuid
}
type UserStat struct {
@ -39,7 +39,9 @@ type UserStat struct {
type TemperatureStat struct {
SensorKey string `json:"sensorKey"`
Temperature float64 `json:"sensorTemperature"`
Temperature float64 `json:"temperature"`
High float64 `json:"sensorHigh"`
Critical float64 `json:"sensorCritical"`
}
func (h InfoStat) String() string {

@ -13,13 +13,13 @@ import (
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/process"
"golang.org/x/sys/unix"
)
// from utmpx.h
const USER_PROCESS = 7
const user_PROCESS = 7
func HostIDWithContext(ctx context.Context) (string, error) {
ioreg, err := exec.LookPath("ioreg")
@ -81,7 +81,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
if err != nil {
continue
}
if u.Type != USER_PROCESS {
if u.Type != user_PROCESS {
continue
}
user := UserStat{

@ -6,7 +6,7 @@ package host
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {

@ -5,7 +5,7 @@ package host
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func HostIDWithContext(ctx context.Context) (string, error) {

@ -12,8 +12,8 @@ import (
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/process"
"golang.org/x/sys/unix"
)

@ -15,11 +15,11 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)
type LSB struct {
type lsbStruct struct {
ID string
Release string
Codename string
@ -27,7 +27,11 @@ type LSB struct {
}
// from utmp.h
const USER_PROCESS = 7
const (
user_PROCESS = 7
hostTemperatureScale = 1000.0
)
func HostIDWithContext(ctx context.Context) (string, error) {
sysProductUUID := common.HostSys("class/dmi/id/product_uuid")
@ -104,7 +108,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
if err != nil {
continue
}
if u.Type != USER_PROCESS {
if u.Type != user_PROCESS {
continue
}
user := UserStat{
@ -120,8 +124,8 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
}
func getLSB() (*LSB, error) {
ret := &LSB{}
func getlsbStruct() (*lsbStruct, error) {
ret := &lsbStruct{}
if common.PathExists(common.HostEtc("lsb-release")) {
contents, err := common.ReadLines(common.HostEtc("lsb-release"))
if err != nil {
@ -175,9 +179,9 @@ func getLSB() (*LSB, error) {
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
lsb, err := getLSB()
lsb, err := getlsbStruct()
if err != nil {
lsb = &LSB{}
lsb = &lsbStruct{}
}
if common.PathExists(common.HostEtc("oracle-release")) {
@ -366,19 +370,27 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
var temperatures []TemperatureStat
files, err := filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_*"))
if err != nil {
var err error
var files []string
temperatures := make([]TemperatureStat, 0)
// Only the temp*_input file provides current temperature
// value in millidegree Celsius as reported by the temperature to the device:
// https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_input")); err != nil {
return temperatures, err
}
if len(files) == 0 {
// CentOS has an intermediate /device directory:
// https://github.com/giampaolo/psutil/issues/971
files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_*"))
if err != nil {
if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_input")); err != nil {
return temperatures, err
}
}
var warns Warnings
if len(files) == 0 { // handle distributions without hwmon, like raspbian #391, parse legacy thermal_zone files
@ -413,6 +425,8 @@ func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, err
return temperatures, warns.Reference()
}
temperatures = make([]TemperatureStat, 0, len(files))
// example directory
// device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm
// name temp1_input temp2_input temp3_input temp4_input temp5_input temp6_input temp7_input
@ -420,44 +434,81 @@ func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, err
// subsystem/ temp1_max temp2_max temp3_max temp4_max temp5_max temp6_max temp7_max
// temp1_crit temp2_crit temp3_crit temp4_crit temp5_crit temp6_crit temp7_crit uevent
for _, file := range files {
filename := strings.Split(filepath.Base(file), "_")
if filename[1] == "label" {
// Do not try to read the temperature of the label file
continue
}
var raw []byte
var temperature float64
// Get the base directory location
directory := filepath.Dir(file)
// Get the base filename prefix like temp1
basename := strings.Split(filepath.Base(file), "_")[0]
// Get the base path like <dir>/temp1
basepath := filepath.Join(directory, basename)
// Get the label of the temperature you are reading
var label string
c, _ := ioutil.ReadFile(filepath.Join(filepath.Dir(file), filename[0]+"_label"))
if c != nil {
//format the label from "Core 0" to "core0_"
label = fmt.Sprintf("%s_", strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(c))), " "), ""))
label := ""
if raw, _ = ioutil.ReadFile(basepath + "_label"); len(raw) != 0 {
// Format the label from "Core 0" to "core_0"
label = strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(raw))), " "), "_")
}
// Get the name of the temperature you are reading
name, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "name"))
if err != nil {
if raw, err = ioutil.ReadFile(filepath.Join(directory, "name")); err != nil {
warns.Add(err)
continue
}
name := strings.TrimSpace(string(raw))
if label != "" {
name = name + "_" + label
}
// Get the temperature reading
current, err := ioutil.ReadFile(file)
if err != nil {
if raw, err = ioutil.ReadFile(file); err != nil {
warns.Add(err)
continue
}
temperature, err := strconv.ParseFloat(strings.TrimSpace(string(current)), 64)
if err != nil {
if temperature, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil {
warns.Add(err)
continue
}
tempName := strings.TrimSpace(strings.ToLower(string(strings.Join(filename[1:], ""))))
// Add discovered temperature sensor to the list
temperatures = append(temperatures, TemperatureStat{
SensorKey: fmt.Sprintf("%s_%s%s", strings.TrimSpace(string(name)), label, tempName),
Temperature: temperature / 1000.0,
SensorKey: name,
Temperature: temperature / hostTemperatureScale,
High: optionalValueReadFromFile(basepath+"_max") / hostTemperatureScale,
Critical: optionalValueReadFromFile(basepath+"_crit") / hostTemperatureScale,
})
}
return temperatures, warns.Reference()
}
func optionalValueReadFromFile(filename string) float64 {
var raw []byte
var err error
var value float64
// Check if file exists
if _, err := os.Stat(filename); os.IsNotExist(err) {
return 0
}
if raw, err = ioutil.ReadFile(filename); err != nil {
return 0
}
if value, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil {
return 0
}
return value
}

@ -11,8 +11,8 @@ import (
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/process"
"golang.org/x/sys/unix"
)

@ -12,7 +12,7 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func HostIDWithContext(ctx context.Context) (string, error) {

@ -6,7 +6,7 @@ import (
"sync"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func skipIfNotImplementedErr(t *testing.T, err error) {
@ -101,7 +101,7 @@ func TestHostInfoStat_String(t *testing.T) {
HostID: "edfd25ff-3c9c-b1a4-e660-bd826495ad35",
KernelArch: "x86_64",
}
e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","kernelVersion":"","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostid":"edfd25ff-3c9c-b1a4-e660-bd826495ad35"}`
e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","kernelVersion":"","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostId":"edfd25ff-3c9c-b1a4-e660-bd826495ad35"}`
if e != fmt.Sprintf("%v", v) {
t.Errorf("HostInfoStat string is invalid:\ngot %v\nwant %v", v, e)
}
@ -137,10 +137,12 @@ func TestTemperatureStat_String(t *testing.T) {
v := TemperatureStat{
SensorKey: "CPU",
Temperature: 1.1,
High: 30.1,
Critical: 0.1,
}
s := `{"sensorKey":"CPU","sensorTemperature":1.1}`
s := `{"sensorKey":"CPU","temperature":1.1,"sensorHigh":30.1,"sensorCritical":0.1}`
if s != fmt.Sprintf("%v", v) {
t.Errorf("TemperatureStat string is invalid")
t.Errorf("TemperatureStat string is invalid, %v", fmt.Sprintf("%v", v))
}
}

@ -1,3 +1,4 @@
//go:build windows
// +build windows
package host
@ -13,8 +14,8 @@ import (
"time"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/process"
"github.com/yusufpapurcu/wmi"
"golang.org/x/sys/windows"
)

@ -253,7 +253,7 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error {
b[0] = *v
case uint8:
bs = b[:1]
b[0] = v
b[0] = byte(v)
case []uint8:
bs = v
case *int16:

@ -94,7 +94,7 @@ func (i FakeInvoke) CommandWithContext(ctx context.Context, name string, arg ...
var ErrNotImplementedError = errors.New("not implemented yet")
// ReadFile reads contents from a file.
// ReadFile reads contents from a file
func ReadFile(filename string) (string, error) {
content, err := ioutil.ReadFile(filename)
@ -111,7 +111,7 @@ func ReadLines(filename string) ([]string, error) {
return ReadLinesOffsetN(filename, 0, -1)
}
// ReadLinesOffsetN reads contents from file and splits them by new line.
// 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
@ -165,7 +165,7 @@ func UintToString(orig []uint8) string {
size = i
break
}
ret[i] = o
ret[i] = byte(o)
}
if size == -1 {
size = len(orig)
@ -224,31 +224,31 @@ func ReadInts(filename string) ([]int64, error) {
return ret, nil
}
// HexToUint32 parses Hex to uint32 without error.
// Parse Hex to uint32 without error
func HexToUint32(hex string) uint32 {
vv, _ := strconv.ParseUint(hex, 16, 32)
return uint32(vv)
}
// mustParseInt32 parses to int32 without error.
// Parse to int32 without error
func mustParseInt32(val string) int32 {
vv, _ := strconv.ParseInt(val, 10, 32)
return int32(vv)
}
// mustParseUint64 parses to uint64 without error.
// Parse to uint64 without error
func mustParseUint64(val string) uint64 {
vv, _ := strconv.ParseInt(val, 10, 64)
return uint64(vv)
}
// mustParseFloat64 parses to Float64 without error.
// Parse to Float64 without error
func mustParseFloat64(val string) float64 {
vv, _ := strconv.ParseFloat(val, 64)
return vv
}
// StringsHas checks the target string slice contains src or not.
// StringsHas checks the target string slice contains src or not
func StringsHas(target []string, src string) bool {
for _, t := range target {
if strings.TrimSpace(t) == src {
@ -258,7 +258,7 @@ func StringsHas(target []string, src string) bool {
return false
}
// StringsContains checks the src in any string of the target string slice.
// 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) {

@ -26,8 +26,8 @@ func DoSysctrl(mib string) ([]string, error) {
return []string{}, err
}
v := strings.Replace(string(out), "{ ", "", 1)
v = strings.Replace(v, " }", "", 1)
values := strings.Fields(v)
v = strings.Replace(string(v), " }", "", 1)
values := strings.Fields(string(v))
return values, nil
}
@ -55,6 +55,7 @@ func NumProcs() (uint64, error) {
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
system, role, err := Virtualization()
if err != nil {
return 0, err
@ -75,18 +76,6 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return 0, err
}
if statFile == "uptime" {
if len(lines) != 1 {
return 0, fmt.Errorf("wrong uptime format")
}
f := strings.Fields(lines[0])
b, err := strconv.ParseFloat(f[0], 64)
if err != nil {
return 0, err
}
t := uint64(time.Now().Unix()) - uint64(b)
return t, nil
}
if statFile == "stat" {
for _, line := range lines {
if strings.HasPrefix(line, "btime") {
@ -102,6 +91,17 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return t, nil
}
}
} else if statFile == "uptime" {
if len(lines) != 1 {
return 0, fmt.Errorf("wrong uptime format")
}
f := strings.Fields(lines[0])
b, err := strconv.ParseFloat(f[0], 64)
if err != nil {
return 0, err
}
t := uint64(time.Now().Unix()) - uint64(b)
return t, nil
}
return 0, fmt.Errorf("could not find btime")
@ -111,7 +111,7 @@ func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
// required variables for concurrency safe virtualization caching.
// required variables for concurrency safe virtualization caching
var (
cachedVirtMap map[string]string
cachedVirtMutex sync.RWMutex
@ -137,27 +137,28 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
if PathExists(filepath.Join(filename, "capabilities")) {
contents, err := ReadLines(filepath.Join(filename, "capabilities"))
if err == nil && StringsContains(contents, "control_d") {
if err == nil {
if StringsContains(contents, "control_d") {
role = "host"
}
}
}
}
filename = HostProc("modules")
if PathExists(filename) {
contents, err := ReadLines(filename)
if err == nil {
switch {
case StringsContains(contents, "kvm"):
if StringsContains(contents, "kvm") {
system = "kvm"
role = "host"
case StringsContains(contents, "vboxdrv"):
} else if StringsContains(contents, "vboxdrv") {
system = "vbox"
role = "host"
case StringsContains(contents, "vboxguest"):
} else if StringsContains(contents, "vboxguest") {
system = "vbox"
role = "guest"
case StringsContains(contents, "vmware"):
} else if StringsContains(contents, "vmware") {
system = "vmware"
role = "guest"
}
@ -200,6 +201,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
if PathExists(filepath.Join(filename, "self", "status")) {
contents, err := ReadLines(filepath.Join(filename, "self", "status"))
if err == nil {
if StringsContains(contents, "s_context:") ||
StringsContains(contents, "VxID:") {
system = "linux-vserver"
@ -222,17 +224,16 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
if PathExists(filepath.Join(filename, "self", "cgroup")) {
contents, err := ReadLines(filepath.Join(filename, "self", "cgroup"))
if err == nil {
switch {
case StringsContains(contents, "lxc"):
if StringsContains(contents, "lxc") {
system = "lxc"
role = "guest"
case StringsContains(contents, "docker"):
} else if StringsContains(contents, "docker") {
system = "docker"
role = "guest"
case StringsContains(contents, "machine-rkt"):
} else if StringsContains(contents, "machine-rkt") {
system = "rkt"
role = "guest"
case PathExists("/usr/bin/lxc-version"):
} else if PathExists("/usr/bin/lxc-version") {
system = "lxc"
role = "host"
}
@ -280,7 +281,7 @@ func GetOSRelease() (platform string, version string, err error) {
return platform, version, nil
}
// trimQuotes removes quotes in the source string.
// Remove quotes of the source string
func trimQuotes(s string) string {
if len(s) >= 2 {
if s[0] == '"' && s[len(s)-1] == '"' {

@ -32,7 +32,8 @@ func TestReadLinesOffsetN(t *testing.T) {
func TestIntToString(t *testing.T) {
src := []int8{65, 66, 67}
if dst := IntToString(src); dst != "ABC" {
dst := IntToString(src)
if dst != "ABC" {
t.Error("could not convert")
}
}
@ -57,7 +58,8 @@ func TestHexToUint32(t *testing.T) {
}
func TestMustParseInt32(t *testing.T) {
if ret := mustParseInt32("11111"); ret != int32(11111) {
ret := mustParseInt32("11111")
if ret != int32(11111) {
t.Error("could not parse")
}
}
@ -100,7 +102,8 @@ func TestHostEtc(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("windows doesn't have etc")
}
if p := HostEtc("mtab"); p != "/etc/mtab" {
p := HostEtc("mtab")
if p != "/etc/mtab" {
t.Errorf("invalid HostEtc, %s", p)
}
}

@ -41,7 +41,8 @@ func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ..
}
func CallPgrepWithContext(ctx context.Context, invoke Invoker, pid int32) ([]int32, error) {
cmd := []string{"-P", strconv.Itoa(int(pid))}
var cmd []string
cmd = []string{"-P", strconv.Itoa(int(pid))}
pgrep, err := exec.LookPath("pgrep")
if err != nil {
return []int32{}, err

@ -2,11 +2,10 @@ package common_test
import (
"context"
"errors"
"testing"
"time"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func TestSleep(test *testing.T) {
@ -14,7 +13,7 @@ func TestSleep(test *testing.T) {
var t = func(name string, ctx context.Context, expected error) {
test.Run(name, func(test *testing.T) {
var err = common.Sleep(ctx, dt)
if !errors.Is(err, expected) {
if err != expected {
test.Errorf("expected %v, got %v", expected, err)
}
})

@ -3,7 +3,7 @@ package load
import (
"encoding/json"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var invoke common.Invoker = common.Invoke{}

@ -1,3 +1,4 @@
//go:build freebsd || openbsd
// +build freebsd openbsd
package load

@ -5,7 +5,7 @@ package load
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func Avg() (*AvgStat, error) {

@ -9,7 +9,7 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func Avg() (*AvgStat, error) {
@ -26,15 +26,16 @@ func AvgWithContext(ctx context.Context) (*AvgStat, error) {
func sysinfoAvgWithContext(ctx context.Context) (*AvgStat, error) {
var info syscall.Sysinfo_t
if err := syscall.Sysinfo(&info); err != nil {
err := syscall.Sysinfo(&info)
if err != nil {
return nil, err
}
const siLoadShift = 16
const si_load_shift = 16
return &AvgStat{
Load1: float64(info.Loads[0]) / float64(1<<siLoadShift),
Load5: float64(info.Loads[1]) / float64(1<<siLoadShift),
Load15: float64(info.Loads[2]) / float64(1<<siLoadShift),
Load1: float64(info.Loads[0]) / float64(1<<si_load_shift),
Load5: float64(info.Loads[1]) / float64(1<<si_load_shift),
Load15: float64(info.Loads[2]) / float64(1<<si_load_shift),
}, nil
}
@ -102,6 +103,7 @@ func MiscWithContext(ctx context.Context) (*MiscStat, error) {
default:
continue
}
}
procsTotal, err := getProcsTotal()

@ -7,7 +7,7 @@ import (
"os/exec"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func Avg() (*AvgStat, error) {

@ -1,15 +1,14 @@
package load
import (
"errors"
"fmt"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func skipIfNotImplementedErr(t testing.TB, err error) {
if errors.Is(err, common.ErrNotImplementedError) {
if err == common.ErrNotImplementedError {
t.Skip("not implemented")
}
}
@ -71,6 +70,7 @@ func TestMiscStatString(t *testing.T) {
}
func BenchmarkLoad(b *testing.B) {
loadAvg := func(t testing.TB) {
v, err := Avg()
skipIfNotImplementedErr(t, err)

@ -9,7 +9,7 @@ import (
"sync"
"time"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var (

@ -3,7 +3,7 @@ package mem
import (
"encoding/json"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var invoke common.Invoker = common.Invoke{}
@ -52,30 +52,30 @@ type VirtualMemoryStat struct {
// https://www.kernel.org/doc/Documentation/vm/overcommit-accounting
Buffers uint64 `json:"buffers"`
Cached uint64 `json:"cached"`
Writeback uint64 `json:"writeback"`
WriteBack uint64 `json:"writeBack"`
Dirty uint64 `json:"dirty"`
WritebackTmp uint64 `json:"writebacktmp"`
WriteBackTmp uint64 `json:"writeBackTmp"`
Shared uint64 `json:"shared"`
Slab uint64 `json:"slab"`
SReclaimable uint64 `json:"sreclaimable"`
SUnreclaim uint64 `json:"sunreclaim"`
PageTables uint64 `json:"pagetables"`
SwapCached uint64 `json:"swapcached"`
CommitLimit uint64 `json:"commitlimit"`
CommittedAS uint64 `json:"committedas"`
HighTotal uint64 `json:"hightotal"`
HighFree uint64 `json:"highfree"`
LowTotal uint64 `json:"lowtotal"`
LowFree uint64 `json:"lowfree"`
SwapTotal uint64 `json:"swaptotal"`
SwapFree uint64 `json:"swapfree"`
Sreclaimable uint64 `json:"sreclaimable"`
Sunreclaim uint64 `json:"sunreclaim"`
PageTables uint64 `json:"pageTables"`
SwapCached uint64 `json:"swapCached"`
CommitLimit uint64 `json:"commitLimit"`
CommittedAS uint64 `json:"committedAS"`
HighTotal uint64 `json:"highTotal"`
HighFree uint64 `json:"highFree"`
LowTotal uint64 `json:"lowTotal"`
LowFree uint64 `json:"lowFree"`
SwapTotal uint64 `json:"swapTotal"`
SwapFree uint64 `json:"swapFree"`
Mapped uint64 `json:"mapped"`
VMallocTotal uint64 `json:"vmalloctotal"`
VMallocUsed uint64 `json:"vmallocused"`
VMallocChunk uint64 `json:"vmallocchunk"`
HugePagesTotal uint64 `json:"hugepagestotal"`
HugePagesFree uint64 `json:"hugepagesfree"`
HugePageSize uint64 `json:"hugepagesize"`
VmallocTotal uint64 `json:"vmallocTotal"`
VmallocUsed uint64 `json:"vmallocUsed"`
VmallocChunk uint64 `json:"vmallocChunk"`
HugePagesTotal uint64 `json:"hugePagesTotal"`
HugePagesFree uint64 `json:"hugePagesFree"`
HugePageSize uint64 `json:"hugePageSize"`
}
type SwapMemoryStat struct {
@ -85,13 +85,13 @@ type SwapMemoryStat struct {
UsedPercent float64 `json:"usedPercent"`
Sin uint64 `json:"sin"`
Sout uint64 `json:"sout"`
PgIn uint64 `json:"pgin"`
PgOut uint64 `json:"pgout"`
PgFault uint64 `json:"pgfault"`
PgIn uint64 `json:"pgIn"`
PgOut uint64 `json:"pgOut"`
PgFault uint64 `json:"pgFault"`
// Linux specific numbers
// https://www.kernel.org/doc/Documentation/cgroup-v2.txt
PgMajFault uint64 `json:"pgmajfault"`
PgMajFault uint64 `json:"pgMajFault"`
}
func (m VirtualMemoryStat) String() string {

@ -7,7 +7,7 @@ import (
"fmt"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)

@ -1,11 +1,11 @@
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!plan9
package mem
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func VirtualMemory() (*VirtualMemoryStat, error) {

@ -9,7 +9,7 @@ import (
"golang.org/x/sys/unix"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func VirtualMemory() (*VirtualMemoryStat, error) {

@ -13,7 +13,7 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)
@ -62,7 +62,7 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
memavail := false
activeFile := false // "Active(file)" not available: 2.6.28 / Dec 2008
inactiveFile := false // "Inactive(file)" not available: 2.6.28 / Dec 2008
sReclaimable := false // "SReclaimable:" not available: 2.6.19 / Nov 2006
sReclaimable := false // "Sreclaimable:" not available: 2.6.19 / Nov 2006
ret := &VirtualMemoryStat{}
retEx := &VirtualMemoryExStat{}
@ -152,18 +152,18 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
return ret, retEx, err
}
retEx.Unevictable = t * 1024
case "Writeback":
case "WriteBack":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Writeback = t * 1024
case "WritebackTmp":
ret.WriteBack = t * 1024
case "WriteBackTmp":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.WritebackTmp = t * 1024
ret.WriteBackTmp = t * 1024
case "Dirty":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
@ -188,13 +188,13 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
return ret, retEx, err
}
sReclaimable = true
ret.SReclaimable = t * 1024
ret.Sreclaimable = t * 1024
case "SUnreclaim":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SUnreclaim = t * 1024
ret.Sunreclaim = t * 1024
case "PageTables":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
@ -266,19 +266,19 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
if err != nil {
return ret, retEx, err
}
ret.VMallocTotal = t * 1024
ret.VmallocTotal = t * 1024
case "VmallocUsed":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VMallocUsed = t * 1024
ret.VmallocUsed = t * 1024
case "VmallocChunk":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VMallocChunk = t * 1024
ret.VmallocChunk = t * 1024
case "HugePages_Total":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
@ -300,7 +300,7 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
}
}
ret.Cached += ret.SReclaimable
ret.Cached += ret.Sreclaimable
if !memavail {
if activeFile && inactiveFile && sReclaimable {
@ -357,25 +357,25 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
continue
}
ret.Sout = value * 4 * 1024
case "pgpgin":
case "pgpgIn":
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
continue
}
ret.PgIn = value * 4 * 1024
case "pgpgout":
case "pgpgOut":
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
continue
}
ret.PgOut = value * 4 * 1024
case "pgfault":
case "pgFault":
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
continue
}
ret.PgFault = value * 4 * 1024
case "pgmajfault":
case "pgMajFault":
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
continue
@ -421,7 +421,7 @@ func calcuateAvailVmem(ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint6
pageCache := retEx.ActiveFile + retEx.InactiveFile
pageCache -= uint64(math.Min(float64(pageCache/2), float64(watermarkLow)))
availMemory += pageCache
availMemory += ret.SReclaimable - uint64(math.Min(float64(ret.SReclaimable/2.0), float64(watermarkLow)))
availMemory += ret.Sreclaimable - uint64(math.Min(float64(ret.Sreclaimable/2.0), float64(watermarkLow)))
if availMemory < 0 {
availMemory = 0

@ -37,13 +37,13 @@ var virtualMemoryTests = []struct {
Laundry: 0,
Buffers: 212496384,
Cached: 4069036032,
Writeback: 0,
WriteBack: 0,
Dirty: 176128,
WritebackTmp: 0,
WriteBackTmp: 0,
Shared: 1222402048,
Slab: 253771776,
SReclaimable: 186470400,
SUnreclaim: 67301376,
Sreclaimable: 186470400,
Sunreclaim: 67301376,
PageTables: 65241088,
SwapCached: 0,
CommitLimit: 16509730816,
@ -55,9 +55,9 @@ var virtualMemoryTests = []struct {
SwapTotal: 8258580480,
SwapFree: 8258580480,
Mapped: 1172627456,
VMallocTotal: 35184372087808,
VMallocUsed: 0,
VMallocChunk: 0,
VmallocTotal: 35184372087808,
VmallocUsed: 0,
VmallocChunk: 0,
HugePagesTotal: 0,
HugePagesFree: 0,
HugePageSize: 2097152},
@ -74,13 +74,13 @@ var virtualMemoryTests = []struct {
Laundry: 0,
Buffers: 4915200,
Cached: 96829440,
Writeback: 0,
WriteBack: 0,
Dirty: 0,
WritebackTmp: 0,
WriteBackTmp: 0,
Shared: 0,
Slab: 9293824,
SReclaimable: 2764800,
SUnreclaim: 6529024,
Sreclaimable: 2764800,
Sunreclaim: 6529024,
PageTables: 405504,
SwapCached: 0,
CommitLimit: 130289664,
@ -92,9 +92,9 @@ var virtualMemoryTests = []struct {
SwapTotal: 0,
SwapFree: 0,
Mapped: 38793216,
VMallocTotal: 1996488704,
VMallocUsed: 0,
VMallocChunk: 0,
VmallocTotal: 1996488704,
VmallocUsed: 0,
VmallocChunk: 0,
HugePagesTotal: 0,
HugePagesFree: 0,
HugePageSize: 0},

@ -10,7 +10,7 @@ import (
"fmt"
"os/exec"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/unix"
)

@ -10,7 +10,7 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
// VirtualMemory for Solaris is a minimal implementation which only returns

@ -5,7 +5,7 @@ import (
"runtime"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/stretchr/testify/assert"
)
@ -86,7 +86,7 @@ func TestVirtualMemoryStat_String(t *testing.T) {
UsedPercent: 30.1,
Free: 40,
}
e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"laundry":0,"buffers":0,"cached":0,"writeback":0,"dirty":0,"writebacktmp":0,"shared":0,"slab":0,"sreclaimable":0,"sunreclaim":0,"pagetables":0,"swapcached":0,"commitlimit":0,"committedas":0,"hightotal":0,"highfree":0,"lowtotal":0,"lowfree":0,"swaptotal":0,"swapfree":0,"mapped":0,"vmalloctotal":0,"vmallocused":0,"vmallocchunk":0,"hugepagestotal":0,"hugepagesfree":0,"hugepagesize":0}`
e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"laundry":0,"buffers":0,"cached":0,"writeBack":0,"dirty":0,"writeBackTmp":0,"shared":0,"slab":0,"sreclaimable":0,"sunreclaim":0,"pageTables":0,"swapCached":0,"commitLimit":0,"committedAS":0,"highTotal":0,"highFree":0,"lowTotal":0,"lowFree":0,"swapTotal":0,"swapFree":0,"mapped":0,"vmallocTotal":0,"vmallocUsed":0,"vmallocChunk":0,"hugePagesTotal":0,"hugePagesFree":0,"hugePageSize":0}`
if e != fmt.Sprintf("%v", v) {
t.Errorf("VirtualMemoryStat string is invalid: %v", v)
}
@ -105,7 +105,7 @@ func TestSwapMemoryStat_String(t *testing.T) {
PgFault: 5,
PgMajFault: 6,
}
e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":1,"sout":2,"pgin":3,"pgout":4,"pgfault":5,"pgmajfault":6}`
e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":1,"sout":2,"pgIn":3,"pgOut":4,"pgFault":5,"pgMajFault":6}`
if e != fmt.Sprintf("%v", v) {
t.Errorf("SwapMemoryStat string is invalid: %v", v)
}

@ -8,7 +8,7 @@ import (
"syscall"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"golang.org/x/sys/windows"
)

@ -5,7 +5,7 @@ import (
"encoding/json"
"net"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var invoke common.Invoker = common.Invoke{}
@ -53,18 +53,24 @@ type InterfaceAddr struct {
Addr string `json:"addr"`
}
// InterfaceAddrList is a list of InterfaceAddr
type InterfaceAddrList []InterfaceAddr
type InterfaceStat struct {
Index int `json:"index"`
MTU int `json:"mtu"` // maximum transmission unit
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
HardwareAddr string `json:"hardwareaddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
HardwareAddr string `json:"hardwareAddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast
Addrs []InterfaceAddr `json:"addrs"`
Addrs InterfaceAddrList `json:"addrs"`
}
// InterfaceStatList is a list of InterfaceStat
type InterfaceStatList []InterfaceStat
type FilterStat struct {
ConnTrackCount int64 `json:"conntrackCount"`
ConnTrackMax int64 `json:"conntrackMax"`
ConnTrackCount int64 `json:"connTrackCount"`
ConnTrackMax int64 `json:"connTrackMax"`
}
// ConntrackStat has conntrack summary info
@ -76,16 +82,16 @@ type ConntrackStat struct {
Invalid uint32 `json:"invalid"` // Number of packets seen which can not be tracked
Ignore uint32 `json:"ignore"` // Packets seen which are already connected to an entry
Delete uint32 `json:"delete"` // Number of entries which were removed
DeleteList uint32 `json:"delete_list"` // Number of entries which were put to dying list
DeleteList uint32 `json:"deleteList"` // Number of entries which were put to dying list
Insert uint32 `json:"insert"` // Number of entries inserted into the list
InsertFailed uint32 `json:"insert_failed"` // # insertion attempted but failed (same entry exists)
InsertFailed uint32 `json:"insertFailed"` // # insertion attempted but failed (same entry exists)
Drop uint32 `json:"drop"` // Number of packets dropped due to conntrack failure.
EarlyDrop uint32 `json:"early_drop"` // Dropped entries to make room for new ones, if maxsize reached
IcmpError uint32 `json:"icmp_error"` // Subset of invalid. Packets that can't be tracked d/t error
ExpectNew uint32 `json:"expect_new"` // Entries added after an expectation was already present
ExpectCreate uint32 `json:"expect_create"` // Expectations added
ExpectDelete uint32 `json:"expect_delete"` // Expectations deleted
SearchRestart uint32 `json:"search_restart"` // Conntrack table lookups restarted due to hashtable resizes
EarlyDrop uint32 `json:"earlyDrop"` // Dropped entries to make room for new ones, if maxsize reached
IcmpError uint32 `json:"icmpError"` // Subset of invalid. Packets that can't be tracked d/t error
ExpectNew uint32 `json:"expectNew"` // Entries added after an expectation was already present
ExpectCreate uint32 `json:"expectCreate"` // Expectations added
ExpectDelete uint32 `json:"expectDelete"` // Expectations deleted
SearchRestart uint32 `json:"searchRestart"` // Conntrack table lookups restarted due to hashtable resizes
}
func NewConntrackStat(e uint32, s uint32, f uint32, n uint32, inv uint32, ign uint32, del uint32, dlst uint32, ins uint32, insfail uint32, drop uint32, edrop uint32, ie uint32, en uint32, ec uint32, ed uint32, sr uint32) *ConntrackStat {
@ -182,6 +188,11 @@ func (n InterfaceStat) String() string {
return string(s)
}
func (l InterfaceStatList) String() string {
s, _ := json.Marshal(l)
return string(s)
}
func (n InterfaceAddr) String() string {
s, _ := json.Marshal(n)
return string(s)
@ -192,16 +203,16 @@ func (n ConntrackStat) String() string {
return string(s)
}
func Interfaces() ([]InterfaceStat, error) {
func Interfaces() (InterfaceStatList, error) {
return InterfacesWithContext(context.Background())
}
func InterfacesWithContext(ctx context.Context) ([]InterfaceStat, error) {
func InterfacesWithContext(ctx context.Context) (InterfaceStatList, error) {
is, err := net.Interfaces()
if err != nil {
return nil, err
}
ret := make([]InterfaceStat, 0, len(is))
ret := make(InterfaceStatList, 0, len(is))
for _, ifi := range is {
var flags []string
@ -230,7 +241,7 @@ func InterfacesWithContext(ctx context.Context) ([]InterfaceStat, error) {
}
addrs, err := ifi.Addrs()
if err == nil {
r.Addrs = make([]InterfaceAddr, 0, len(addrs))
r.Addrs = make(InterfaceAddrList, 0, len(addrs))
for _, addr := range addrs {
r.Addrs = append(r.Addrs, InterfaceAddr{
Addr: addr.String(),

@ -11,7 +11,7 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func parseNetstatI(output string) ([]IOCountersStat, error) {

@ -6,7 +6,7 @@ import (
"context"
"errors"
"fmt"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"os/exec"
"regexp"
"strconv"

@ -5,7 +5,7 @@ package net
import (
"context"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func IOCounters(pernic bool) ([]IOCountersStat, error) {

@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func IOCounters(pernic bool) ([]IOCountersStat, error) {

@ -16,27 +16,27 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
const ( // Conntrack Column numbers
CT_ENTRIES = iota
CT_SEARCHED
CT_FOUND
CT_NEW
CT_INVALID
CT_IGNORE
CT_DELETE
CT_DELETE_LIST
CT_INSERT
CT_INSERT_FAILED
CT_DROP
CT_EARLY_DROP
CT_ICMP_ERROR
CT_EXPECT_NEW
CT_EXPECT_CREATE
CT_EXPECT_DELETE
CT_SEARCH_RESTART
ctENTRIES = iota
ctSEARCHED
ctFOUND
ctNEW
ctINVALID
ctIGNORE
ctDELETE
ctDELETE_LIST
ctINSERT
ctINSERT_FAILED
ctDROP
ctEARLY_DROP
ctICMP_ERROR
CT_EXPEctNEW
ctEXPECT_CREATE
CT_EXPEctDELETE
ctSEARCH_RESTART
)
// NetIOCounters returnes network I/O statistics for every network
@ -278,23 +278,23 @@ func conntrackStatsFromFile(filename string, percpu bool) ([]ConntrackStat, erro
fields := strings.Fields(line)
if len(fields) == 17 && fields[0] != "entries" {
statlist.Append(NewConntrackStat(
common.HexToUint32(fields[CT_ENTRIES]),
common.HexToUint32(fields[CT_SEARCHED]),
common.HexToUint32(fields[CT_FOUND]),
common.HexToUint32(fields[CT_NEW]),
common.HexToUint32(fields[CT_INVALID]),
common.HexToUint32(fields[CT_IGNORE]),
common.HexToUint32(fields[CT_DELETE]),
common.HexToUint32(fields[CT_DELETE_LIST]),
common.HexToUint32(fields[CT_INSERT]),
common.HexToUint32(fields[CT_INSERT_FAILED]),
common.HexToUint32(fields[CT_DROP]),
common.HexToUint32(fields[CT_EARLY_DROP]),
common.HexToUint32(fields[CT_ICMP_ERROR]),
common.HexToUint32(fields[CT_EXPECT_NEW]),
common.HexToUint32(fields[CT_EXPECT_CREATE]),
common.HexToUint32(fields[CT_EXPECT_DELETE]),
common.HexToUint32(fields[CT_SEARCH_RESTART]),
common.HexToUint32(fields[ctENTRIES]),
common.HexToUint32(fields[ctSEARCHED]),
common.HexToUint32(fields[ctFOUND]),
common.HexToUint32(fields[ctNEW]),
common.HexToUint32(fields[ctINVALID]),
common.HexToUint32(fields[ctIGNORE]),
common.HexToUint32(fields[ctDELETE]),
common.HexToUint32(fields[ctDELETE_LIST]),
common.HexToUint32(fields[ctINSERT]),
common.HexToUint32(fields[ctINSERT_FAILED]),
common.HexToUint32(fields[ctDROP]),
common.HexToUint32(fields[ctEARLY_DROP]),
common.HexToUint32(fields[ctICMP_ERROR]),
common.HexToUint32(fields[CT_EXPEctNEW]),
common.HexToUint32(fields[ctEXPECT_CREATE]),
common.HexToUint32(fields[CT_EXPEctDELETE]),
common.HexToUint32(fields[ctSEARCH_RESTART]),
))
}
}
@ -306,7 +306,7 @@ func conntrackStatsFromFile(filename string, percpu bool) ([]ConntrackStat, erro
}
// http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
var TCPStatuses = map[string]string{
var tcpStatuses = map[string]string{
"01": "ESTABLISHED",
"02": "SYN_SENT",
"03": "SYN_RECV",
@ -545,12 +545,12 @@ func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, erro
return ret, err
}
defer f.Close()
files, err := f.Readdir(max)
dirEntries, err := f.ReadDir(max)
if err != nil {
return ret, err
}
for _, fd := range files {
inodePath := fmt.Sprintf("%s/%d/fd/%s", root, pid, fd.Name())
for _, dirEntry := range dirEntries {
inodePath := fmt.Sprintf("%s/%d/fd/%s", root, pid, dirEntry.Name())
inode, err := os.Readlink(inodePath)
if err != nil {
@ -566,7 +566,7 @@ func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, erro
if !ok {
ret[inode] = make([]inodeMap, 0)
}
fd, err := strconv.Atoi(fd.Name())
fd, err := strconv.Atoi(dirEntry.Name())
if err != nil {
continue
}
@ -786,7 +786,7 @@ func processInet(file string, kind netConnectionKindType, inodes map[string][]in
continue
}
if kind.sockType == syscall.SOCK_STREAM {
status = TCPStatuses[status]
status = tcpStatuses[status]
} else {
status = "NONE"
}

@ -9,7 +9,7 @@ import (
"syscall"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/stretchr/testify/assert"
)
@ -187,7 +187,7 @@ func TestConntrackStatFileParsing(t *testing.T) {
assert.Nil(t, err, "Temporary file creation failed: ", err)
data := []byte(`
entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart
entries searched found new invalid ignore delete deleteList insert insertFailed drop earlyDrop icmpError expectNew expectCreate expectDelete searchRestart
0000007b 00000000 00000000 00000000 000b115a 00000084 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000004a
0000007b 00000000 00000000 00000000 0007eee5 00000068 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000035
0000007b 00000000 00000000 00000000 0090346b 00000057 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000025

@ -11,7 +11,7 @@ import (
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`)

@ -7,7 +7,7 @@ import (
"runtime"
"testing"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/v3/internal/common"
)
func skipIfNotImplementedErr(t *testing.T, err error) {
@ -20,7 +20,7 @@ func TestAddrString(t *testing.T) {
v := Addr{IP: "192.168.0.1", Port: 8000}
s := fmt.Sprintf("%v", v)
if s != "{\"ip\":\"192.168.0.1\",\"port\":8000}" {
if s != `{"ip":"192.168.0.1","port":8000}` {
t.Errorf("Addr string is invalid: %v", v)
}
}
@ -232,7 +232,7 @@ func TestNetFilterCounters(t *testing.T) {
if runtime.GOOS == "linux" {
// some test environment has not the path.
if !common.PathExists("/proc/sys/net/netfilter/nf_conntrackCount") {
if !common.PathExists("/proc/sys/net/netfilter/nf_connTrackCount") {
t.SkipNow()
}
}
@ -247,8 +247,30 @@ func TestNetFilterCounters(t *testing.T) {
}
for _, vv := range v {
if vv.ConnTrackMax == 0 {
t.Errorf("nf_conntrackMax needs to be greater than zero: %v", vv)
t.Errorf("nf_connTrackMax needs to be greater than zero: %v", vv)
}
}
}
func TestInterfaceStatString(t *testing.T) {
v := InterfaceStat{
Index: 0,
MTU: 1500,
Name: "eth0",
HardwareAddr: "01:23:45:67:89:ab",
Flags: []string{"up", "down"},
Addrs: InterfaceAddrList{{Addr: "1.2.3.4"}, {Addr: "5.6.7.8"}},
}
s := fmt.Sprintf("%v", v)
if s != `{"index":0,"mtu":1500,"name":"eth0","hardwareAddr":"01:23:45:67:89:ab","flags":["up","down"],"addrs":[{"addr":"1.2.3.4"},{"addr":"5.6.7.8"}]}` {
t.Errorf("InterfaceStat string is invalid: %v", s)
}
list := InterfaceStatList{v, v}
s = fmt.Sprintf("%v", list)
if s != `[{"index":0,"mtu":1500,"name":"eth0","hardwareAddr":"01:23:45:67:89:ab","flags":["up","down"],"addrs":[{"addr":"1.2.3.4"},{"addr":"5.6.7.8"}]},{"index":0,"mtu":1500,"name":"eth0","hardwareAddr":"01:23:45:67:89:ab","flags":["up","down"],"addrs":[{"addr":"1.2.3.4"},{"addr":"5.6.7.8"}]}]` {
t.Errorf("InterfaceStatList string is invalid: %v", s)
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save