diff --git a/.github/labeler.yml b/.github/labeler.yml index 4b43d26b0..dde462a11 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -14,6 +14,8 @@ package:net: - net/* package:process: - process/* +package:sensors: + - sensors/* package:winservices: - winservices/* os:linux: diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 09093cdb0..9aea984da 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -13,7 +13,7 @@ jobs: run: | versions=$(curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])') echo "::set-output name=value::${versions}" - build_test_v3: + build_test: needs: go-versions strategy: fail-fast: false diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7e5a66dc1..bdd22a7b3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: run: | versions=$(curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])') echo "::set-output name=value::${versions}" - test_v3_module: + test: needs: go-versions strategy: fail-fast: false diff --git a/Makefile b/Makefile index 864b1f666..da1cca5ea 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ macos_test: init_tools: go get github.com/golang/dep/cmd/dep -TAG=$(shell date +'v3.%y.%-m' --date='last Month') +TAG=$(shell date +'v4.%y.%-m' --date='last Month') release: git tag $(TAG) diff --git a/README.md b/README.md index fea8e7efd..1e21451be 100644 --- a/README.md +++ b/README.md @@ -5,20 +5,21 @@ This is a port of psutil (https://github.com/giampaolo/psutil). The challenge is porting all psutil functions on some architectures. -## v3 migration +## migration -From v3.20.10, gopsutil becomes v3 which breaks backwards compatibility. -See [v3Changes.md](_tools/v3migration/v3Changes.md) for more detailed changes. +### v4 migration + +There are some breaking changes. Please see [v4 release note](https://github.com/shirou/gopsutil/releases/tag/v4.24.5). ## Tag semantics gopsutil tag policy is almost same as Semantic Versioning, but automatically increases like [Ubuntu versioning](https://calver.org/). -For example, v2.17.04 means +For example, v4.24.04 means -- v2: major version -- 17: release year, 2017 +- v4: major version +- 24: release year, 2024 - 04: release month gopsutil aims to keep backwards compatibility until major version change. @@ -33,16 +34,14 @@ can be skipped. - Windows i386/amd64/arm/arm64 - Darwin amd64/arm64 - OpenBSD i386/amd64/armv7/arm64/riscv64 (Thank you @mpfz0r!) -- Solaris amd64 (developed and tested on SmartOS/Illumos, Thank you - @jen20!) +- Solaris amd64 (developed and tested on SmartOS/Illumos, Thank you @jen20!) These have partial support: - CPU on DragonFly BSD (#893, Thank you @gballet!) - host on Linux RISC-V (#896, Thank you @tklauser!) -All works are implemented without cgo by porting C structs to golang -structs. +All works are implemented without cgo by porting C structs to golang structs. ## Usage @@ -52,8 +51,7 @@ package main import ( "fmt" - "github.com/shirou/gopsutil/v3/mem" - // "github.com/shirou/gopsutil/mem" // to use v2 + "github.com/shirou/gopsutil/v4/mem" ) func main() { @@ -120,13 +118,38 @@ Be very careful that enabling the cache may cause inconsistencies. For example, - `process` - EnableBootTimeCache +### `Ex` struct (from v4.24.5) + +gopsutil is designed to work across multiple platforms. However, there are differences in the information available on different platforms, such as memory information that exists on Linux but not on Windows. + +As of v4.24.5, to access this platform-specific information, gopsutil provides functions named `Ex` within the package. Currently, these functions are available in the mem and sensor packages. + +The Ex structs are specific to each platform. For example, on Linux, there is an `ExLinux` struct, which can be obtained using the `mem.NewExLinux()` function. On Windows, it's `mem.ExWindows()`. These Ex structs provide platform-specific information. + +``` +ex := NewExWindows() +v, err := ex.VirtualMemory() +if err != nil { + panic(err) +} + +fmt.Println(v.VirtualAvail) +fmt.Println(v.VirtualTotal) + +// Output: +// 140731958648832 +// 140737488224256 +``` + +gopsutil aims to minimize platform differences by offering common functions. However, there are many requests to obtain unique information for each platform. The Ex structs are designed to meet those requests. Additional functionalities might be added in the future. The use of these structures makes it clear that the information they provide is specific to each platform, which is why they have been designed in this way. + ## Documentation -See https://pkg.go.dev/github.com/shirou/gopsutil/v3 or https://godocs.io/github.com/shirou/gopsutil/v3 +See https://pkg.go.dev/github.com/shirou/gopsutil/v4 or https://godocs.io/github.com/shirou/gopsutil/v4 ## Requirements -- go1.16 or above is required. +- go1.18 or above is required. ## More Info @@ -184,28 +207,29 @@ Some code is ported from Ohai. Many thanks. - x: works - b: almost works, but something is broken - -|name |Linux |FreeBSD |OpenBSD |macOS |Windows |Solaris |Plan 9 | -|----------------------|-------|---------|---------|--------|---------|---------|---------| -|cpu\_times |x |x |x |x |x | |b | -|cpu\_count |x |x |x |x |x | |x | -|cpu\_percent |x |x |x |x |x | | | -|cpu\_times\_percent |x |x |x |x |x | | | -|virtual\_memory |x |x |x |x |x | b |x | -|swap\_memory |x |x |x |x | | |x | -|disk\_partitions |x |x |x |x |x | | | -|disk\_io\_counters |x |x |x | | | | | -|disk\_usage |x |x |x |x |x | | | -|net\_io\_counters |x |x |x |b |x | | | -|boot\_time |x |x |x |x |x | | | -|users |x |x |x |x |x | | | -|pids |x |x |x |x |x | | | -|pid\_exists |x |x |x |x |x | | | -|net\_connections |x |x |x |x | | | | -|net\_protocols |x | | | | | | | -|net\_if\_addrs | | | | | | | | -|net\_if\_stats | | | | | | | | -|netfilter\_conntrack |x | | | | | | | +- c: works in CGO only + +|name |Linux |FreeBSD |OpenBSD |macOS |Windows |Solaris |Plan 9 |AIX | +|----------------------|-------|---------|---------|--------|---------|---------|---------|---------| +|cpu\_times |x |x |x |x |x | |b |x | +|cpu\_count |x |x |x |x |x | |x |x | +|cpu\_percent |x |x |x |x |x | | |x | +|cpu\_times\_percent |x |x |x |x |x | | |x | +|virtual\_memory |x |x |x |x |x | b |x |x | +|swap\_memory |x |x |x |x | | |x |X | +|disk\_partitions |x |x |x |x |x | | |x | +|disk\_io\_counters |x |x |x | | | | | | +|disk\_usage |x |x |x |x |x | | |x | +|net\_io\_counters |x |x |x |b |x | | | | +|boot\_time |x |x |x |x |x | | |X | +|users |x |x |x |x |x | | |x | +|pids |x |x |x |x |x | | | | +|pid\_exists |x |x |x |x |x | | | | +|net\_connections |x |x |x |x | | | |x | +|net\_protocols |x | | | | | | |x | +|net\_if\_addrs | | | | | | | |x | +|net\_if\_stats | | | | | | | |x | +|netfilter\_conntrack |x | | | | | | | | ### Process class @@ -254,37 +278,37 @@ Some code is ported from Ohai. Many thanks. ### Original Metrics -|item |Linux |FreeBSD |OpenBSD |macOS |Windows |Solaris | -|-----------------|-------|---------|---------|--------|--------|---------| -|**HostInfo** | | | | | | | -|hostname |x |x |x |x |x |x | -|uptime |x |x |x |x | |x | -|process |x |x |x | | |x | -|os |x |x |x |x |x |x | -|platform |x |x |x |x | |x | -|platformfamily |x |x |x |x | |x | -|virtualization |x | | | | | | -|**CPU** | | | | | | | -|VendorID |x |x |x |x |x |x | -|Family |x |x |x |x |x |x | -|Model |x |x |x |x |x |x | -|Stepping |x |x |x |x |x |x | -|PhysicalID |x | | | | |x | -|CoreID |x | | | | |x | -|Cores |x | | | |x |x | -|ModelName |x |x |x |x |x |x | -|Microcode |x | | | | |x | -|**LoadAvg** | | | | | | | -|Load1 |x |x |x |x | | | -|Load5 |x |x |x |x | | | -|Load15 |x |x |x |x | | | -|**GetDockerID** | | | | | | | -|container id |x |no |no |no |no | | -|**CgroupsCPU** | | | | | | | -|user |x |no |no |no |no | | -|system |x |no |no |no |no | | -|**CgroupsMem** | | | | | | | -|various |x |no |no |no |no | | +|item |Linux |FreeBSD |OpenBSD |macOS |Windows |Solaris |AIX | +|-----------------|-------|---------|---------|--------|--------|---------|---------| +|**HostInfo** | | | | | | | | +|hostname |x |x |x |x |x |x |X | +|uptime |x |x |x |x | |x |x | +|process |x |x |x | | |x | | +|os |x |x |x |x |x |x |x | +|platform |x |x |x |x | |x |x | +|platformfamily |x |x |x |x | |x |x | +|virtualization |x | | | | | | | +|**CPU** | | | | | | | | +|VendorID |x |x |x |x |x |x |x | +|Family |x |x |x |x |x |x |x | +|Model |x |x |x |x |x |x |x | +|Stepping |x |x |x |x |x |x | | +|PhysicalID |x | | | | |x | | +|CoreID |x | | | | |x | | +|Cores |x | | | |x |x |x | +|ModelName |x |x |x |x |x |x |x | +|Microcode |x | | | | |x | | +|**LoadAvg** | | | | | | | | +|Load1 |x |x |x |x | | |x | +|Load5 |x |x |x |x | | |x | +|Load15 |x |x |x |x | | |x | +|**GetDockerID** | | | | | | | | +|container id |x |no |no |no |no | | | +|**CgroupsCPU** | | | | | | | | +|user |x |no |no |no |no | | | +|system |x |no |no |no |no | | | +|**CgroupsMem** | | | | | | | | +|various |x |no |no |no |no | | | - future work - process_iter @@ -292,6 +316,7 @@ Some code is ported from Ohai. Many thanks. - Process class - as_dict - wait + - AIX processes ## License @@ -320,5 +345,4 @@ I have been influenced by the following great works: 4. Push to the branch (git push origin my-new-feature) 5. Create new Pull Request -English is not my native language, so PRs correcting grammar or spelling -are welcome and appreciated. +English is not my native language, so PRs correcting grammar or spelling are welcome and appreciated. diff --git a/_tools/v3migration/v3Changes.md b/_tools/v3migration/v3Changes.md deleted file mode 100644 index 1cd739e67..000000000 --- a/_tools/v3migration/v3Changes.md +++ /dev/null @@ -1,18 +0,0 @@ -# v2 to v3 changes - -- v3 is in the `v3` directory - -- [process] RLimit is now uint64 ([#364](https://github.com/shirou/gopsutil/issues/364)) -- [process] Remove process.NetIOCounters ([#429](https://github.com/shirou/gopsutil/issues/429)) -- [docker] fix typo of memoryLimitInBbytes ([#464](https://github.com/shirou/gopsutil/issues/464)) -- [mem] VirtualMemoryStat JSON fields capitalization ([#545](https://github.com/shirou/gopsutil/issues/545)) - - various JSON field name and some of Variable name have been changed. see v3migration.sh -- [all] various kind of platform dependent values/constants such as process.GetWin32Proc is now private. see v3migration.sh -- [process] process.Status() now returns []string. and status string is "Running", not just "R". defined in process.go. ([#596](https://github.com/shirou/gopsutil/issues/596)) -- [docker] `CgroupCPU()` now returns `*CgroupCPUStat` with Usage ([#590](https://github.com/shirou/gopsutil/issues/590) and [#581](https://github.com/shirou/gopsutil/issues/581)) -- [disk] `disk.Opts` is now string[], not string. (related to [#955](https://github.com/shirou/gopsutil/issues/955)) -- [host] Fixed temperature sensors detection in Linux ([#905](https://github.com/shirou/gopsutil/issues/905)) -- [disk] `GetDiskSerialNumber()` is now `SerialNumber()` and spread to all platforms -- [disk] `GetLabel ()` is now `Label()` and spread to all platform -- [net] Change net.InterfaceStat.Addrs to InterfaceAddrList ([#226](https://github.com/shirou/gopsutil/issues/226)) -- [cpu] Removed windows-specific `ProcInfo()` diff --git a/_tools/v3migration/v3migration.go b/_tools/v3migration/v3migration.go deleted file mode 100644 index eb826f465..000000000 --- a/_tools/v3migration/v3migration.go +++ /dev/null @@ -1,106 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/token" - "log" - "os" - - "golang.org/x/tools/go/ast/astutil" -) - -// https://github.com/shirou/gopsutil/issues/429 -func issue429() error { - f := func(filename string) error { - fset := token.NewFileSet() - expr, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) - if err != nil { - return err - } - n := astutil.Apply(expr, func(cr *astutil.Cursor) bool { - if cr.Name() == "Decls" { - switch n := cr.Node().(type) { - case *ast.FuncDecl: - if n.Name.Name == "NetIOCounters" || n.Name.Name == ("NetIOCountersWithContext") { - cr.Delete() - } - } - } - return true - }, nil) - return replace(filename, fset, n) - } - - root := "process/" - fnames := []string{"process.go", "process_darwin.go", "process_fallback.go", "process_freebsd.go", "process_linux.go", "process_openbsd.go", "process_bsd.go", "process_posix.go", "process_windows.go", "process_test.go"} - for _, fname := range fnames { - if err := f(root + fname); err != nil { - log.Fatalln("run 429:", err) - } - } - return nil -} - -func issueRemoveUnusedValue() error { - f := func(filename string) error { - fset := token.NewFileSet() - expr, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) - if err != nil { - return err - } - n := astutil.Apply(expr, func(cr *astutil.Cursor) bool { - if cr.Name() == "Decls" { - switch n := cr.Node().(type) { - case *ast.GenDecl: - if n.Tok != token.TYPE { - break - } - ts := n.Specs[0].(*ast.TypeSpec) - if ts.Name.Name == "SystemProcessInformation" { - cr.Delete() - } - } - } - return true - }, nil) - return replace(filename, fset, n) - } - - if err := f("process/process_windows.go"); err != nil { - log.Fatalln("run 429:", err) - } - return nil -} - -func replace(filename string, fset *token.FileSet, n ast.Node) error { - if err := os.Remove(filename); err != nil { - return err - } - fp, err := os.Create(filename) - if err != nil { - return err - } - defer fp.Close() - if err := format.Node(fp, fset, n); err != nil { - return err - } - fp.WriteString("\n") - return nil -} - -func main() { - flag.Parse() - for _, n := range flag.Args() { - fmt.Println("issue:" + n) - switch n { - case "429": - issue429() - case "issueRemoveUnusedValue": - issueRemoveUnusedValue() - } - } -} diff --git a/_tools/v3migration/v3migration.sh b/_tools/v3migration/v3migration.sh deleted file mode 100644 index 39f65e899..000000000 --- a/_tools/v3migration/v3migration.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env bash - -set -eu - -# this scripts is used when migrating v2 to v3. -# usage: cd ${GOPATH}/src/github.com/shirou/gopsutil && bash tools/v3migration/v3migration.sh - - - -DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)" -ROOT=$(cd "${DIR}"/../.. && pwd) - - -## 1. refresh -cd "${ROOT}" - -/bin/rm -rf v3 - -## 2. copy directories -# docker is removed, #464 will be fixed -mkdir -p v3 -cp -rp cpu disk docker host internal load mem net process winservices v3 -cp Makefile v3 - -# build migartion tool -go build -o v3/v3migration "${DIR}"/v3migration.go - - -V3DIR=$(cd "${ROOT}"/v3 && pwd) -cd "${V3DIR}" - -## 3. mod -go mod init - -### change import path -find . -name "*.go" -print0 | xargs -0 -I@ sed -i 's|"github.com/shirou/gopsutil/|"github.com/shirou/gopsutil/v3/|g' @ - -############ Issues - -# #429 process.NetIOCounters is pointless on Linux -./v3migration "$(pwd)" 429 -sed -i '/NetIOCounters/d' process/process.go -sed -i "/github.com\/shirou\/gopsutil\/v3\/net/d" process/process_bsd.go - - -# #464 CgroupMem : fix typo and wrong file names -sed -i 's|memoryLimitInBbytes|memoryLimitInBytes|g' docker/docker.go -sed -i 's|memoryLimitInBbytes|memory.limit_in_bytes|g' docker/docker_linux.go -sed -i 's|memoryFailcnt|memory.failcnt|g' docker/docker_linux.go - - -# fix #346 -sed -i 's/Soft int32/Soft uint64/' process/process.go -sed -i 's/Hard int32/Hard uint64/' process/process.go -sed -i 's| //TODO too small. needs to be uint64||' process/process.go -sed -i 's|limitToInt(val string) (int32, error)|limitToUint(val string) (uint64, error)|' process/process_*.go -sed -i 's|limitToInt|limitToUint|' process/process_*.go -sed -i 's|return int32(res), nil|return uint64(res), nil|' process/process_*.go -sed -i 's|math.MaxInt32|math.MaxUint64|' process/process_*.go - -# fix #545 -# variable names -sed -i 's|WritebackTmp|WriteBackTmp|g' mem/*.go -sed -i 's|Writeback|WriteBack|g' mem/*.go -sed -i 's|SReclaimable|Sreclaimable|g' mem/*.go -sed -i 's|SUnreclaim|Sunreclaim|g' mem/*.go -sed -i 's|VMallocTotal|VmallocTotal|g' mem/*.go -sed -i 's|VMallocUsed|VmallocUsed|g' mem/*.go -sed -i 's|VMallocChunk|VmallocChunk|g' mem/*.go - -# json field name -sed -i 's|hostid|hostId|g' host/host.go -sed -i 's|hostid|hostId|g' host/host_test.go -sed -i 's|sensorTemperature|temperature|g' host/host.go -sed -i 's|sensorTemperature|temperature|g' host/host_test.go - -sed -i 's|writeback|writeBack|g' mem/*.go -sed -i 's|writeBacktmp|writeBackTmp|g' mem/*.go -sed -i 's|pagetables|pageTables|g' mem/*.go -sed -i 's|swapcached|swapCached|g' mem/*.go -sed -i 's|commitlimit|commitLimit|g' mem/*.go -sed -i 's|committedas|committedAS|g' mem/*.go -sed -i 's|hightotal|highTotal|g' mem/*.go -sed -i 's|highfree|highFree|g' mem/*.go -sed -i 's|lowtotal|lowTotal|g' mem/*.go -sed -i 's|lowfree|lowFree|g' mem/*.go -sed -i 's|swaptotal|swapTotal|g' mem/*.go -sed -i 's|swapfree|swapFree|g' mem/*.go -sed -i 's|vmalloctotal|vmallocTotal|g' mem/*.go -sed -i 's|vmallocused|vmallocUsed|g' mem/*.go -sed -i 's|vmallocchunk|vmallocChunk|g' mem/*.go -sed -i 's|hugepagestotal|hugePagesTotal|g' mem/*.go -sed -i 's|hugepagesfree|hugePagesFree|g' mem/*.go -sed -i 's|hugepagesize|hugePageSize|g' mem/*.go -sed -i 's|pgin|pgIn|g' mem/*.go -sed -i 's|pgout|pgOut|g' mem/*.go -sed -i 's|pgfault|pgFault|g' mem/*.go -sed -i 's|pgmajfault|pgMajFault|g' mem/*.go - -sed -i 's|hardwareaddr|hardwareAddr|g' net/*.go -sed -i 's|conntrackCount|connTrackCount|g' net/*.go -sed -i 's|conntrackMax|connTrackMax|g' net/*.go -sed -i 's|delete_list|deleteList|g' net/*.go -sed -i 's|insert_failed|insertFailed|g' net/*.go -sed -i 's|early_drop|earlyDrop|g' net/*.go -sed -i 's|expect_create|expectCreate|g' net/*.go -sed -i 's|expect_delete|expectDelete|g' net/*.go -sed -i 's|search_restart|searchRestart|g' net/*.go -sed -i 's|icmp_error|icmpError|g' net/*.go -sed -i 's|expect_new|expectNew|g' net/*.go - - - -# fix no more public API/types/constants defined only for some platforms - -sed -i 's|CTLKern|ctlKern|g' cpu/*.go -sed -i 's|CPNice|cpNice|g' cpu/*.go -sed -i 's|CPSys|cpSys|g' cpu/*.go -sed -i 's|CPIntr|cpIntr|g' cpu/*.go -sed -i 's|CPIdle|cpIdle|g' cpu/*.go -sed -i 's|CPUStates|cpUStates|g' cpu/*.go -sed -i 's|CTLKern|ctlKern|g' cpu/cpu_openbsd.go -sed -i 's|CTLHw|ctlHw|g' cpu/cpu_openbsd.go -sed -i 's|SMT|sMT|g' cpu/cpu_openbsd.go -sed -i 's|KernCptime|kernCptime|g' cpu/cpu_openbsd.go -sed -i 's|KernCptime2|kernCptime2|g' cpu/cpu_openbsd.go -sed -i 's|Win32_Processor|win32Processor|g' cpu/cpu_windows.go - -sed -i 's|DEVSTAT_NO_DATA|devstat_NO_DATA|g' disk/*.go -sed -i 's|DEVSTAT_READ|devstat_READ|g' disk/*.go -sed -i 's|DEVSTAT_WRITE|devstat_WRITE|g' disk/*.go -sed -i 's|DEVSTAT_FREE|devstat_FREE|g' disk/*.go -sed -i 's|Devstat|devstat|g' disk/*.go -sed -i 's|Bintime|bintime|g' disk/*.go -sed -i 's|SectorSize|sectorSize|g' disk/disk_linux.go -sed -i 's|FileFileCompression|fileFileCompression|g' disk/disk_windows.go -sed -i 's|FileReadOnlyVolume|fileReadOnlyVolume|g' disk/disk_windows.go - -sed -i 's|USER_PROCESS|user_PROCESS|g' host/host_*.go -sed -i 's|LSB|lsbStruct|g' host/host_linux* - -sed -i 's| BcacheStats | bcacheStats |g' mem/*.go - -sed -i 's|TCPStatuses|tcpStatuses|g' net/*.go -sed -i 's|CT_ENTRIES|ctENTRIES|g' net/net_linux.go -sed -i 's|CT_SEARCHED|ctSEARCHED|g' net/net_linux.go -sed -i 's|CT_FOUND|ctFOUND|g' net/net_linux.go -sed -i 's|CT_NEW|ctNEW|g' net/net_linux.go -sed -i 's|CT_INVALID|ctINVALID|g' net/net_linux.go -sed -i 's|CT_IGNORE|ctIGNORE|g' net/net_linux.go -sed -i 's|CT_DELETE|ctDELETE|g' net/net_linux.go -sed -i 's|CT_DELETE_LIST|ctDELETE_LIST|g' net/net_linux.go -sed -i 's|CT_INSERT|ctINSERT|g' net/net_linux.go -sed -i 's|CT_INSERT_FAILED|ctINSERT_FAILED|g' net/net_linux.go -sed -i 's|CT_DROP|ctDROP|g' net/net_linux.go -sed -i 's|CT_EARLY_DROP|ctEARLY_DROP|g' net/net_linux.go -sed -i 's|CT_ICMP_ERROR|ctICMP_ERROR|g' net/net_linux.go -sed -i 's|CT_EXPECT_NEW|ctEXPECT_NEW|g' net/net_linux.go -sed -i 's|CT_EXPECT_CREATE|ctEXPECT_CREATE|g' net/net_linux.go -sed -i 's|CT_EXPECT_DELETE|ctEXPECT_DELETE|g' net/net_linux.go -sed -i 's|CT_SEARCH_RESTART|ctSEARCH_RESTART|g' net/net_linux.go - -sed -i 's|PageSize|pageSize|g' process/process_*.go -sed -i 's|PrioProcess|prioProcess|g' process/process_*.go -sed -i 's|ClockTicks|clockTicks|g' process/process_*.go - - -./v3migration "$(pwd)" issueRemoveUnusedValue - - -############ SHOULD BE FIXED BY HAND diff --git a/common/env.go b/common/env.go index 4b5f4980c..4acad1fd1 100644 --- a/common/env.go +++ b/common/env.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common type EnvKeyType string diff --git a/coverall.sh b/coverall.sh deleted file mode 100644 index f759a4670..000000000 --- a/coverall.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -# see http://www.songmu.jp/riji/entry/2015-01-15-goveralls-multi-package.html - -set -e -# cleanup -cleanup() { - if [ "$tmpprof" != "" ] && [ -f "$tmpprof" ]; then - rm -f "$tmpprof" - fi - exit -} -trap cleanup INT QUIT TERM EXIT - -# メインの処理 -prof=${1:-".profile.cov"} -echo "mode: count" > "$prof" -gopath1=$(echo "$GOPATH" | cut -d: -f1) -for pkg in $(go list ./...); do - tmpprof="$gopath1/src/$pkg/profile.tmp" - go test -covermode=count -coverprofile="$tmpprof" "$pkg" - if [ -f "$tmpprof" ]; then - tail -n +2 "$tmpprof" >> "$prof" - rm "$tmpprof" - fi -done diff --git a/cpu/cpu.go b/cpu/cpu.go index 83bc23d45..56f53c3a1 100644 --- a/cpu/cpu.go +++ b/cpu/cpu.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( @@ -11,7 +12,7 @@ import ( "sync" "time" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) // TimesStat contains the amounts of time the CPU has spent performing different diff --git a/cpu/cpu_aix.go b/cpu/cpu_aix.go index 1439d1d79..bc766bd4f 100644 --- a/cpu/cpu_aix.go +++ b/cpu/cpu_aix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix -// +build aix package cpu diff --git a/cpu/cpu_aix_cgo.go b/cpu/cpu_aix_cgo.go index 9c1e70b17..559dc5fea 100644 --- a/cpu/cpu_aix_cgo.go +++ b/cpu/cpu_aix_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && cgo -// +build aix,cgo package cpu diff --git a/cpu/cpu_aix_nocgo.go b/cpu/cpu_aix_nocgo.go index a77b4dbb7..329ef8336 100644 --- a/cpu/cpu_aix_nocgo.go +++ b/cpu/cpu_aix_nocgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && !cgo -// +build aix,!cgo package cpu @@ -8,12 +8,61 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { + var ret []TimesStat if percpu { - return []TimesStat{}, common.ErrNotImplementedError + per_out, err := invoke.CommandWithContext(ctx, "sar", "-u", "-P", "ALL", "10", "1") + if err != nil { + return nil, err + } + lines := strings.Split(string(per_out), "\n") + if len(lines) < 6 { + return []TimesStat{}, common.ErrNotImplementedError + } + + hp := strings.Fields(lines[5]) // headers + for l := 6; l < len(lines)-1; l++ { + ct := &TimesStat{} + v := strings.Fields(lines[l]) // values + for i, header := range hp { + // We're done in any of these use cases + if i >= len(v) || v[0] == "-" { + break + } + + // Position variable for v + pos := i + // There is a missing field at the beginning of all but the first line + // so adjust the position + if l > 6 { + pos = i - 1 + } + // We don't want invalid positions + if pos < 0 { + continue + } + + if t, err := strconv.ParseFloat(v[pos], 64); err == nil { + switch header { + case `cpu`: + ct.CPU = strconv.FormatFloat(t, 'f', -1, 64) + case `%usr`: + ct.User = t + case `%sys`: + ct.System = t + case `%wio`: + ct.Iowait = t + case `%idle`: + ct.Idle = t + } + } + } + // Valid CPU data, so append it + ret = append(ret, *ct) + } } else { out, err := invoke.CommandWithContext(ctx, "sar", "-u", "10", "1") if err != nil { @@ -24,26 +73,28 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { return []TimesStat{}, common.ErrNotImplementedError } - ret := TimesStat{CPU: "cpu-total"} + ct := &TimesStat{CPU: "cpu-total"} h := strings.Fields(lines[len(lines)-3]) // headers v := strings.Fields(lines[len(lines)-2]) // values for i, header := range h { if t, err := strconv.ParseFloat(v[i], 64); err == nil { switch header { case `%usr`: - ret.User = t + ct.User = t case `%sys`: - ret.System = t + ct.System = t case `%wio`: - ret.Iowait = t + ct.Iowait = t case `%idle`: - ret.Idle = t + ct.Idle = t } } } - return []TimesStat{ret}, nil + ret = append(ret, *ct) } + + return ret, nil } func InfoWithContext(ctx context.Context) ([]InfoStat, error) { @@ -78,6 +129,20 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { } } break + } else if strings.HasPrefix(line, "System Model:") { + p := strings.Split(string(line), ":") + if p != nil { + ret.VendorID = strings.TrimSpace(p[1]) + } + } else if strings.HasPrefix(line, "Processor Type:") { + p := strings.Split(string(line), ":") + if p != nil { + c := strings.Split(string(p[1]), "_") + if c != nil { + ret.Family = strings.TrimSpace(c[0]) + ret.Model = strings.TrimSpace(c[1]) + } + } } } return []InfoStat{ret}, nil diff --git a/cpu/cpu_darwin.go b/cpu/cpu_darwin.go index 41f395e5e..79a458b8e 100644 --- a/cpu/cpu_darwin.go +++ b/cpu/cpu_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package cpu diff --git a/cpu/cpu_darwin_cgo.go b/cpu/cpu_darwin_cgo.go index 1d5f0772e..3a02024c5 100644 --- a/cpu/cpu_darwin_cgo.go +++ b/cpu/cpu_darwin_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && cgo -// +build darwin,cgo package cpu diff --git a/cpu/cpu_darwin_nocgo.go b/cpu/cpu_darwin_nocgo.go index e067e99f9..1af8566a6 100644 --- a/cpu/cpu_darwin_nocgo.go +++ b/cpu/cpu_darwin_nocgo.go @@ -1,9 +1,9 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && !cgo -// +build darwin,!cgo package cpu -import "github.com/shirou/gopsutil/v3/internal/common" +import "github.com/shirou/gopsutil/v4/internal/common" func perCPUTimes() ([]TimesStat, error) { return []TimesStat{}, common.ErrNotImplementedError diff --git a/cpu/cpu_darwin_test.go b/cpu/cpu_darwin_test.go index a95862369..5548cf961 100644 --- a/cpu/cpu_darwin_test.go +++ b/cpu/cpu_darwin_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package cpu @@ -10,7 +10,7 @@ import ( "github.com/shoenig/go-m1cpu" ) -func Test_CpuInfo_AppleSilicon(t *testing.T) { +func TestInfo_AppleSilicon(t *testing.T) { if !m1cpu.IsAppleSilicon() { t.Skip("wrong cpu type") } diff --git a/cpu/cpu_dragonfly.go b/cpu/cpu_dragonfly.go index fef53e5dc..19b1e9dd3 100644 --- a/cpu/cpu_dragonfly.go +++ b/cpu/cpu_dragonfly.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( @@ -10,7 +11,7 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) diff --git a/cpu/cpu_dragonfly_amd64.go b/cpu/cpu_dragonfly_amd64.go index 57e14528d..25ececa68 100644 --- a/cpu/cpu_dragonfly_amd64.go +++ b/cpu/cpu_dragonfly_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_fallback.go b/cpu/cpu_fallback.go index 089f603c8..245c1ec98 100644 --- a/cpu/cpu_fallback.go +++ b/cpu/cpu_fallback.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !dragonfly && !plan9 && !aix -// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!solaris,!windows,!dragonfly,!plan9,!aix package cpu @@ -7,7 +7,7 @@ import ( "context" "runtime" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func Times(percpu bool) ([]TimesStat, error) { diff --git a/cpu/cpu_freebsd.go b/cpu/cpu_freebsd.go index d3f47353c..c68d6bff0 100644 --- a/cpu/cpu_freebsd.go +++ b/cpu/cpu_freebsd.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( @@ -10,7 +11,7 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) diff --git a/cpu/cpu_freebsd_386.go b/cpu/cpu_freebsd_386.go index 8b7f4c321..e4799bcf5 100644 --- a/cpu/cpu_freebsd_386.go +++ b/cpu/cpu_freebsd_386.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_freebsd_amd64.go b/cpu/cpu_freebsd_amd64.go index 57e14528d..25ececa68 100644 --- a/cpu/cpu_freebsd_amd64.go +++ b/cpu/cpu_freebsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_freebsd_arm.go b/cpu/cpu_freebsd_arm.go index 8b7f4c321..e4799bcf5 100644 --- a/cpu/cpu_freebsd_arm.go +++ b/cpu/cpu_freebsd_arm.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_freebsd_arm64.go b/cpu/cpu_freebsd_arm64.go index 57e14528d..25ececa68 100644 --- a/cpu/cpu_freebsd_arm64.go +++ b/cpu/cpu_freebsd_arm64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_freebsd_test.go b/cpu/cpu_freebsd_test.go index 27a709d31..33334f879 100644 --- a/cpu/cpu_freebsd_test.go +++ b/cpu/cpu_freebsd_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( @@ -5,7 +6,7 @@ import ( "runtime" "testing" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func TestParseDmesgBoot(t *testing.T) { diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index da467e2dd..f78c61a25 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package cpu @@ -13,7 +13,7 @@ import ( "github.com/tklauser/go-sysconf" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var ClocksPerSec = float64(100) diff --git a/cpu/cpu_linux_test.go b/cpu/cpu_linux_test.go index e06f30520..f67d07133 100644 --- a/cpu/cpu_linux_test.go +++ b/cpu/cpu_linux_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( @@ -20,7 +21,7 @@ func TestTimesEmpty(t *testing.T) { } } -func TestCPUparseStatLine_424(t *testing.T) { +func TestParseStatLine_424(t *testing.T) { t.Setenv("HOST_PROC", "testdata/linux/424/proc") { l, err := Times(true) @@ -38,7 +39,7 @@ func TestCPUparseStatLine_424(t *testing.T) { } } -func TestCPUCountsAgainstLscpu(t *testing.T) { +func TestCountsAgainstLscpu(t *testing.T) { cmd := exec.Command("lscpu") cmd.Env = []string{"LC_ALL=C"} out, err := cmd.Output() @@ -93,7 +94,7 @@ func TestCPUCountsAgainstLscpu(t *testing.T) { } } -func TestCPUCountsLogicalAndroid_1037(t *testing.T) { // https://github.com/shirou/gopsutil/issues/1037 +func TestCountsLogicalAndroid_1037(t *testing.T) { // https://github.com/shirou/gopsutil/issues/1037 t.Setenv("HOST_PROC", "testdata/linux/1037/proc") count, err := Counts(true) diff --git a/cpu/cpu_netbsd.go b/cpu/cpu_netbsd.go index 1f66be342..2cda5cd24 100644 --- a/cpu/cpu_netbsd.go +++ b/cpu/cpu_netbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd -// +build netbsd package cpu @@ -9,7 +9,7 @@ import ( "runtime" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) diff --git a/cpu/cpu_netbsd_amd64.go b/cpu/cpu_netbsd_amd64.go index 57e14528d..25ececa68 100644 --- a/cpu/cpu_netbsd_amd64.go +++ b/cpu/cpu_netbsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_netbsd_arm64.go b/cpu/cpu_netbsd_arm64.go index 57e14528d..25ececa68 100644 --- a/cpu/cpu_netbsd_arm64.go +++ b/cpu/cpu_netbsd_arm64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_openbsd.go b/cpu/cpu_openbsd.go index fe3329030..33233d3c7 100644 --- a/cpu/cpu_openbsd.go +++ b/cpu/cpu_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package cpu @@ -9,7 +9,7 @@ import ( "runtime" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) diff --git a/cpu/cpu_openbsd_386.go b/cpu/cpu_openbsd_386.go index 5e878399a..40a6f43e4 100644 --- a/cpu/cpu_openbsd_386.go +++ b/cpu/cpu_openbsd_386.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_openbsd_amd64.go b/cpu/cpu_openbsd_amd64.go index d659058cd..464156d54 100644 --- a/cpu/cpu_openbsd_amd64.go +++ b/cpu/cpu_openbsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_openbsd_arm.go b/cpu/cpu_openbsd_arm.go index 5e878399a..40a6f43e4 100644 --- a/cpu/cpu_openbsd_arm.go +++ b/cpu/cpu_openbsd_arm.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_openbsd_arm64.go b/cpu/cpu_openbsd_arm64.go index d659058cd..464156d54 100644 --- a/cpu/cpu_openbsd_arm64.go +++ b/cpu/cpu_openbsd_arm64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_openbsd_riscv64.go b/cpu/cpu_openbsd_riscv64.go index d659058cd..464156d54 100644 --- a/cpu/cpu_openbsd_riscv64.go +++ b/cpu/cpu_openbsd_riscv64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu type cpuTimes struct { diff --git a/cpu/cpu_plan9.go b/cpu/cpu_plan9.go index a2e99d8c0..bff2e0c75 100644 --- a/cpu/cpu_plan9.go +++ b/cpu/cpu_plan9.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build plan9 -// +build plan9 package cpu @@ -9,7 +9,7 @@ import ( "runtime" stats "github.com/lufia/plan9stats" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func Times(percpu bool) ([]TimesStat, error) { diff --git a/cpu/cpu_plan9_test.go b/cpu/cpu_plan9_test.go index 2820a3f41..9413e2aea 100644 --- a/cpu/cpu_plan9_test.go +++ b/cpu/cpu_plan9_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build plan9 -// +build plan9 package cpu diff --git a/cpu/cpu_solaris.go b/cpu/cpu_solaris.go index 4231ad168..d8ba1d324 100644 --- a/cpu/cpu_solaris.go +++ b/cpu/cpu_solaris.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( diff --git a/cpu/cpu_solaris_test.go b/cpu/cpu_solaris_test.go index dd9362c3a..527d98541 100644 --- a/cpu/cpu_solaris_test.go +++ b/cpu/cpu_solaris_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index 688660a1a..2e4dd30a4 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package cpu import ( @@ -10,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -19,7 +20,7 @@ func skipIfNotImplementedErr(t *testing.T, err error) { } } -func TestCpu_times(t *testing.T) { +func TestTimes(t *testing.T) { v, err := Times(false) skipIfNotImplementedErr(t, err) if err != nil { @@ -77,7 +78,7 @@ func TestCpu_times(t *testing.T) { } } -func TestCpu_counts(t *testing.T) { +func TestCounts(t *testing.T) { v, err := Counts(true) skipIfNotImplementedErr(t, err) if err != nil { @@ -98,7 +99,7 @@ func TestCpu_counts(t *testing.T) { t.Logf("physical cores: %d", v) } -func TestCPUTimeStat_String(t *testing.T) { +func TestTimeStat_String(t *testing.T) { v := TimesStat{ CPU: "cpu0", User: 100.1, @@ -111,7 +112,7 @@ func TestCPUTimeStat_String(t *testing.T) { } } -func TestCpuInfo(t *testing.T) { +func TestInfo(t *testing.T) { v, err := Info() skipIfNotImplementedErr(t, err) if err != nil { @@ -127,7 +128,7 @@ func TestCpuInfo(t *testing.T) { } } -func testCPUPercent(t *testing.T, percpu bool) { +func testPercent(t *testing.T, percpu bool) { numcpu := runtime.NumCPU() testCount := 3 @@ -161,7 +162,7 @@ func testCPUPercent(t *testing.T, percpu bool) { } } -func testCPUPercentLastUsed(t *testing.T, percpu bool) { +func testPercentLastUsed(t *testing.T, percpu bool) { numcpu := runtime.NumCPU() testCount := 10 @@ -195,18 +196,18 @@ func testCPUPercentLastUsed(t *testing.T, percpu bool) { } } -func TestCPUPercent(t *testing.T) { - testCPUPercent(t, false) +func TestPercent(t *testing.T) { + testPercent(t, false) } -func TestCPUPercentPerCpu(t *testing.T) { - testCPUPercent(t, true) +func TestPercentPerCpu(t *testing.T) { + testPercent(t, true) } -func TestCPUPercentIntervalZero(t *testing.T) { - testCPUPercentLastUsed(t, false) +func TestPercentIntervalZero(t *testing.T) { + testPercentLastUsed(t, false) } -func TestCPUPercentIntervalZeroPerCPU(t *testing.T) { - testCPUPercentLastUsed(t, true) +func TestPercentIntervalZeroPerCPU(t *testing.T) { + testPercentLastUsed(t, true) } diff --git a/cpu/cpu_windows.go b/cpu/cpu_windows.go index e10612fd1..4476b91cb 100644 --- a/cpu/cpu_windows.go +++ b/cpu/cpu_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package cpu @@ -8,14 +8,12 @@ import ( "fmt" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/yusufpapurcu/wmi" "golang.org/x/sys/windows" ) -var ( - procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") -) +var procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") type win32_Processor struct { Family uint16 diff --git a/cpu/testdata/aix/prtconf b/cpu/testdata/aix/prtconf new file mode 100644 index 000000000..7d4d93a97 --- /dev/null +++ b/cpu/testdata/aix/prtconf @@ -0,0 +1,68 @@ +System Model: IBM pSeries (emulated by qemu) +Machine Serial Number: Not Available +Processor Type: PowerPC_POWER8 +Processor Implementation Mode: POWER 8 +Processor Version: PV_8_Compat +Number Of Processors: 4 +Processor Clock Speed: 1000 MHz +CPU Type: 64-bit +Kernel Type: 64-bit +LPAR Info: 0 aix_7200-04-02-2027 +Memory Size: 4096 MB +Good Memory Size: 4096 MB +Platform Firmware level: Not Available +Firmware Version: SLOF,HEAD +Console Login: enable +Auto Restart: true +Full Core: false +NX Crypto Acceleration: Not Capable +In-Core Crypto Acceleration: Capable, but not Enabled + +en0 +Network Information + Host Name: aix72-dylan + IP Address: 192.168.124.53 + Sub Netmask: + Gateway: 192.168.124.1 + Name Server: + Domain Name: + +Paging Space Information + Total Paging Space: 512MB + Percent Used: 1% + +Volume Groups Information +============================================================================== +Active VGs +============================================================================== +rootvg: +PV_NAME PV STATE TOTAL PPs FREE PPs FREE DISTRIBUTION +hdisk0 active 999 809 199..193..17..200..200 +============================================================================== + +INSTALLED RESOURCE LIST + +The following resources are installed on the machine. ++/- = Added or deleted from Resource List. +* = Diagnostic support not available. + + Model Architecture: chrp + Model Implementation: Uni-Processor, PCI bus + ++ sys0 System Object ++ sysplanar0 System Planar +* vio0 Virtual I/O Bus +* ent0 Virtual I/O Ethernet Adapter (l-lan) +* vscsi0 Virtual SCSI Client Adapter +* cd0 Virtual SCSI Optical Served by VIO Server +* vsa0 LPAR Virtual Serial Adapter +* vty0 Asynchronous Terminal +* pci0 PCI Bus +* scsi0 qemu_virtio-scsi-pci:0000:00:02.0 Virtio SCSI Client Adapter (f41a0800) +* hdisk0 qemu_virtio-scsi-pci:0000:00:02.0-LW_0 MPIO Other Virtio SCSI Disk Drive ++ L2cache0 L2 Cache ++ mem0 Memory ++ proc0 Processor ++ proc1 Processor ++ proc2 Processor ++ proc3 Processor diff --git a/cpu/testdata/aix/sar-u-PALL101 b/cpu/testdata/aix/sar-u-PALL101 new file mode 100644 index 000000000..2a3dc63e6 --- /dev/null +++ b/cpu/testdata/aix/sar-u-PALL101 @@ -0,0 +1,11 @@ + +AIX aix72-dylan 2 7 000000000000 05/15/24 + +System configuration: lcpu=4 ent=4.00 mode=Capped + +11:19:03 cpu %usr %sys %wio %idle physc %entc +11:19:13 0 1 11 0 88 1.00 25.0 + 1 0 0 0 100 1.00 25.0 + 2 0 0 0 100 1.00 25.0 + 3 0 0 0 100 1.00 25.0 + - 0 3 0 97 4.00 100.0 diff --git a/cpu/testdata/aix/sar-u101 b/cpu/testdata/aix/sar-u101 new file mode 100644 index 000000000..e3dbb13f2 --- /dev/null +++ b/cpu/testdata/aix/sar-u101 @@ -0,0 +1,7 @@ + +AIX aix72-dylan 2 7 000000000000 05/15/24 + +System configuration: lcpu=4 ent=4.00 mode=Capped + +11:19:44 %usr %sys %wio %idle physc %entc +11:19:54 0 3 0 96 4.00 100.0 diff --git a/disk/disk.go b/disk/disk.go index 0d4b25345..310ea04f1 100644 --- a/disk/disk.go +++ b/disk/disk.go @@ -1,10 +1,11 @@ +// SPDX-License-Identifier: BSD-3-Clause package disk import ( "context" "encoding/json" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var invoke common.Invoker = common.Invoke{} diff --git a/disk/disk_aix.go b/disk/disk_aix.go index bc71712ea..3fe7fae39 100644 --- a/disk/disk_aix.go +++ b/disk/disk_aix.go @@ -1,22 +1,50 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix -// +build aix package disk import ( "context" + "errors" + "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { return nil, common.ErrNotImplementedError } -func SerialNumberWithContext(ctx context.Context, name string) (string, error) { +func LabelWithContext(ctx context.Context, name string) (string, error) { return "", common.ErrNotImplementedError } -func LabelWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError +// Using lscfg and a device name, we can get the device information +// This is a pure go implementation, and should be moved to disk_aix_nocgo.go +// if a more efficient CGO method is introduced in disk_aix_cgo.go +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + // This isn't linux, these aren't actual disk devices + if strings.HasPrefix(name, "/dev/") { + return "", errors.New("devices on /dev are not physical disks on aix") + } + out, err := invoke.CommandWithContext(ctx, "lscfg", "-vl", name) + if err != nil { + return "", err + } + + ret := "" + // Kind of inefficient, but it works + lines := strings.Split(string(out[:]), "\n") + for line := 1; line < len(lines); line++ { + v := strings.TrimSpace(lines[line]) + if strings.HasPrefix(v, "Serial Number...............") { + ret = strings.TrimPrefix(v, "Serial Number...............") + if ret == "" { + return "", errors.New("empty serial for disk") + } + return ret, nil + } + } + + return ret, errors.New("serial entry not found for disk") } diff --git a/disk/disk_aix_cgo.go b/disk/disk_aix_cgo.go index aa534df30..a0d0829f9 100644 --- a/disk/disk_aix_cgo.go +++ b/disk/disk_aix_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && cgo -// +build aix,cgo package disk diff --git a/disk/disk_aix_nocgo.go b/disk/disk_aix_nocgo.go index 17e2b9c84..e42732583 100644 --- a/disk/disk_aix_nocgo.go +++ b/disk/disk_aix_nocgo.go @@ -1,26 +1,29 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && !cgo -// +build aix,!cgo package disk import ( "context" "regexp" + "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) var startBlank = regexp.MustCompile(`^\s+`) -var ignoreFSType = map[string]bool{"procfs": true} -var FSType = map[int]string{ - 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", - 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", - 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", - 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", -} +var ( + ignoreFSType = map[string]bool{"procfs": true} + FSType = map[int]string{ + 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", + 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", + 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", + 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", + } +) func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { var ret []PartitionStat @@ -79,3 +82,108 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro func getFsType(stat unix.Statfs_t) string { return FSType[int(stat.Vfstype)] } + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + out, err := invoke.CommandWithContext(ctx, "df", "-v") + if err != nil { + return nil, err + } + + ret := &UsageStat{} + + blocksize := uint64(512) + lines := strings.Split(string(out), "\n") + if len(lines) < 2 { + return &UsageStat{}, common.ErrNotImplementedError + } + + hf := strings.Fields(strings.Replace(lines[0], "Mounted on", "Path", -1)) // headers + for line := 1; line < len(lines); line++ { + fs := strings.Fields(lines[line]) // values + for i, header := range hf { + // We're done in any of these use cases + if i >= len(fs) { + break + } + + switch header { + case `Filesystem`: + // This is not a valid fs for us to parse + if fs[i] == "/proc" || fs[i] == "/ahafs" || fs[i] != path { + break + } + + ret.Fstype, err = GetMountFSTypeWithContext(ctx, fs[i]) + if err != nil { + return nil, err + } + case `Path`: + ret.Path = fs[i] + case `512-blocks`: + total, err := strconv.ParseUint(fs[i], 10, 64) + ret.Total = total * blocksize + if err != nil { + return nil, err + } + case `Used`: + ret.Used, err = strconv.ParseUint(fs[i], 10, 64) + if err != nil { + return nil, err + } + case `Free`: + ret.Free, err = strconv.ParseUint(fs[i], 10, 64) + if err != nil { + return nil, err + } + case `%Used`: + val, err := strconv.Atoi(strings.Replace(fs[i], "%", "", -1)) + if err != nil { + return nil, err + } + ret.UsedPercent = float64(val) / float64(100) + case `Ifree`: + ret.InodesFree, err = strconv.ParseUint(fs[i], 10, 64) + if err != nil { + return nil, err + } + case `Iused`: + ret.InodesUsed, err = strconv.ParseUint(fs[i], 10, 64) + if err != nil { + return nil, err + } + case `%Iused`: + val, err := strconv.Atoi(strings.Replace(fs[i], "%", "", -1)) + if err != nil { + return nil, err + } + ret.InodesUsedPercent = float64(val) / float64(100) + } + } + + // Calculated value, since it isn't returned by the command + ret.InodesTotal = ret.InodesUsed + ret.InodesFree + + // Valid Usage data, so append it + return ret, nil + } + + return ret, nil +} + +func GetMountFSTypeWithContext(ctx context.Context, mp string) (string, error) { + out, err := invoke.CommandWithContext(ctx, "mount") + if err != nil { + return "", err + } + + // Kind of inefficient, but it works + lines := strings.Split(string(out[:]), "\n") + for line := 1; line < len(lines); line++ { + fields := strings.Fields(lines[line]) + if strings.TrimSpace(fields[0]) == mp { + return fields[2], nil + } + } + + return "", nil +} diff --git a/disk/disk_darwin.go b/disk/disk_darwin.go index 9362d9e5d..6ed7400e2 100644 --- a/disk/disk_darwin.go +++ b/disk/disk_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package disk @@ -8,7 +8,7 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) // PartitionsWithContext returns disk partition. diff --git a/disk/disk_darwin_cgo.go b/disk/disk_darwin_cgo.go index 27c24c922..3a98b61e5 100644 --- a/disk/disk_darwin_cgo.go +++ b/disk/disk_darwin_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && cgo && !ios -// +build darwin,cgo,!ios package disk @@ -14,12 +14,12 @@ import "C" import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { var buf [C.NDRIVE]C.DriveStats - n, err := C.gopsutil_v3_readdrivestat(&buf[0], C.int(len(buf))) + n, err := C.gopsutil_v4_readdrivestat(&buf[0], C.int(len(buf))) if err != nil { return nil, err } diff --git a/disk/disk_darwin_nocgo.go b/disk/disk_darwin_nocgo.go index 1f099b7ca..8d55ca314 100644 --- a/disk/disk_darwin_nocgo.go +++ b/disk/disk_darwin_nocgo.go @@ -1,12 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build (darwin && !cgo) || ios -// +build darwin,!cgo ios package disk import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { diff --git a/disk/disk_fallback.go b/disk/disk_fallback.go index 36525f694..17f0f7bf4 100644 --- a/disk/disk_fallback.go +++ b/disk/disk_fallback.go @@ -1,12 +1,12 @@ -//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !windows && !solaris && !aix -// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!windows,!solaris,!aix +// SPDX-License-Identifier: BSD-3-Clause +//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !windows && !solaris && !aix package disk import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { diff --git a/disk/disk_freebsd.go b/disk/disk_freebsd.go index 9b53106c2..10006febf 100644 --- a/disk/disk_freebsd.go +++ b/disk/disk_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd -// +build freebsd package disk @@ -12,7 +12,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) diff --git a/disk/disk_freebsd_386.go b/disk/disk_freebsd_386.go index 7fa1783dc..4660b1451 100644 --- a/disk/disk_freebsd_386.go +++ b/disk/disk_freebsd_386.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/disk/disk_freebsd_amd64.go b/disk/disk_freebsd_amd64.go index d86a308be..3f4363172 100644 --- a/disk/disk_freebsd_amd64.go +++ b/disk/disk_freebsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/disk/disk_freebsd_arm.go b/disk/disk_freebsd_arm.go index 7fa1783dc..4660b1451 100644 --- a/disk/disk_freebsd_arm.go +++ b/disk/disk_freebsd_arm.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/disk/disk_freebsd_arm64.go b/disk/disk_freebsd_arm64.go index f6b3f80df..15fae4192 100644 --- a/disk/disk_freebsd_arm64.go +++ b/disk/disk_freebsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd && arm64 -// +build freebsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs disk/types_freebsd.go diff --git a/disk/disk_linux.go b/disk/disk_linux.go index ada9f9e76..e94d2124b 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package disk @@ -16,7 +16,7 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) const ( diff --git a/disk/disk_netbsd.go b/disk/disk_netbsd.go index d313737e5..b376f8769 100644 --- a/disk/disk_netbsd.go +++ b/disk/disk_netbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd -// +build netbsd package disk @@ -7,7 +7,7 @@ import ( "context" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) diff --git a/disk/disk_netbsd_amd64.go b/disk/disk_netbsd_amd64.go index c21421cfe..c4b903f60 100644 --- a/disk/disk_netbsd_amd64.go +++ b/disk/disk_netbsd_amd64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd && amd64 -// +build netbsd,amd64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_netbsd.go diff --git a/disk/disk_netbsd_arm64.go b/disk/disk_netbsd_arm64.go index dfe48f812..d01c864e7 100644 --- a/disk/disk_netbsd_arm64.go +++ b/disk/disk_netbsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd && arm64 -// +build netbsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_netbsd.go diff --git a/disk/disk_openbsd.go b/disk/disk_openbsd.go index 81ff23994..713e38e1d 100644 --- a/disk/disk_openbsd.go +++ b/disk/disk_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package disk @@ -8,7 +8,7 @@ import ( "context" "encoding/binary" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) diff --git a/disk/disk_openbsd_386.go b/disk/disk_openbsd_386.go index f4c139f5e..66e1795b5 100644 --- a/disk/disk_openbsd_386.go +++ b/disk/disk_openbsd_386.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && 386 -// +build openbsd,386 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs disk/types_openbsd.go @@ -34,5 +34,7 @@ type Timeval struct { Usec int32 } -type Diskstat struct{} -type bintime struct{} +type ( + Diskstat struct{} + bintime struct{} +) diff --git a/disk/disk_openbsd_amd64.go b/disk/disk_openbsd_amd64.go index c1bd52ef8..9070ff0d6 100644 --- a/disk/disk_openbsd_amd64.go +++ b/disk/disk_openbsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_openbsd.go @@ -32,5 +33,7 @@ type Timeval struct { Usec int64 } -type Diskstat struct{} -type bintime struct{} +type ( + Diskstat struct{} + bintime struct{} +) diff --git a/disk/disk_openbsd_arm.go b/disk/disk_openbsd_arm.go index 86054a626..f23a293db 100644 --- a/disk/disk_openbsd_arm.go +++ b/disk/disk_openbsd_arm.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm -// +build openbsd,arm // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs disk/types_openbsd.go @@ -34,5 +34,7 @@ type Timeval struct { Usec int32 } -type Diskstat struct{} -type bintime struct{} +type ( + Diskstat struct{} + bintime struct{} +) diff --git a/disk/disk_openbsd_arm64.go b/disk/disk_openbsd_arm64.go index ae1cf57e1..465296e79 100644 --- a/disk/disk_openbsd_arm64.go +++ b/disk/disk_openbsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm64 -// +build openbsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs disk/types_openbsd.go @@ -34,5 +34,7 @@ type Timeval struct { Usec int64 } -type Diskstat struct{} -type bintime struct{} +type ( + Diskstat struct{} + bintime struct{} +) diff --git a/disk/disk_openbsd_riscv64.go b/disk/disk_openbsd_riscv64.go index 8374b94eb..3620c1662 100644 --- a/disk/disk_openbsd_riscv64.go +++ b/disk/disk_openbsd_riscv64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && riscv64 -// +build openbsd,riscv64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs disk/types_openbsd.go @@ -36,5 +36,7 @@ type ( } ) -type Diskstat struct{} -type bintime struct{} +type ( + Diskstat struct{} + bintime struct{} +) diff --git a/disk/disk_solaris.go b/disk/disk_solaris.go index 5d6ea8653..f849da96b 100644 --- a/disk/disk_solaris.go +++ b/disk/disk_solaris.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build solaris -// +build solaris package disk @@ -16,7 +16,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) diff --git a/disk/disk_test.go b/disk/disk_test.go index 5adae5ca3..534577c4a 100644 --- a/disk/disk_test.go +++ b/disk/disk_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package disk import ( @@ -7,7 +8,7 @@ import ( "sync" "testing" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -16,7 +17,7 @@ func skipIfNotImplementedErr(t *testing.T, err error) { } } -func TestDisk_usage(t *testing.T) { +func TestUsage(t *testing.T) { path := "/" if runtime.GOOS == "windows" { path = "C:" @@ -31,7 +32,7 @@ func TestDisk_usage(t *testing.T) { } } -func TestDisk_partitions(t *testing.T) { +func TestPartitions(t *testing.T) { ret, err := Partitions(false) skipIfNotImplementedErr(t, err) if err != nil || len(ret) == 0 { @@ -49,7 +50,7 @@ func TestDisk_partitions(t *testing.T) { } } -func TestDisk_io_counters(t *testing.T) { +func TestIOCounters(t *testing.T) { ret, err := IOCounters() skipIfNotImplementedErr(t, err) if err != nil { @@ -68,7 +69,7 @@ func TestDisk_io_counters(t *testing.T) { } // https://github.com/shirou/gopsutil/issues/560 regression test -func TestDisk_io_counters_concurrency_on_darwin_cgo(t *testing.T) { +func TestIOCounters_concurrency_on_darwin_cgo(t *testing.T) { if runtime.GOOS != "darwin" { t.Skip("darwin only") } @@ -84,7 +85,7 @@ func TestDisk_io_counters_concurrency_on_darwin_cgo(t *testing.T) { wg.Wait() } -func TestDiskUsageStat_String(t *testing.T) { +func TestUsageStat_String(t *testing.T) { v := UsageStat{ Path: "/", Total: 1000, @@ -103,7 +104,7 @@ func TestDiskUsageStat_String(t *testing.T) { } } -func TestDiskPartitionStat_String(t *testing.T) { +func TestPartitionStat_String(t *testing.T) { v := PartitionStat{ Device: "sd01", Mountpoint: "/", @@ -116,7 +117,7 @@ func TestDiskPartitionStat_String(t *testing.T) { } } -func TestDiskIOCountersStat_String(t *testing.T) { +func TestIOCountersStat_String(t *testing.T) { v := IOCountersStat{ Name: "sd01", ReadCount: 100, diff --git a/disk/disk_unix.go b/disk/disk_unix.go index 1e7352408..d69d83817 100644 --- a/disk/disk_unix.go +++ b/disk/disk_unix.go @@ -1,5 +1,5 @@ -//go:build freebsd || linux || darwin || (aix && !cgo) -// +build freebsd linux darwin aix,!cgo +// SPDX-License-Identifier: BSD-3-Clause +//go:build freebsd || linux || darwin package disk diff --git a/disk/disk_windows.go b/disk/disk_windows.go index e17db3e5b..86d6a4e9d 100644 --- a/disk/disk_windows.go +++ b/disk/disk_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package disk @@ -10,7 +10,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" ) diff --git a/disk/iostat_darwin.c b/disk/iostat_darwin.c index 8aab04f60..ba1e4c505 100644 --- a/disk/iostat_darwin.c +++ b/disk/iostat_darwin.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-FileCopyrightText: Copyright (c) 2017, kadota kyohei // https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.c #include #include @@ -16,7 +18,7 @@ static int getdrivestat(io_registry_entry_t d, DriveStats *stat); static int fillstat(io_registry_entry_t d, DriveStats *stat); int -gopsutil_v3_readdrivestat(DriveStats a[], int n) +gopsutil_v4_readdrivestat(DriveStats a[], int n) { CFMutableDictionaryRef match; io_iterator_t drives; diff --git a/disk/iostat_darwin.h b/disk/iostat_darwin.h index cb9ec7a0a..7b702aaa0 100644 --- a/disk/iostat_darwin.h +++ b/disk/iostat_darwin.h @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-FileCopyrightText: Copyright (c) 2017, kadota kyohei // https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.h typedef struct DriveStats DriveStats; typedef struct CPUStats CPUStats; @@ -29,4 +31,4 @@ struct CPUStats { natural_t idle; }; -extern int gopsutil_v3_readdrivestat(DriveStats a[], int n); +extern int gopsutil_v4_readdrivestat(DriveStats a[], int n); diff --git a/disk/types_freebsd.go b/disk/types_freebsd.go index 47f55513a..6fc14fe7c 100644 --- a/disk/types_freebsd.go +++ b/disk/types_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // Hand writing: _Ctype_struct___0 diff --git a/disk/types_netbsd.go b/disk/types_netbsd.go index c0326f5c2..63a6aec90 100644 --- a/disk/types_netbsd.go +++ b/disk/types_netbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // Hand writing: _Ctype_struct___0 diff --git a/disk/types_openbsd.go b/disk/types_openbsd.go index abb43c806..2329fb985 100644 --- a/disk/types_openbsd.go +++ b/disk/types_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // Hand writing: _Ctype_struct___0 diff --git a/doc.go b/doc.go index 6a65fe268..fc471f694 100644 --- a/doc.go +++ b/doc.go @@ -1 +1,2 @@ +// SPDX-License-Identifier: BSD-3-Clause package gopsutil diff --git a/docker/docker.go b/docker/docker.go index dda7ba00a..1c0abca8a 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -1,11 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause package docker import ( "encoding/json" "errors" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" ) var ( diff --git a/docker/docker_linux.go b/docker/docker_linux.go index 4904874d0..f3409d953 100644 --- a/docker/docker_linux.go +++ b/docker/docker_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package docker @@ -13,8 +13,8 @@ import ( "strconv" "strings" - cpu "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" + cpu "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" ) // GetDockerStat returns a list of Docker basic stats. diff --git a/docker/docker_linux_test.go b/docker/docker_linux_test.go index 5ef80f932..2d0f35b03 100644 --- a/docker/docker_linux_test.go +++ b/docker/docker_linux_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package docker diff --git a/docker/docker_notlinux.go b/docker/docker_notlinux.go index 434ca12aa..ca7a7f914 100644 --- a/docker/docker_notlinux.go +++ b/docker/docker_notlinux.go @@ -1,12 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build !linux -// +build !linux package docker import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) // GetDockerStat returns a list of Docker basic stats. diff --git a/docker/main_test.go b/docker/main_test.go index 1d6e6bfe0..14ee18689 100644 --- a/docker/main_test.go +++ b/docker/main_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package docker import ( diff --git a/go.mod b/go.mod index aa8157a53..c5ed8bdc7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ -module github.com/shirou/gopsutil/v3 +module github.com/shirou/gopsutil/v4 -go 1.15 +go 1.18 require ( github.com/google/go-cmp v0.6.0 @@ -13,4 +13,18 @@ require ( golang.org/x/sys v0.20.0 ) -retract v3.22.11 +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index 1c0a78124..64e81120b 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,8 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= @@ -16,14 +14,6 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:Om github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -41,6 +31,5 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/host/host.go b/host/host.go index ee9486369..b69d2f624 100644 --- a/host/host.go +++ b/host/host.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package host import ( @@ -8,7 +9,7 @@ import ( "runtime" "time" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) type Warnings = common.Warnings @@ -40,13 +41,6 @@ type UserStat struct { Started int `json:"started"` } -type TemperatureStat struct { - SensorKey string `json:"sensorKey"` - Temperature float64 `json:"temperature"` - High float64 `json:"sensorHigh"` - Critical float64 `json:"sensorCritical"` -} - func (h InfoStat) String() string { s, _ := json.Marshal(h) return string(s) @@ -57,11 +51,6 @@ func (u UserStat) String() string { return string(s) } -func (t TemperatureStat) String() string { - s, _ := json.Marshal(t) - return string(s) -} - var enableBootTimeCache bool // EnableBootTimeCache change cache behavior of BootTime. If true, cache BootTime value. Default is false. @@ -157,10 +146,6 @@ func KernelVersion() (string, error) { return KernelVersionWithContext(context.Background()) } -func SensorsTemperatures() ([]TemperatureStat, error) { - return SensorsTemperaturesWithContext(context.Background()) -} - func timeSince(ts uint64) uint64 { return uint64(time.Now().Unix()) - ts } diff --git a/host/host_aix.go b/host/host_aix.go new file mode 100644 index 000000000..7d66666e5 --- /dev/null +++ b/host/host_aix.go @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build aix + +package host + +import ( + "context" + "errors" + "strconv" + "strings" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +// from https://www.ibm.com/docs/en/aix/7.2?topic=files-utmph-file +const ( + user_PROCESS = 7 +) + +func HostIDWithContext(ctx context.Context) (string, error) { + out, err := invoke.CommandWithContext(ctx, "uname", "-u") + if err != nil { + return "", err + } + + // The command always returns an extra newline, so we make use of Split() to get only the first line + return strings.Split(string(out[:]), "\n")[0], nil +} + +func numProcs(ctx context.Context) (uint64, error) { + return 0, common.ErrNotImplementedError +} + +func BootTimeWithContext(ctx context.Context) (btime uint64, err error) { + ut, err := UptimeWithContext(ctx) + if err != nil { + return 0, err + } + + if ut <= 0 { + return 0, errors.New("Uptime was not set, so cannot calculate boot time from it.") + } + + ut = ut * 60 + return timeSince(ut), nil +} + +// This function takes multiple formats of output frmo the uptime +// command and converts the data into minutes. +// Some examples of uptime output that this command handles: +// 11:54AM up 13 mins, 1 user, load average: 2.78, 2.62, 1.79 +// 12:41PM up 1 hr, 1 user, load average: 2.47, 2.85, 2.83 +// 07:43PM up 5 hrs, 1 user, load average: 3.27, 2.91, 2.72 +// 11:18:23 up 83 days, 18:29, 4 users, load average: 0.16, 0.03, 0.01 +func UptimeWithContext(ctx context.Context) (uint64, error) { + out, err := invoke.CommandWithContext(ctx, "uptime") + if err != nil { + return 0, err + } + + // Convert our uptime to a series of fields we can extract + ut := strings.Fields(string(out[:])) + + // Convert the second field value to integer + var days uint64 = 0 + var hours uint64 = 0 + var minutes uint64 = 0 + if ut[3] == "day," || ut[3] == "days," { + days, err = strconv.ParseUint(ut[2], 10, 64) + if err != nil { + return 0, err + } + + // Split field 4 into hours and minutes + hm := strings.Split(ut[4], ":") + hours, err = strconv.ParseUint(hm[0], 10, 64) + if err != nil { + return 0, err + } + minutes, err = strconv.ParseUint(strings.Replace(hm[1], ",", "", -1), 10, 64) + if err != nil { + return 0, err + } + } else if ut[3] == "hr," || ut[3] == "hrs," { + hours, err = strconv.ParseUint(ut[2], 10, 64) + if err != nil { + return 0, err + } + } else if ut[3] == "mins," { + minutes, err = strconv.ParseUint(ut[2], 10, 64) + if err != nil { + return 0, err + } + } else if _, err := strconv.ParseInt(ut[3], 10, 64); err == nil && strings.Contains(ut[2], ":") { + // Split field 2 into hours and minutes + hm := strings.Split(ut[2], ":") + hours, err = strconv.ParseUint(hm[0], 10, 64) + if err != nil { + return 0, err + } + minutes, err = strconv.ParseUint(strings.Replace(hm[1], ",", "", -1), 10, 64) + if err != nil { + return 0, err + } + } + + // Stack them all together as minutes + total_time := (days * 24 * 60) + (hours * 60) + minutes + + return total_time, nil +} + +// This is a weak implementation due to the limitations on retrieving this data in AIX +func UsersWithContext(ctx context.Context) ([]UserStat, error) { + var ret []UserStat + out, err := invoke.CommandWithContext(ctx, "w") + if err != nil { + return nil, err + } + lines := strings.Split(string(out), "\n") + if len(lines) < 3 { + return []UserStat{}, common.ErrNotImplementedError + } + + hf := strings.Fields(lines[1]) // headers + for l := 2; l < len(lines); l++ { + v := strings.Fields(lines[l]) // values + us := &UserStat{} + for i, header := range hf { + // We're done in any of these use cases + if i >= len(v) || v[0] == "-" { + break + } + + if t, err := strconv.ParseFloat(v[i], 64); err == nil { + switch header { + case `User`: + us.User = strconv.FormatFloat(t, 'f', 1, 64) + case `tty`: + us.Terminal = strconv.FormatFloat(t, 'f', 1, 64) + } + } + } + + // Valid User data, so append it + ret = append(ret, *us) + } + + return ret, nil +} + +// Much of this function could be static. However, to be future proofed, I've made it call the OS for the information in all instances. +func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) { + // Set the platform (which should always, and only be, "AIX") from `uname -s` + out, err := invoke.CommandWithContext(ctx, "uname", "-s") + if err != nil { + return "", "", "", err + } + platform = strings.TrimRight(string(out[:]), "\n") + + // Set the family + family = strings.TrimRight(string(out[:]), "\n") + + // Set the version + out, err = invoke.CommandWithContext(ctx, "oslevel") + if err != nil { + return "", "", "", err + } + version = strings.TrimRight(string(out[:]), "\n") + + return platform, family, version, nil +} + +func KernelVersionWithContext(ctx context.Context) (version string, err error) { + out, err := invoke.CommandWithContext(ctx, "oslevel", "-s") + if err != nil { + return "", err + } + version = strings.TrimRight(string(out[:]), "\n") + + return version, nil +} + +func KernelArch() (arch string, err error) { + out, err := invoke.Command("bootinfo", "-y") + if err != nil { + return "", err + } + arch = strings.TrimRight(string(out[:]), "\n") + + return arch, nil +} + +func VirtualizationWithContext(ctx context.Context) (string, string, error) { + return "", "", common.ErrNotImplementedError +} diff --git a/host/host_aix_ppc64.go b/host/host_aix_ppc64.go new file mode 100644 index 000000000..de9674b73 --- /dev/null +++ b/host/host_aix_ppc64.go @@ -0,0 +1,48 @@ +//go:build aix && ppc64 && cgo +// +build aix,ppc64,cgo + +// Guessed at from the following document: +// https://www.ibm.com/docs/sl/ibm-mq/9.2?topic=platforms-standard-data-types-aix-linux-windows + +package host + +const ( + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 + sizeOfUtmp = 0x180 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type utmp struct { + Type int16 + Pad_cgo_0 [2]byte + Pid int32 + Line [32]int8 + Id [4]int8 + User [32]int8 + Host [256]int8 + Exit exit_status + Session int32 + Tv timeval + Addr_v6 [4]int32 + X__glibc_reserved [20]int8 +} + +type exit_status struct { + Termination int16 + Exit int16 +} + +type timeval struct { + Sec int64 + Usec int64 +} diff --git a/host/host_bsd.go b/host/host_bsd.go index f9a296148..b67f8fb6e 100644 --- a/host/host_bsd.go +++ b/host/host_bsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin || freebsd || openbsd || netbsd -// +build darwin freebsd openbsd netbsd package host diff --git a/host/host_darwin.go b/host/host_darwin.go index 873ed4aee..068f1060a 100644 --- a/host/host_darwin.go +++ b/host/host_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package host @@ -15,8 +15,8 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/process" ) // from utmpx.h diff --git a/host/host_darwin_amd64.go b/host/host_darwin_amd64.go index 8caeed2e8..1efc353aa 100644 --- a/host/host_darwin_amd64.go +++ b/host/host_darwin_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_darwin.go diff --git a/host/host_darwin_arm64.go b/host/host_darwin_arm64.go index 293bd4df8..512e56970 100644 --- a/host/host_darwin_arm64.go +++ b/host/host_darwin_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && arm64 -// +build darwin,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_darwin.go diff --git a/host/host_darwin_nocgo.go b/host/host_darwin_nocgo.go deleted file mode 100644 index 6285ba94d..000000000 --- a/host/host_darwin_nocgo.go +++ /dev/null @@ -1,14 +0,0 @@ -//go:build darwin && !cgo -// +build darwin,!cgo - -package host - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} diff --git a/host/host_fallback.go b/host/host_fallback.go index a393ca15d..bc8397909 100644 --- a/host/host_fallback.go +++ b/host/host_fallback.go @@ -1,12 +1,12 @@ -//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows -// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!solaris,!windows +// SPDX-License-Identifier: BSD-3-Clause +//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !aix package host import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func HostIDWithContext(ctx context.Context) (string, error) { @@ -41,10 +41,6 @@ func PlatformInformationWithContext(ctx context.Context) (string, string, string return "", "", "", common.ErrNotImplementedError } -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - func KernelArch() (string, error) { return "", common.ErrNotImplementedError } diff --git a/host/host_freebsd.go b/host/host_freebsd.go index 9a5382d39..97aa05a14 100644 --- a/host/host_freebsd.go +++ b/host/host_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd -// +build freebsd package host @@ -13,8 +13,8 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/process" "golang.org/x/sys/unix" ) @@ -141,10 +141,6 @@ func getUsersFromUtmp(utmpfile string) ([]UserStat, error) { return ret, nil } -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - func KernelVersionWithContext(ctx context.Context) (string, error) { _, _, version, err := PlatformInformationWithContext(ctx) return version, err diff --git a/host/host_freebsd_386.go b/host/host_freebsd_386.go index 88453d2a2..0d31eb113 100644 --- a/host/host_freebsd_386.go +++ b/host/host_freebsd_386.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_freebsd.go diff --git a/host/host_freebsd_amd64.go b/host/host_freebsd_amd64.go index 8af74b0fe..603a0ba50 100644 --- a/host/host_freebsd_amd64.go +++ b/host/host_freebsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_freebsd.go diff --git a/host/host_freebsd_arm.go b/host/host_freebsd_arm.go index f7d6ede55..5021f5e1b 100644 --- a/host/host_freebsd_arm.go +++ b/host/host_freebsd_arm.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs types_freebsd.go diff --git a/host/host_freebsd_arm64.go b/host/host_freebsd_arm64.go index 41bec3c11..4fe188b33 100644 --- a/host/host_freebsd_arm64.go +++ b/host/host_freebsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd && arm64 -// +build freebsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_freebsd.go diff --git a/host/host_linux.go b/host/host_linux.go index 5d4c1a90f..04bda6c98 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package host @@ -10,14 +10,12 @@ import ( "fmt" "io" "os" - "path/filepath" "regexp" - "strconv" "strings" "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) type lsbStruct struct { @@ -30,8 +28,6 @@ type lsbStruct struct { // from utmp.h const ( user_PROCESS = 7 - - hostTemperatureScale = 1000.0 ) func HostIDWithContext(ctx context.Context) (string, error) { @@ -392,147 +388,3 @@ func getSusePlatform(contents []string) string { func VirtualizationWithContext(ctx context.Context) (string, string, error) { return common.VirtualizationWithContext(ctx) } - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - 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.HostSysWithContext(ctx, "/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 - if files, err = filepath.Glob(common.HostSysWithContext(ctx, "/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 - files, err = filepath.Glob(common.HostSysWithContext(ctx, "/class/thermal/thermal_zone*/")) - if err != nil { - return temperatures, err - } - for _, file := range files { - // Get the name of the temperature you are reading - name, err := os.ReadFile(filepath.Join(file, "type")) - if err != nil { - warns.Add(err) - continue - } - // Get the temperature reading - current, err := os.ReadFile(filepath.Join(file, "temp")) - if err != nil { - warns.Add(err) - continue - } - temperature, err := strconv.ParseInt(strings.TrimSpace(string(current)), 10, 64) - if err != nil { - warns.Add(err) - continue - } - - temperatures = append(temperatures, TemperatureStat{ - SensorKey: strings.TrimSpace(string(name)), - Temperature: float64(temperature) / 1000.0, - }) - } - 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 - // power/ temp1_label temp2_label temp3_label temp4_label temp5_label temp6_label temp7_label - // 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 { - 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 /temp1 - basepath := filepath.Join(directory, basename) - - // Get the label of the temperature you are reading - label := "" - - if raw, _ = os.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 - if raw, err = os.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 - if raw, err = os.ReadFile(file); err != nil { - warns.Add(err) - continue - } - - if temperature, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { - warns.Add(err) - continue - } - - // Add discovered temperature sensor to the list - temperatures = append(temperatures, TemperatureStat{ - 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 = os.ReadFile(filename); err != nil { - return 0 - } - - if value, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { - return 0 - } - - return value -} diff --git a/host/host_linux_386.go b/host/host_linux_386.go index 46e0c5d5a..3e241b104 100644 --- a/host/host_linux_386.go +++ b/host/host_linux_386.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // ATTENTION - FILE MANUAL FIXED AFTER CGO. // Fixed line: Tv _Ctype_struct_timeval -> Tv UtTv // Created by cgo -godefs, MANUAL FIXED diff --git a/host/host_linux_amd64.go b/host/host_linux_amd64.go index 1e574482f..480e72d3b 100644 --- a/host/host_linux_amd64.go +++ b/host/host_linux_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_arm.go b/host/host_linux_arm.go index 7abbbb8a3..1b7ee978a 100644 --- a/host/host_linux_arm.go +++ b/host/host_linux_arm.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go | sed "s/uint8/int8/g" diff --git a/host/host_linux_arm64.go b/host/host_linux_arm64.go index cd0b4ddcf..0e6fc8b76 100644 --- a/host/host_linux_arm64.go +++ b/host/host_linux_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause // Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs types_linux.go package host diff --git a/host/host_linux_loong64.go b/host/host_linux_loong64.go index edf1be597..c4c8390f3 100644 --- a/host/host_linux_loong64.go +++ b/host/host_linux_loong64.go @@ -1,8 +1,8 @@ +// SPDX-License-Identifier: BSD-3-Clause // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_linux.go //go:build linux && loong64 -// +build linux,loong64 package host diff --git a/host/host_linux_mips.go b/host/host_linux_mips.go index 50207e5bc..8aa049cae 100644 --- a/host/host_linux_mips.go +++ b/host/host_linux_mips.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_mips64.go b/host/host_linux_mips64.go index 50207e5bc..8aa049cae 100644 --- a/host/host_linux_mips64.go +++ b/host/host_linux_mips64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_mips64le.go b/host/host_linux_mips64le.go index 50207e5bc..8aa049cae 100644 --- a/host/host_linux_mips64le.go +++ b/host/host_linux_mips64le.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_mipsle.go b/host/host_linux_mipsle.go index 50207e5bc..8aa049cae 100644 --- a/host/host_linux_mipsle.go +++ b/host/host_linux_mipsle.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_ppc64.go b/host/host_linux_ppc64.go index 5b324effa..23f5cb9d8 100644 --- a/host/host_linux_ppc64.go +++ b/host/host_linux_ppc64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux && ppc64 -// +build linux,ppc64 // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_ppc64le.go b/host/host_linux_ppc64le.go index 51f5bee11..e81f12392 100644 --- a/host/host_linux_ppc64le.go +++ b/host/host_linux_ppc64le.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux && ppc64le -// +build linux,ppc64le // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_riscv64.go b/host/host_linux_riscv64.go index bb03a0b39..080fdb8dc 100644 --- a/host/host_linux_riscv64.go +++ b/host/host_linux_riscv64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_s390x.go b/host/host_linux_s390x.go index 6ea432a61..738af6018 100644 --- a/host/host_linux_s390x.go +++ b/host/host_linux_s390x.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux && s390x -// +build linux,s390x // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_linux.go diff --git a/host/host_linux_test.go b/host/host_linux_test.go index c114ec795..84763abb7 100644 --- a/host/host_linux_test.go +++ b/host/host_linux_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package host @@ -7,7 +7,7 @@ import ( "context" "testing" - "github.com/shirou/gopsutil/v3/common" + "github.com/shirou/gopsutil/v4/common" ) func TestGetRedhatishVersion(t *testing.T) { @@ -64,7 +64,7 @@ func TestGetRedhatishPlatform(t *testing.T) { } } -func Test_getlsbStruct(t *testing.T) { +func TestGetlsbStruct(t *testing.T) { cases := []struct { root string id string diff --git a/host/host_netbsd.go b/host/host_netbsd.go index 488f1dfc2..f3cddb7be 100644 --- a/host/host_netbsd.go +++ b/host/host_netbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd -// +build netbsd package host @@ -7,7 +7,7 @@ import ( "context" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) @@ -45,10 +45,6 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { return ret, common.ErrNotImplementedError } -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - func KernelVersionWithContext(ctx context.Context) (string, error) { _, _, version, err := PlatformInformationWithContext(ctx) return version, err diff --git a/host/host_openbsd.go b/host/host_openbsd.go index 325015c23..f21c5e859 100644 --- a/host/host_openbsd.go +++ b/host/host_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package host @@ -12,8 +12,8 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/process" "golang.org/x/sys/unix" ) @@ -95,10 +95,6 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { return ret, nil } -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - func KernelVersionWithContext(ctx context.Context) (string, error) { _, _, version, err := PlatformInformationWithContext(ctx) return version, err diff --git a/host/host_openbsd_386.go b/host/host_openbsd_386.go index b299d7ae4..df820a4ab 100644 --- a/host/host_openbsd_386.go +++ b/host/host_openbsd_386.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && 386 -// +build openbsd,386 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_openbsd.go diff --git a/host/host_openbsd_amd64.go b/host/host_openbsd_amd64.go index 2d23b9b71..b1d674e8c 100644 --- a/host/host_openbsd_amd64.go +++ b/host/host_openbsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_openbsd.go diff --git a/host/host_openbsd_arm.go b/host/host_openbsd_arm.go index f0ac57d0b..e5f1590fe 100644 --- a/host/host_openbsd_arm.go +++ b/host/host_openbsd_arm.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm -// +build openbsd,arm // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_openbsd.go diff --git a/host/host_openbsd_arm64.go b/host/host_openbsd_arm64.go index 20fb42dd7..d8c1061f7 100644 --- a/host/host_openbsd_arm64.go +++ b/host/host_openbsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm64 -// +build openbsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_openbsd.go diff --git a/host/host_openbsd_riscv64.go b/host/host_openbsd_riscv64.go index 7a123b649..584004b2f 100644 --- a/host/host_openbsd_riscv64.go +++ b/host/host_openbsd_riscv64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && riscv64 -// +build openbsd,riscv64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs host/types_openbsd.go diff --git a/host/host_posix.go b/host/host_posix.go index e7e0d837f..91ab6aee8 100644 --- a/host/host_posix.go +++ b/host/host_posix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux || freebsd || openbsd || netbsd || darwin || solaris -// +build linux freebsd openbsd netbsd darwin solaris package host diff --git a/host/host_solaris.go b/host/host_solaris.go index fef67f835..371cc98e8 100644 --- a/host/host_solaris.go +++ b/host/host_solaris.go @@ -1,18 +1,19 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build solaris + package host import ( "bufio" "bytes" "context" - "encoding/csv" "fmt" - "io" "os" "regexp" "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func HostIDWithContext(ctx context.Context) (string, error) { @@ -94,43 +95,6 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { return []UserStat{}, common.ErrNotImplementedError } -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - var ret []TemperatureStat - - out, err := invoke.CommandWithContext(ctx, "ipmitool", "-c", "sdr", "list") - if err != nil { - return ret, err - } - - r := csv.NewReader(strings.NewReader(string(out))) - // Output may contain errors, e.g. "bmc_send_cmd: Permission denied", don't expect a consistent number of records - r.FieldsPerRecord = -1 - for { - record, err := r.Read() - if err == io.EOF { - break - } - if err != nil { - return ret, err - } - // CPU1 Temp,40,degrees C,ok - if len(record) < 3 || record[1] == "" || record[2] != "degrees C" { - continue - } - v, err := strconv.ParseFloat(record[1], 64) - if err != nil { - return ret, err - } - ts := TemperatureStat{ - SensorKey: strings.TrimSuffix(record[0], " Temp"), - Temperature: v, - } - ret = append(ret, ts) - } - - return ret, nil -} - func VirtualizationWithContext(ctx context.Context) (string, string, error) { return "", "", common.ErrNotImplementedError } diff --git a/host/host_test.go b/host/host_test.go index d3b75859e..24b137121 100644 --- a/host/host_test.go +++ b/host/host_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package host import ( @@ -7,7 +8,7 @@ import ( "sync" "testing" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -16,7 +17,19 @@ func skipIfNotImplementedErr(t *testing.T, err error) { } } -func TestHostInfo(t *testing.T) { +func TestHostID(t *testing.T) { + v, err := HostID() + skipIfNotImplementedErr(t, err) + if err != nil { + t.Errorf("error %v", err) + } + if v == "" { + t.Errorf("Could not get host id %v", v) + } + t.Log(v) +} + +func TestInfo(t *testing.T) { v, err := Info() skipIfNotImplementedErr(t, err) if err != nil { @@ -47,7 +60,7 @@ func TestUptime(t *testing.T) { } } -func TestBoot_time(t *testing.T) { +func TestBootTime(t *testing.T) { if os.Getenv("CI") == "true" { t.Skip("Skip CI") } @@ -93,7 +106,7 @@ func TestUsers(t *testing.T) { } } -func TestHostInfoStat_String(t *testing.T) { +func TestInfoStat_String(t *testing.T) { v := InfoStat{ Hostname: "test", Uptime: 3000, @@ -123,7 +136,7 @@ func TestUserStat_String(t *testing.T) { } } -func TestHostGuid(t *testing.T) { +func TestGuid(t *testing.T) { id, err := HostID() skipIfNotImplementedErr(t, err) if err != nil { @@ -136,19 +149,6 @@ func TestHostGuid(t *testing.T) { } } -func TestTemperatureStat_String(t *testing.T) { - v := TemperatureStat{ - SensorKey: "CPU", - Temperature: 1.1, - High: 30.1, - Critical: 0.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, %v", fmt.Sprintf("%v", v)) - } -} - func TestVirtualization(t *testing.T) { wg := sync.WaitGroup{} testCount := 10 diff --git a/host/host_windows.go b/host/host_windows.go index b83ad6db1..7daad6f94 100644 --- a/host/host_windows.go +++ b/host/host_windows.go @@ -1,12 +1,11 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package host import ( "context" "fmt" - "math" "strconv" "strings" "sync/atomic" @@ -14,9 +13,8 @@ import ( "time" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" - "github.com/yusufpapurcu/wmi" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/process" "golang.org/x/sys/windows" ) @@ -57,13 +55,6 @@ type systemInfo struct { wProcessorRevision uint16 } -type msAcpi_ThermalZoneTemperature struct { - Active bool - CriticalTripPoint uint32 - CurrentTemperature uint32 - InstanceName string -} - func HostIDWithContext(ctx context.Context) (string, error) { // there has been reports of issues on 32bit using golang.org/x/sys/windows/registry, see https://github.com/shirou/gopsutil/pull/312#issuecomment-277422612 // for rationale of using windows.RegOpenKeyEx/RegQueryValueEx instead of registry.OpenKey/GetStringValue @@ -145,6 +136,14 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { } func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) { + platform, family, _, displayVersion, err := platformInformation(ctx) + if err != nil { + return "", "", "", err + } + return platform, family, displayVersion, nil +} + +func platformInformation(ctx context.Context) (platform, family, version, displayVersion string, err error) { // GetVersionEx lies on Windows 8.1 and returns as Windows 8 if we don't declare compatibility in manifest // RtlGetVersion bypasses this lying layer and returns the true Windows version // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-rtlgetversion @@ -208,6 +207,14 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil copy((*[4]byte)(unsafe.Pointer(&UBR))[:], regBuf) } + // Get DisplayVersion(ex: 23H2) as platformVersion + err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`DisplayVersion`), nil, &valType, nil, &bufLen) + if err == nil { + regBuf := make([]uint16, bufLen/2+1) + err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`DisplayVersion`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) + displayVersion = windows.UTF16ToString(regBuf[:]) + } + // PlatformFamily switch osInfo.wProductType { case 1: @@ -223,7 +230,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil osInfo.dwMajorVersion, osInfo.dwMinorVersion, osInfo.dwBuildNumber, UBR, osInfo.dwBuildNumber, UBR) - return platform, family, version, nil + return platform, family, version, displayVersion, nil } func UsersWithContext(ctx context.Context) ([]UserStat, error) { @@ -232,39 +239,12 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { return ret, common.ErrNotImplementedError } -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - var ret []TemperatureStat - var dst []msAcpi_ThermalZoneTemperature - q := wmi.CreateQuery(&dst, "") - if err := common.WMIQueryWithContext(ctx, q, &dst, nil, "root/wmi"); err != nil { - return ret, err - } - - for _, v := range dst { - ts := TemperatureStat{ - SensorKey: v.InstanceName, - Temperature: kelvinToCelsius(v.CurrentTemperature, 2), - } - ret = append(ret, ts) - } - - return ret, nil -} - -func kelvinToCelsius(temp uint32, n int) float64 { - // wmi return temperature Kelvin * 10, so need to divide the result by 10, - // and then minus 273.15 to get °Celsius. - t := float64(temp/10) - 273.15 - n10 := math.Pow10(n) - return math.Trunc((t+0.5/n10)*n10) / n10 -} - func VirtualizationWithContext(ctx context.Context) (string, string, error) { return "", "", common.ErrNotImplementedError } func KernelVersionWithContext(ctx context.Context) (string, error) { - _, _, version, err := PlatformInformationWithContext(ctx) + _, _, version, _, err := platformInformation(ctx) return version, err } diff --git a/host/types_darwin.go b/host/types_darwin.go index 3378cffe4..4e35ab72d 100644 --- a/host/types_darwin.go +++ b/host/types_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // plus hand editing about timeval diff --git a/host/types_freebsd.go b/host/types_freebsd.go index 79154d7ec..50a62d44e 100644 --- a/host/types_freebsd.go +++ b/host/types_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore /* Input to cgo -godefs. diff --git a/host/types_linux.go b/host/types_linux.go index 2b087b1a0..b225af166 100644 --- a/host/types_linux.go +++ b/host/types_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore /* Input to cgo -godefs. diff --git a/host/types_openbsd.go b/host/types_openbsd.go index 81cdd5336..fe1e5b9a5 100644 --- a/host/types_openbsd.go +++ b/host/types_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore /* Input to cgo -godefs. diff --git a/internal/common/binary.go b/internal/common/binary.go index 5e8d43db8..6e75e74b0 100644 --- a/internal/common/binary.go +++ b/internal/common/binary.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common // Copyright 2009 The Go Authors. All rights reserved. diff --git a/internal/common/common.go b/internal/common/common.go index 5e25e507b..642aabc55 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common // @@ -25,7 +26,7 @@ import ( "strings" "time" - "github.com/shirou/gopsutil/v3/common" + "github.com/shirou/gopsutil/v4/common" ) var ( diff --git a/internal/common/common_darwin.go b/internal/common/common_darwin.go index f1a784597..53f9ae8d9 100644 --- a/internal/common/common_darwin.go +++ b/internal/common/common_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package common diff --git a/internal/common/common_freebsd.go b/internal/common/common_freebsd.go index f590e2e67..53cdceeb6 100644 --- a/internal/common/common_freebsd.go +++ b/internal/common/common_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd || openbsd -// +build freebsd openbsd package common diff --git a/internal/common/common_linux.go b/internal/common/common_linux.go index 8f36c701e..89a682e8e 100644 --- a/internal/common/common_linux.go +++ b/internal/common/common_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package common diff --git a/internal/common/common_netbsd.go b/internal/common/common_netbsd.go index efbc710a5..206532126 100644 --- a/internal/common/common_netbsd.go +++ b/internal/common/common_netbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd -// +build netbsd package common diff --git a/internal/common/common_openbsd.go b/internal/common/common_openbsd.go index 58d76f334..00fa19a2f 100644 --- a/internal/common/common_openbsd.go +++ b/internal/common/common_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package common diff --git a/internal/common/common_test.go b/internal/common/common_test.go index 424ea26ab..77db9b4ca 100644 --- a/internal/common/common_test.go +++ b/internal/common/common_test.go @@ -1,15 +1,15 @@ +// SPDX-License-Identifier: BSD-3-Clause package common import ( "context" - "fmt" "os" "reflect" "runtime" "strings" "testing" - "github.com/shirou/gopsutil/v3/common" + "github.com/shirou/gopsutil/v4/common" ) func TestReadlines(t *testing.T) { @@ -17,17 +17,16 @@ func TestReadlines(t *testing.T) { if err != nil { t.Error(err) } - if !strings.Contains(ret[0], "package common") { + if !strings.Contains(ret[1], "package common") { t.Error("could not read correctly") } } func TestReadLinesOffsetN(t *testing.T) { - ret, err := ReadLinesOffsetN("common_test.go", 2, 1) + ret, err := ReadLinesOffsetN("common_test.go", 3, 1) if err != nil { t.Error(err) } - fmt.Println(ret[0]) if !strings.Contains(ret[0], `import (`) { t.Error("could not read correctly") } diff --git a/internal/common/common_unix.go b/internal/common/common_unix.go index 4af7e5c2a..2715b890b 100644 --- a/internal/common/common_unix.go +++ b/internal/common/common_unix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux || freebsd || darwin || openbsd -// +build linux freebsd darwin openbsd package common diff --git a/internal/common/common_windows.go b/internal/common/common_windows.go index 301b2315b..766ed2fcb 100644 --- a/internal/common/common_windows.go +++ b/internal/common/common_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package common diff --git a/internal/common/endian.go b/internal/common/endian.go index 147cfdc4b..113ff2e9f 100644 --- a/internal/common/endian.go +++ b/internal/common/endian.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common import "unsafe" diff --git a/internal/common/sleep.go b/internal/common/sleep.go index 94cedfd34..504f13ffd 100644 --- a/internal/common/sleep.go +++ b/internal/common/sleep.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common import ( diff --git a/internal/common/sleep_test.go b/internal/common/sleep_test.go index aadc7667c..d3205c225 100644 --- a/internal/common/sleep_test.go +++ b/internal/common/sleep_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common_test import ( @@ -6,7 +7,7 @@ import ( "testing" "time" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func TestSleep(test *testing.T) { diff --git a/internal/common/warnings.go b/internal/common/warnings.go index a4aaadaf5..888cc57fa 100644 --- a/internal/common/warnings.go +++ b/internal/common/warnings.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package common import "fmt" diff --git a/load/load.go b/load/load.go index 0da50904e..ec48a07ca 100644 --- a/load/load.go +++ b/load/load.go @@ -1,9 +1,10 @@ +// SPDX-License-Identifier: BSD-3-Clause package load import ( "encoding/json" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var invoke common.Invoker = common.Invoke{} diff --git a/load/load_aix.go b/load/load_aix.go index 78b391280..eb5b5b066 100644 --- a/load/load_aix.go +++ b/load/load_aix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix -// +build aix package load diff --git a/load/load_aix_cgo.go b/load/load_aix_cgo.go index bbbf287e2..e325432ed 100644 --- a/load/load_aix_cgo.go +++ b/load/load_aix_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && cgo -// +build aix,cgo package load diff --git a/load/load_aix_nocgo.go b/load/load_aix_nocgo.go index 25d50ac18..cfb4117d6 100644 --- a/load/load_aix_nocgo.go +++ b/load/load_aix_nocgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && !cgo -// +build aix,!cgo package load @@ -9,7 +9,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var separator = regexp.MustCompile(`,?\s+`) @@ -26,7 +26,7 @@ func AvgWithContext(ctx context.Context) (*AvgStat, error) { } ret := &AvgStat{} - p := separator.Split(string(line[idx:len(line)]), 5) + p := separator.Split(string(line[idx:]), 5) if 4 < len(p) && p[0] == "load" && p[1] == "average:" { if t, err := strconv.ParseFloat(p[2], 64); err == nil { ret.Load1 = t diff --git a/load/load_bsd.go b/load/load_bsd.go index 51d928682..97001f3c6 100644 --- a/load/load_bsd.go +++ b/load/load_bsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd || openbsd -// +build freebsd openbsd package load diff --git a/load/load_darwin.go b/load/load_darwin.go index ce8018813..fb7d5c09c 100644 --- a/load/load_darwin.go +++ b/load/load_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package load diff --git a/load/load_fallback.go b/load/load_fallback.go index 3e41fd1ea..e633066be 100644 --- a/load/load_fallback.go +++ b/load/load_fallback.go @@ -1,12 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build !darwin && !linux && !freebsd && !openbsd && !windows && !solaris && !aix -// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris,!aix package load import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func Avg() (*AvgStat, error) { diff --git a/load/load_freebsd.go b/load/load_freebsd.go index 406980506..3e35f3f73 100644 --- a/load/load_freebsd.go +++ b/load/load_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd -// +build freebsd package load diff --git a/load/load_linux.go b/load/load_linux.go index daf2614c2..e964b6960 100644 --- a/load/load_linux.go +++ b/load/load_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package load @@ -10,7 +10,7 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func Avg() (*AvgStat, error) { diff --git a/load/load_openbsd.go b/load/load_openbsd.go index 1d5d611f3..df00588cd 100644 --- a/load/load_openbsd.go +++ b/load/load_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package load diff --git a/load/load_solaris.go b/load/load_solaris.go index 99b339bd8..3713f4a80 100644 --- a/load/load_solaris.go +++ b/load/load_solaris.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build solaris -// +build solaris package load diff --git a/load/load_test.go b/load/load_test.go index 1790fa559..38e032b63 100644 --- a/load/load_test.go +++ b/load/load_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package load import ( @@ -5,7 +6,7 @@ import ( "fmt" "testing" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func skipIfNotImplementedErr(t testing.TB, err error) { @@ -14,7 +15,7 @@ func skipIfNotImplementedErr(t testing.TB, err error) { } } -func TestLoad(t *testing.T) { +func TestAvg(t *testing.T) { v, err := Avg() skipIfNotImplementedErr(t, err) if err != nil { @@ -28,7 +29,7 @@ func TestLoad(t *testing.T) { t.Log(v) } -func TestLoadAvgStat_String(t *testing.T) { +func TestAvgStat_String(t *testing.T) { v := AvgStat{ Load1: 10.1, Load5: 20.1, diff --git a/load/load_windows.go b/load/load_windows.go index 5241dfaab..a55c7b40a 100644 --- a/load/load_windows.go +++ b/load/load_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package load @@ -9,7 +9,7 @@ import ( "sync" "time" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var ( diff --git a/mem/ex_linux.go b/mem/ex_linux.go new file mode 100644 index 000000000..0a12fe2fe --- /dev/null +++ b/mem/ex_linux.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build linux + +package mem + +import ( + "context" + "encoding/json" +) + +type ExVirtualMemory struct { + ActiveFile uint64 `json:"activefile"` + InactiveFile uint64 `json:"inactivefile"` + ActiveAnon uint64 `json:"activeanon"` + InactiveAnon uint64 `json:"inactiveanon"` + Unevictable uint64 `json:"unevictable"` +} + +func (v ExVirtualMemory) String() string { + s, _ := json.Marshal(v) + return string(s) +} + +type ExLinux struct{} + +func NewExLinux() *ExLinux { + return &ExLinux{} +} + +func (ex *ExLinux) VirtualMemory() (*ExVirtualMemory, error) { + return ex.VirtualMemoryWithContext(context.Background()) +} + +func (ex *ExLinux) VirtualMemoryWithContext(ctx context.Context) (*ExVirtualMemory, error) { + _, vmEx, err := fillFromMeminfoWithContext(ctx) + if err != nil { + return nil, err + } + return vmEx, nil +} diff --git a/mem/ex_windows.go b/mem/ex_windows.go new file mode 100644 index 000000000..4f1573b3c --- /dev/null +++ b/mem/ex_windows.go @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build windows + +package mem + +import ( + "unsafe" + + "golang.org/x/sys/windows" +) + +// ExVirtualMemory represents Windows specific information +// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex +type ExVirtualMemory struct { + VirtualTotal uint64 `json:"virtualTotal"` + VirtualAvail uint64 `json:"virtualAvail"` +} + +type ExWindows struct{} + +func NewExWindows() *ExWindows { + return &ExWindows{} +} + +func (e *ExWindows) VirtualMemory() (*ExVirtualMemory, error) { + var memInfo memoryStatusEx + memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) + mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) + if mem == 0 { + return nil, windows.GetLastError() + } + + ret := &ExVirtualMemory{ + VirtualTotal: memInfo.ullTotalVirtual, + VirtualAvail: memInfo.ullAvailVirtual, + } + + return ret, nil +} diff --git a/mem/mem.go b/mem/mem.go index edaf268bb..0da71a988 100644 --- a/mem/mem.go +++ b/mem/mem.go @@ -1,9 +1,10 @@ +// SPDX-License-Identifier: BSD-3-Clause package mem import ( "encoding/json" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var invoke common.Invoker = common.Invoke{} diff --git a/mem/mem_aix.go b/mem/mem_aix.go index 22a6a4e92..916bff30d 100644 --- a/mem/mem_aix.go +++ b/mem/mem_aix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix -// +build aix package mem diff --git a/mem/mem_aix_cgo.go b/mem/mem_aix_cgo.go index 67e11dff8..2d03dd0c3 100644 --- a/mem/mem_aix_cgo.go +++ b/mem/mem_aix_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && cgo -// +build aix,cgo package mem diff --git a/mem/mem_aix_nocgo.go b/mem/mem_aix_nocgo.go index cc6a76d2f..bc3c0ed3b 100644 --- a/mem/mem_aix_nocgo.go +++ b/mem/mem_aix_nocgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && !cgo -// +build aix,!cgo package mem @@ -8,11 +8,11 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - vmem, swap, err := callSVMon(ctx) + vmem, swap, err := callSVMon(ctx, true) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { } func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - _, swap, err := callSVMon(ctx) + _, swap, err := callSVMon(ctx, false) if err != nil { return nil, err } @@ -35,7 +35,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { return swap, nil } -func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error) { +func callSVMon(ctx context.Context, virt bool) (*VirtualMemoryStat, *SwapMemoryStat, error) { out, err := invoke.CommandWithContext(ctx, "svmon", "-G") if err != nil { return nil, nil, err @@ -45,7 +45,7 @@ func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error) vmem := &VirtualMemoryStat{} swap := &SwapMemoryStat{} for _, line := range strings.Split(string(out), "\n") { - if strings.HasPrefix(line, "memory") { + if virt && strings.HasPrefix(line, "memory") { p := strings.Fields(line) if len(p) > 2 { if t, err := strconv.ParseUint(p[1], 10, 64); err == nil { diff --git a/mem/mem_bsd.go b/mem/mem_bsd.go index ef867d742..4f3e57c03 100644 --- a/mem/mem_bsd.go +++ b/mem/mem_bsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd || openbsd || netbsd -// +build freebsd openbsd netbsd package mem diff --git a/mem/mem_bsd_test.go b/mem/mem_bsd_test.go index 9839a0435..8b0eb9f06 100644 --- a/mem/mem_bsd_test.go +++ b/mem/mem_bsd_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd || openbsd -// +build freebsd openbsd package mem diff --git a/mem/mem_darwin.go b/mem/mem_darwin.go index a05a0faba..a33c5f125 100644 --- a/mem/mem_darwin.go +++ b/mem/mem_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package mem @@ -10,7 +10,7 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func getHwMemsize() (uint64, error) { diff --git a/mem/mem_darwin_cgo.go b/mem/mem_darwin_cgo.go index e5da7dcdb..cc6657d04 100644 --- a/mem/mem_darwin_cgo.go +++ b/mem/mem_darwin_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && cgo -// +build darwin,cgo package mem diff --git a/mem/mem_darwin_nocgo.go b/mem/mem_darwin_nocgo.go index c93931680..097a93e63 100644 --- a/mem/mem_darwin_nocgo.go +++ b/mem/mem_darwin_nocgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && !cgo -// +build darwin,!cgo package mem diff --git a/mem/mem_darwin_test.go b/mem/mem_darwin_test.go index 4e0d9a014..c7f5668bd 100644 --- a/mem/mem_darwin_test.go +++ b/mem/mem_darwin_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package mem diff --git a/mem/mem_fallback.go b/mem/mem_fallback.go index 697fd8709..ba882c8be 100644 --- a/mem/mem_fallback.go +++ b/mem/mem_fallback.go @@ -1,12 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build !darwin && !linux && !freebsd && !openbsd && !solaris && !windows && !plan9 && !aix && !netbsd -// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!plan9,!aix,!netbsd package mem import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func VirtualMemory() (*VirtualMemoryStat, error) { diff --git a/mem/mem_freebsd.go b/mem/mem_freebsd.go index 9a56785b3..d9cae7116 100644 --- a/mem/mem_freebsd.go +++ b/mem/mem_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd -// +build freebsd package mem @@ -8,7 +8,7 @@ import ( "errors" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) diff --git a/mem/mem_linux.go b/mem/mem_linux.go index 214a91e47..05bfdaf4e 100644 --- a/mem/mem_linux.go +++ b/mem/mem_linux.go @@ -1,12 +1,11 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package mem import ( "bufio" "context" - "encoding/json" "fmt" "io" "math" @@ -16,22 +15,9 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) -type VirtualMemoryExStat struct { - ActiveFile uint64 `json:"activefile"` - InactiveFile uint64 `json:"inactivefile"` - ActiveAnon uint64 `json:"activeanon"` - InactiveAnon uint64 `json:"inactiveanon"` - Unevictable uint64 `json:"unevictable"` -} - -func (v VirtualMemoryExStat) String() string { - s, _ := json.Marshal(v) - return string(s) -} - func VirtualMemory() (*VirtualMemoryStat, error) { return VirtualMemoryWithContext(context.Background()) } @@ -44,19 +30,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { return vm, nil } -func VirtualMemoryEx() (*VirtualMemoryExStat, error) { - return VirtualMemoryExWithContext(context.Background()) -} - -func VirtualMemoryExWithContext(ctx context.Context) (*VirtualMemoryExStat, error) { - _, vmEx, err := fillFromMeminfoWithContext(ctx) - if err != nil { - return nil, err - } - return vmEx, nil -} - -func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *VirtualMemoryExStat, error) { +func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *ExVirtualMemory, error) { filename := common.HostProcWithContext(ctx, "meminfo") lines, _ := common.ReadLines(filename) @@ -67,7 +41,7 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu sReclaimable := false // "Sreclaimable:" not available: 2.6.19 / Nov 2006 ret := &VirtualMemoryStat{} - retEx := &VirtualMemoryExStat{} + retEx := &ExVirtualMemory{} for _, line := range lines { fields := strings.Split(line, ":") @@ -409,7 +383,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { // calculateAvailVmem is a fallback under kernel 3.14 where /proc/meminfo does not provide // "MemAvailable:" column. It reimplements an algorithm from the link below // https://github.com/giampaolo/psutil/pull/890 -func calculateAvailVmem(ctx context.Context, ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint64 { +func calculateAvailVmem(ctx context.Context, ret *VirtualMemoryStat, retEx *ExVirtualMemory) uint64 { var watermarkLow uint64 fn := common.HostProcWithContext(ctx, "zoneinfo") diff --git a/mem/mem_linux_test.go b/mem/mem_linux_test.go index 6b6fb782a..390621d5e 100644 --- a/mem/mem_linux_test.go +++ b/mem/mem_linux_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package mem @@ -13,8 +13,10 @@ import ( "github.com/stretchr/testify/assert" ) -func TestVirtualMemoryEx(t *testing.T) { - v, err := VirtualMemoryEx() +func TestExVirtualMemory(t *testing.T) { + ex := NewExLinux() + + v, err := ex.VirtualMemory() if err != nil { t.Error(err) } diff --git a/mem/mem_netbsd.go b/mem/mem_netbsd.go index d1f54ecaf..0a41b3e34 100644 --- a/mem/mem_netbsd.go +++ b/mem/mem_netbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build netbsd -// +build netbsd package mem diff --git a/mem/mem_openbsd.go b/mem/mem_openbsd.go index e37d5abe0..2510bb0d3 100644 --- a/mem/mem_openbsd.go +++ b/mem/mem_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package mem @@ -10,7 +10,7 @@ import ( "errors" "fmt" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/unix" ) diff --git a/mem/mem_openbsd_386.go b/mem/mem_openbsd_386.go index de2b26ca4..552e93f4a 100644 --- a/mem/mem_openbsd_386.go +++ b/mem/mem_openbsd_386.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && 386 -// +build openbsd,386 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs mem/types_openbsd.go diff --git a/mem/mem_openbsd_amd64.go b/mem/mem_openbsd_amd64.go index d187abf01..73e5b72aa 100644 --- a/mem/mem_openbsd_amd64.go +++ b/mem/mem_openbsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_openbsd.go diff --git a/mem/mem_openbsd_arm.go b/mem/mem_openbsd_arm.go index 2488f1851..57b5861de 100644 --- a/mem/mem_openbsd_arm.go +++ b/mem/mem_openbsd_arm.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm -// +build openbsd,arm // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs mem/types_openbsd.go diff --git a/mem/mem_openbsd_arm64.go b/mem/mem_openbsd_arm64.go index 3661b16fb..f39a6456b 100644 --- a/mem/mem_openbsd_arm64.go +++ b/mem/mem_openbsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm64 -// +build openbsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs mem/types_openbsd.go diff --git a/mem/mem_openbsd_riscv64.go b/mem/mem_openbsd_riscv64.go index 7a7b48038..f9f838f54 100644 --- a/mem/mem_openbsd_riscv64.go +++ b/mem/mem_openbsd_riscv64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && riscv64 -// +build openbsd,riscv64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs mem/types_openbsd.go diff --git a/mem/mem_plan9.go b/mem/mem_plan9.go index b5259f844..c17a102ee 100644 --- a/mem/mem_plan9.go +++ b/mem/mem_plan9.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build plan9 -// +build plan9 package mem @@ -8,7 +8,7 @@ import ( "os" stats "github.com/lufia/plan9stats" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func SwapMemory() (*SwapMemoryStat, error) { diff --git a/mem/mem_plan9_test.go b/mem/mem_plan9_test.go index 1ae353d3a..836d6c8fa 100644 --- a/mem/mem_plan9_test.go +++ b/mem/mem_plan9_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build plan9 -// +build plan9 package mem diff --git a/mem/mem_solaris.go b/mem/mem_solaris.go index c911267e1..06d0d9a00 100644 --- a/mem/mem_solaris.go +++ b/mem/mem_solaris.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build solaris -// +build solaris package mem @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/tklauser/go-sysconf" ) diff --git a/mem/mem_solaris_test.go b/mem/mem_solaris_test.go index 05360203a..5e0aa700f 100644 --- a/mem/mem_solaris_test.go +++ b/mem/mem_solaris_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build solaris -// +build solaris package mem diff --git a/mem/mem_test.go b/mem/mem_test.go index 79ddb0fc6..c069a4a10 100644 --- a/mem/mem_test.go +++ b/mem/mem_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package mem import ( @@ -8,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -17,7 +18,7 @@ func skipIfNotImplementedErr(t *testing.T, err error) { } } -func TestVirtual_memory(t *testing.T) { +func TestVirtualMemory(t *testing.T) { if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" { t.Skip("Only .Total .Available are supported on Solaris/illumos") } @@ -66,7 +67,7 @@ func TestVirtual_memory(t *testing.T) { "UsedPercent should be how many percent of Total is Used: %v", v) } -func TestSwap_memory(t *testing.T) { +func TestSwapMemory(t *testing.T) { v, err := SwapMemory() skipIfNotImplementedErr(t, err) if err != nil { diff --git a/mem/mem_windows.go b/mem/mem_windows.go index 8c7fb1a13..4666cbd01 100644 --- a/mem/mem_windows.go +++ b/mem/mem_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package mem @@ -9,7 +9,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" ) diff --git a/mem/types_openbsd.go b/mem/types_openbsd.go index 8e0e412af..f71a457e4 100644 --- a/mem/types_openbsd.go +++ b/mem/types_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore /* Input to cgo -godefs. diff --git a/mktypes.sh b/mktypes.sh index 9d8cf8ea3..e2327fb00 100644 --- a/mktypes.sh +++ b/mktypes.sh @@ -1,19 +1,15 @@ #!/bin/sh -PKGS="cpu disk docker host load mem net process" +PKGS="cpu disk docker host load mem net process sensors winservices" GOOS=$(go env GOOS) GOARCH=$(go env GOARCH) -for DIR in . v3 +for PKG in $PKGS do - (cd "$DIR" || exit - for PKG in $PKGS - do - if [ -e "${PKG}/types_${GOOS}.go" ]; then - (echo "// +build $GOOS" - echo "// +build $GOARCH" - go tool cgo -godefs "${PKG}/types_${GOOS}.go") | gofmt > "${PKG}/${PKG}_${GOOS}_${GOARCH}.go" - fi - done) + if [ -e "${PKG}/types_${GOOS}.go" ]; then + (echo "// +build $GOOS" + echo "// +build $GOARCH" + go tool cgo -godefs "${PKG}/types_${GOOS}.go") | gofmt > "${PKG}/${PKG}_${GOOS}_${GOARCH}.go" + fi done diff --git a/net/net.go b/net/net.go index 0f3a62f39..3890eda53 100644 --- a/net/net.go +++ b/net/net.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package net import ( @@ -5,7 +6,7 @@ import ( "encoding/json" "net" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var invoke common.Invoker = common.Invoke{} diff --git a/net/net_aix.go b/net/net_aix.go index 81feaa8d7..df59abecb 100644 --- a/net/net_aix.go +++ b/net/net_aix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix -// +build aix package net @@ -11,7 +11,7 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCounters(pernic bool) ([]IOCountersStat, error) { diff --git a/net/net_aix_cgo.go b/net/net_aix_cgo.go index 8c34f881c..a45a5b75c 100644 --- a/net/net_aix_cgo.go +++ b/net/net_aix_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && cgo -// +build aix,cgo package net diff --git a/net/net_aix_nocgo.go b/net/net_aix_nocgo.go index e3fce9021..f63a21e73 100644 --- a/net/net_aix_nocgo.go +++ b/net/net_aix_nocgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build aix && !cgo -// +build aix,!cgo package net @@ -9,7 +9,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func parseNetstatI(output string) ([]IOCountersStat, error) { diff --git a/net/net_darwin.go b/net/net_darwin.go index 8a7b63744..f86b7bf9e 100644 --- a/net/net_darwin.go +++ b/net/net_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package net @@ -12,7 +12,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var ( diff --git a/net/net_darwin_test.go b/net/net_darwin_test.go index 0680d08ad..86ed1262d 100644 --- a/net/net_darwin_test.go +++ b/net/net_darwin_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package net import ( diff --git a/net/net_fallback.go b/net/net_fallback.go index e136be1ba..e62deeeed 100644 --- a/net/net_fallback.go +++ b/net/net_fallback.go @@ -1,12 +1,12 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build !aix && !darwin && !linux && !freebsd && !openbsd && !windows && !solaris -// +build !aix,!darwin,!linux,!freebsd,!openbsd,!windows,!solaris package net import ( "context" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCounters(pernic bool) ([]IOCountersStat, error) { diff --git a/net/net_freebsd.go b/net/net_freebsd.go index bf8baf094..155a49c40 100644 --- a/net/net_freebsd.go +++ b/net/net_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd -// +build freebsd package net @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func IOCounters(pernic bool) ([]IOCountersStat, error) { diff --git a/net/net_linux.go b/net/net_linux.go index 20ca5470a..a46f1b9dc 100644 --- a/net/net_linux.go +++ b/net/net_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package net @@ -16,7 +16,7 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) const ( // Conntrack Column numbers @@ -552,7 +552,7 @@ func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, erro return ret, err } defer f.Close() - dirEntries, err := readDir(f, max) + dirEntries, err := f.ReadDir(max) if err != nil { return ret, err } diff --git a/net/net_linux_111.go b/net/net_linux_111.go deleted file mode 100644 index bd5c95871..000000000 --- a/net/net_linux_111.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build !go1.16 -// +build !go1.16 - -package net - -import ( - "os" -) - -func readDir(f *os.File, max int) ([]os.FileInfo, error) { - return f.Readdir(max) -} diff --git a/net/net_linux_116.go b/net/net_linux_116.go deleted file mode 100644 index a45072e92..000000000 --- a/net/net_linux_116.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build go1.16 -// +build go1.16 - -package net - -import ( - "os" -) - -func readDir(f *os.File, max int) ([]os.DirEntry, error) { - return f.ReadDir(max) -} diff --git a/net/net_linux_netlink_test.go b/net/net_linux_netlink_test.go deleted file mode 100644 index 889719676..000000000 --- a/net/net_linux_netlink_test.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build linux -// +build linux - -package net - -import "testing" - -func BenchmarkGetConnectionsInet(b *testing.B) { - b.ResetTimer() - for i := 0; i < b.N; i++ { - Connections("inet") - } -} - -func BenchmarkGetConnectionsAll(b *testing.B) { - b.ResetTimer() - for i := 0; i < b.N; i++ { - Connections("all") - } -} diff --git a/net/net_linux_test.go b/net/net_linux_test.go index eae0e71b9..b7ccaa895 100644 --- a/net/net_linux_test.go +++ b/net/net_linux_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package net import ( @@ -11,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func TestIOCountersByFileParsing(t *testing.T) { diff --git a/net/net_openbsd.go b/net/net_openbsd.go index 25bbe49ca..b6c31dd35 100644 --- a/net/net_openbsd.go +++ b/net/net_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package net @@ -12,13 +12,14 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`) func ParseNetstat(output string, mode string, - iocs map[string]IOCountersStat) error { + iocs map[string]IOCountersStat, +) error { lines := strings.Split(output, "\n") exists := make([]string, 0, len(lines)-1) diff --git a/net/net_solaris.go b/net/net_solaris.go index 79d8ac30e..b886066e8 100644 --- a/net/net_solaris.go +++ b/net/net_solaris.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build solaris -// +build solaris package net @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) // NetIOCounters returnes network I/O statistics for every network diff --git a/net/net_test.go b/net/net_test.go index 72f4db9c5..60e843894 100644 --- a/net/net_test.go +++ b/net/net_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package net import ( @@ -7,7 +8,7 @@ import ( "runtime" "testing" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -25,7 +26,7 @@ func TestAddrString(t *testing.T) { } } -func TestNetIOCountersStatString(t *testing.T) { +func TestIOCountersStatString(t *testing.T) { v := IOCountersStat{ Name: "test", BytesSent: 100, @@ -36,7 +37,7 @@ func TestNetIOCountersStatString(t *testing.T) { } } -func TestNetProtoCountersStatString(t *testing.T) { +func TestProtoCountersStatString(t *testing.T) { v := ProtoCountersStat{ Protocol: "tcp", Stats: map[string]int64{ @@ -51,7 +52,7 @@ func TestNetProtoCountersStatString(t *testing.T) { } } -func TestNetConnectionStatString(t *testing.T) { +func TestConnectionStatString(t *testing.T) { v := ConnectionStat{ Fd: 10, Family: 10, @@ -64,7 +65,7 @@ func TestNetConnectionStatString(t *testing.T) { } } -func TestNetIOCountersAll(t *testing.T) { +func TestIOCountersAll(t *testing.T) { v, err := IOCounters(false) skipIfNotImplementedErr(t, err) if err != nil { @@ -102,7 +103,7 @@ func TestNetIOCountersAll(t *testing.T) { } } -func TestNetIOCountersPerNic(t *testing.T) { +func TestIOCountersPerNic(t *testing.T) { v, err := IOCounters(true) skipIfNotImplementedErr(t, err) if err != nil { @@ -151,7 +152,7 @@ func TestGetNetIOCountersAll(t *testing.T) { } } -func TestNetInterfaces(t *testing.T) { +func TestInterfaces(t *testing.T) { v, err := Interfaces() skipIfNotImplementedErr(t, err) if err != nil { @@ -167,7 +168,7 @@ func TestNetInterfaces(t *testing.T) { } } -func TestNetProtoCountersStatsAll(t *testing.T) { +func TestProtoCountersStatsAll(t *testing.T) { v, err := ProtoCounters(nil) skipIfNotImplementedErr(t, err) if err != nil { @@ -186,7 +187,7 @@ func TestNetProtoCountersStatsAll(t *testing.T) { } } -func TestNetProtoCountersStats(t *testing.T) { +func TestProtoCountersStats(t *testing.T) { v, err := ProtoCounters([]string{"tcp", "ip"}) skipIfNotImplementedErr(t, err) if err != nil { @@ -208,8 +209,8 @@ func TestNetProtoCountersStats(t *testing.T) { } } -func TestNetConnections(t *testing.T) { - if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io +func TestConnections(t *testing.T) { + if ci := os.Getenv("CI"); ci != "" { // skip if test on CI return } @@ -228,8 +229,8 @@ func TestNetConnections(t *testing.T) { } } -func TestNetFilterCounters(t *testing.T) { - if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io +func TestFilterCounters(t *testing.T) { + if ci := os.Getenv("CI"); ci != "" { // skip if test on CI return } diff --git a/net/net_unix.go b/net/net_unix.go index cb846e28a..71fc3b972 100644 --- a/net/net_unix.go +++ b/net/net_unix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd || darwin -// +build freebsd darwin package net @@ -11,7 +11,7 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) // Return a list of network connections opened. diff --git a/net/net_windows.go b/net/net_windows.go index 5d384342f..12f62cda0 100644 --- a/net/net_windows.go +++ b/net/net_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package net @@ -11,7 +11,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" ) diff --git a/net/types_darwin.go b/net/types_darwin.go index 81aca0119..c713f6b1b 100644 --- a/net/types_darwin.go +++ b/net/types_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // Hand writing: _Ctype_struct___3, 4 diff --git a/process/process.go b/process/process.go index 1bb27abf8..ba2766252 100644 --- a/process/process.go +++ b/process/process.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package process import ( @@ -9,10 +10,10 @@ import ( "sync" "time" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/mem" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/mem" + "github.com/shirou/gopsutil/v4/net" ) var ( @@ -29,9 +30,9 @@ type Process struct { parent int32 parentMutex sync.RWMutex // for windows ppid cache numCtxSwitches *NumCtxSwitchesStat - uids []int32 - gids []int32 - groups []int32 + uids []uint32 + gids []uint32 + groups []uint32 numThreads int32 memInfo *MemoryInfoStat sigInfo *SignalInfoStat @@ -102,10 +103,18 @@ type RlimitStat struct { } type IOCountersStat struct { - ReadCount uint64 `json:"readCount"` + // ReadCount is a number of read I/O operations such as syscalls. + ReadCount uint64 `json:"readCount"` + // WriteCount is a number of read I/O operations such as syscalls. WriteCount uint64 `json:"writeCount"` - ReadBytes uint64 `json:"readBytes"` + // ReadBytes is a number of all I/O read in bytes. This includes disk I/O on Linux and Windows. + ReadBytes uint64 `json:"readBytes"` + // WriteBytes is a number of all I/O write in bytes. This includes disk I/O on Linux and Windows. WriteBytes uint64 `json:"writeBytes"` + // DiskReadBytes is a number of disk I/O write in bytes. Currently only Linux has this value. + DiskReadBytes uint64 `json:"diskReadBytes"` + // DiskWriteBytes is a number of disk I/O read in bytes. Currently only Linux has this value. + DiskWriteBytes uint64 `json:"diskWriteBytes"` } type NumCtxSwitchesStat struct { @@ -368,7 +377,7 @@ func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) { } // Groups returns all group IDs(include supplementary groups) of the process as a slice of the int -func (p *Process) Groups() ([]int32, error) { +func (p *Process) Groups() ([]uint32, error) { return p.GroupsWithContext(context.Background()) } @@ -433,12 +442,12 @@ func (p *Process) Foreground() (bool, error) { } // Uids returns user ids of the process as a slice of the int -func (p *Process) Uids() ([]int32, error) { +func (p *Process) Uids() ([]uint32, error) { return p.UidsWithContext(context.Background()) } // Gids returns group ids of the process as a slice of the int -func (p *Process) Gids() ([]int32, error) { +func (p *Process) Gids() ([]uint32, error) { return p.GidsWithContext(context.Background()) } diff --git a/process/process_bsd.go b/process/process_bsd.go index 263829ffa..dcc056101 100644 --- a/process/process_bsd.go +++ b/process/process_bsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin || freebsd || openbsd -// +build darwin freebsd openbsd package process @@ -8,8 +8,8 @@ import ( "context" "encoding/binary" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" ) type MemoryInfoExStat struct{} diff --git a/process/process_darwin.go b/process/process_darwin.go index 176661cbd..5231007c3 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin -// +build darwin package process @@ -13,8 +13,8 @@ import ( "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/net" ) // copied from sys/sysctl.h @@ -117,31 +117,31 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return strings.IndexByte(string(out), '+') != -1, nil } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } // See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html - userEffectiveUID := int32(k.Eproc.Ucred.Uid) + userEffectiveUID := uint32(k.Eproc.Ucred.Uid) - return []int32{userEffectiveUID}, nil + return []uint32{userEffectiveUID}, nil } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Pcred.P_svgid)) + gids := make([]uint32, 0, 3) + gids = append(gids, uint32(k.Eproc.Pcred.P_rgid), uint32(k.Eproc.Pcred.P_rgid), uint32(k.Eproc.Pcred.P_svgid)) return gids, nil } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError // k, err := p.getKProc() // if err != nil { diff --git a/process/process_darwin_amd64.go b/process/process_darwin_amd64.go index b353e5eac..a13522473 100644 --- a/process/process_darwin_amd64.go +++ b/process/process_darwin_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_darwin.go diff --git a/process/process_darwin_arm64.go b/process/process_darwin_arm64.go index cbd6bdc79..f1f3df365 100644 --- a/process/process_darwin_arm64.go +++ b/process/process_darwin_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && arm64 -// +build darwin,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs process/types_darwin.go diff --git a/process/process_darwin_cgo.go b/process/process_darwin_cgo.go index 858f08e7a..bbdfc963e 100644 --- a/process/process_darwin_cgo.go +++ b/process/process_darwin_cgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && cgo -// +build darwin,cgo package process @@ -20,7 +20,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v4/cpu" ) var ( diff --git a/process/process_darwin_nocgo.go b/process/process_darwin_nocgo.go index d903474f6..129bb6098 100644 --- a/process/process_darwin_nocgo.go +++ b/process/process_darwin_nocgo.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && !cgo -// +build darwin,!cgo package process @@ -9,8 +9,8 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" ) func (p *Process) CwdWithContext(ctx context.Context) (string, error) { diff --git a/process/process_fallback.go b/process/process_fallback.go index 1a5d0c4b4..23793e92c 100644 --- a/process/process_fallback.go +++ b/process/process_fallback.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build !darwin && !linux && !freebsd && !openbsd && !windows && !solaris && !plan9 -// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris,!plan9 package process @@ -7,9 +7,9 @@ import ( "context" "syscall" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/net" ) type Signal = syscall.Signal @@ -82,15 +82,15 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return false, common.ErrNotImplementedError } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } diff --git a/process/process_freebsd.go b/process/process_freebsd.go index 40b10e14f..3d21183d6 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd -// +build freebsd package process @@ -10,9 +10,9 @@ import ( "strconv" "strings" - cpu "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - net "github.com/shirou/gopsutil/v3/net" + cpu "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + net "github.com/shirou/gopsutil/v4/net" "golang.org/x/sys/unix" ) @@ -157,40 +157,40 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return strings.IndexByte(string(out), '+') != -1, nil } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - uids := make([]int32, 0, 3) + uids := make([]uint32, 0, 3) - uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid)) + uids = append(uids, uint32(k.Ruid), uint32(k.Uid), uint32(k.Svuid)) return uids, nil } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid)) + gids := make([]uint32, 0, 3) + gids = append(gids, uint32(k.Rgid), uint32(k.Ngroups), uint32(k.Svgid)) return gids, nil } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - groups := make([]int32, k.Ngroups) + groups := make([]uint32, k.Ngroups) for i := int16(0); i < k.Ngroups; i++ { - groups[i] = int32(k.Groups[i]) + groups[i] = uint32(k.Groups[i]) } return groups, nil diff --git a/process/process_freebsd_386.go b/process/process_freebsd_386.go index 08ab333b4..279ba9fbb 100644 --- a/process/process_freebsd_386.go +++ b/process/process_freebsd_386.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/process/process_freebsd_amd64.go b/process/process_freebsd_amd64.go index 560e627d2..f3b70ec1b 100644 --- a/process/process_freebsd_amd64.go +++ b/process/process_freebsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/process/process_freebsd_arm.go b/process/process_freebsd_arm.go index 81ae0b9a8..75ed30630 100644 --- a/process/process_freebsd_arm.go +++ b/process/process_freebsd_arm.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_freebsd.go diff --git a/process/process_freebsd_arm64.go b/process/process_freebsd_arm64.go index 73ac08201..3dc301c02 100644 --- a/process/process_freebsd_arm64.go +++ b/process/process_freebsd_arm64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build freebsd && arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. diff --git a/process/process_linux.go b/process/process_linux.go index 557435b34..8f1d6c89c 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package process @@ -18,9 +18,9 @@ import ( "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/net" ) var pageSize = uint64(os.Getpagesize()) @@ -148,26 +148,26 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return pgid == tpgid, nil } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { err := p.fillFromStatusWithContext(ctx) if err != nil { - return []int32{}, err + return []uint32{}, err } return p.uids, nil } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { err := p.fillFromStatusWithContext(ctx) if err != nil { - return []int32{}, err + return []uint32{}, err } return p.gids, nil } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { err := p.fillFromStatusWithContext(ctx) if err != nil { - return []int32{}, err + return []uint32{}, err } return p.groups, nil } @@ -727,8 +727,12 @@ func (p *Process) fillFromIOWithContext(ctx context.Context) (*IOCountersStat, e case "syscw": ret.WriteCount = t case "read_bytes": - ret.ReadBytes = t + ret.DiskReadBytes = t case "write_bytes": + ret.DiskWriteBytes = t + case "rchar": + ret.ReadBytes = t + case "wchar": ret.WriteBytes = t } } @@ -866,32 +870,32 @@ func (p *Process) fillFromStatusWithContext(ctx context.Context) error { } p.tgid = int32(pval) case "Uid": - p.uids = make([]int32, 0, 4) + p.uids = make([]uint32, 0, 4) for _, i := range strings.Split(value, "\t") { v, err := strconv.ParseInt(i, 10, 32) if err != nil { return err } - p.uids = append(p.uids, int32(v)) + p.uids = append(p.uids, uint32(v)) } case "Gid": - p.gids = make([]int32, 0, 4) + p.gids = make([]uint32, 0, 4) for _, i := range strings.Split(value, "\t") { v, err := strconv.ParseInt(i, 10, 32) if err != nil { return err } - p.gids = append(p.gids, int32(v)) + p.gids = append(p.gids, uint32(v)) } case "Groups": groups := strings.Fields(value) - p.groups = make([]int32, 0, len(groups)) + p.groups = make([]uint32, 0, len(groups)) for _, i := range groups { - v, err := strconv.ParseInt(i, 10, 32) + v, err := strconv.ParseUint(i, 10, 32) if err != nil { return err } - p.groups = append(p.groups, int32(v)) + p.groups = append(p.groups, uint32(v)) } case "Threads": v, err := strconv.ParseInt(value, 10, 32) diff --git a/process/process_linux_test.go b/process/process_linux_test.go index 87df81231..9b9b77a88 100644 --- a/process/process_linux_test.go +++ b/process/process_linux_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux -// +build linux package process @@ -14,7 +14,7 @@ import ( "github.com/stretchr/testify/assert" ) -func Test_Process_splitProcStat(t *testing.T) { +func TestSplitProcStat(t *testing.T) { expectedFieldsNum := 53 statLineContent := make([]string, expectedFieldsNum-1) for i := 0; i < expectedFieldsNum-1; i++ { @@ -56,7 +56,7 @@ func Test_Process_splitProcStat(t *testing.T) { } } -func Test_Process_splitProcStat_fromFile(t *testing.T) { +func TestSplitProcStat_fromFile(t *testing.T) { pids, err := os.ReadDir("testdata/linux/") if err != nil { t.Error(err) @@ -92,7 +92,7 @@ func Test_Process_splitProcStat_fromFile(t *testing.T) { } } -func Test_fillFromCommWithContext(t *testing.T) { +func TestFillFromCommWithContext(t *testing.T) { pids, err := os.ReadDir("testdata/linux/") if err != nil { t.Error(err) @@ -113,7 +113,7 @@ func Test_fillFromCommWithContext(t *testing.T) { } } -func Test_fillFromStatusWithContext(t *testing.T) { +func TestFillFromStatusWithContext(t *testing.T) { pids, err := os.ReadDir("testdata/linux/") if err != nil { t.Error(err) @@ -152,7 +152,7 @@ func Benchmark_fillFromStatusWithContext(b *testing.B) { } } -func Test_fillFromTIDStatWithContext_lx_brandz(t *testing.T) { +func TestFillFromTIDStatWithContext_lx_brandz(t *testing.T) { pids, err := os.ReadDir("testdata/lx_brandz/") if err != nil { t.Error(err) diff --git a/process/process_openbsd.go b/process/process_openbsd.go index a58c5eb11..7f85facb5 100644 --- a/process/process_openbsd.go +++ b/process/process_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd -// +build openbsd package process @@ -14,10 +14,10 @@ import ( "strings" "unsafe" - cpu "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - mem "github.com/shirou/gopsutil/v3/mem" - net "github.com/shirou/gopsutil/v3/net" + cpu "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + mem "github.com/shirou/gopsutil/v4/mem" + net "github.com/shirou/gopsutil/v4/net" "golang.org/x/sys/unix" ) @@ -68,7 +68,12 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { } func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError + mib := []int32{CTLKern, KernProcCwd, p.Pid} + buf, _, err := common.CallSyscall(mib) + if err != nil { + return "", err + } + return common.ByteToString(buf), nil } func (p *Process) ExeWithContext(ctx context.Context) (string, error) { @@ -171,40 +176,40 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return strings.IndexByte(string(out), '+') != -1, nil } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - uids := make([]int32, 0, 3) + uids := make([]uint32, 0, 3) - uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid)) + uids = append(uids, uint32(k.Ruid), uint32(k.Uid), uint32(k.Svuid)) return uids, nil } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid)) + gids := make([]uint32, 0, 3) + gids = append(gids, uint32(k.Rgid), uint32(k.Ngroups), uint32(k.Svgid)) return gids, nil } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { k, err := p.getKProc() if err != nil { return nil, err } - groups := make([]int32, k.Ngroups) + groups := make([]uint32, k.Ngroups) for i := int16(0); i < k.Ngroups; i++ { - groups[i] = int32(k.Groups[i]) + groups[i] = uint32(k.Groups[i]) } return groups, nil diff --git a/process/process_openbsd_386.go b/process/process_openbsd_386.go index f4ed02491..5b84706a7 100644 --- a/process/process_openbsd_386.go +++ b/process/process_openbsd_386.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && 386 -// +build openbsd,386 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs process/types_openbsd.go @@ -14,6 +14,7 @@ const ( KernProcProc = 8 KernProcPathname = 12 KernProcArgs = 55 + KernProcCwd = 78 KernProcArgv = 1 KernProcEnv = 3 ) diff --git a/process/process_openbsd_amd64.go b/process/process_openbsd_amd64.go index 8607422b5..3229bb32c 100644 --- a/process/process_openbsd_amd64.go +++ b/process/process_openbsd_amd64.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types_openbsd.go @@ -11,6 +12,7 @@ const ( KernProcProc = 8 KernProcPathname = 12 KernProcArgs = 55 + KernProcCwd = 78 KernProcArgv = 1 KernProcEnv = 3 ) diff --git a/process/process_openbsd_arm.go b/process/process_openbsd_arm.go index b94429f2e..6f74ce756 100644 --- a/process/process_openbsd_arm.go +++ b/process/process_openbsd_arm.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm -// +build openbsd,arm // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs process/types_openbsd.go @@ -14,6 +14,7 @@ const ( KernProcProc = 8 KernProcPathname = 12 KernProcArgs = 55 + KernProcCwd = 78 KernProcArgv = 1 KernProcEnv = 3 ) diff --git a/process/process_openbsd_arm64.go b/process/process_openbsd_arm64.go index a3291b8ca..910454562 100644 --- a/process/process_openbsd_arm64.go +++ b/process/process_openbsd_arm64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && arm64 -// +build openbsd,arm64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs process/types_openbsd.go @@ -14,6 +14,7 @@ const ( KernProcProc = 8 KernProcPathname = 12 KernProcArgs = 55 + KernProcCwd = 78 KernProcArgv = 1 KernProcEnv = 3 ) diff --git a/process/process_openbsd_riscv64.go b/process/process_openbsd_riscv64.go index 076f095ea..e3e0d36a0 100644 --- a/process/process_openbsd_riscv64.go +++ b/process/process_openbsd_riscv64.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build openbsd && riscv64 -// +build openbsd,riscv64 // Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs process/types_openbsd.go @@ -14,6 +14,7 @@ const ( KernProcProc = 8 KernProcPathname = 12 KernProcArgs = 55 + KernProcCwd = 78 KernProcArgv = 1 KernProcEnv = 3 ) diff --git a/process/process_plan9.go b/process/process_plan9.go index bc4bc062a..726758cae 100644 --- a/process/process_plan9.go +++ b/process/process_plan9.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build plan9 -// +build plan9 package process @@ -7,9 +7,9 @@ import ( "context" "syscall" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/net" ) type Signal = syscall.Note @@ -82,15 +82,15 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return false, common.ErrNotImplementedError } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } diff --git a/process/process_posix.go b/process/process_posix.go index a01f9ecfc..caa9d3f7c 100644 --- a/process/process_posix.go +++ b/process/process_posix.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux || freebsd || openbsd || darwin || solaris -// +build linux freebsd openbsd darwin solaris package process @@ -16,7 +16,7 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) type Signal = syscall.Signal diff --git a/process/process_posix_test.go b/process/process_posix_test.go index 201a58c90..2b1140493 100644 --- a/process/process_posix_test.go +++ b/process/process_posix_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build linux || freebsd -// +build linux freebsd package process diff --git a/process/process_race_test.go b/process/process_race_test.go index 93c078d50..74e96c028 100644 --- a/process/process_race_test.go +++ b/process/process_race_test.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build race -// +build race package process @@ -8,7 +8,7 @@ import ( "testing" ) -func Test_Process_Ppid_Race(t *testing.T) { +func TestPpid_Race(t *testing.T) { wg := sync.WaitGroup{} testCount := 10 p := testGetProcess() diff --git a/process/process_solaris.go b/process/process_solaris.go index dd4bd4760..04f86f16b 100644 --- a/process/process_solaris.go +++ b/process/process_solaris.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package process import ( @@ -7,9 +8,9 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/net" ) type MemoryMapsStat struct { @@ -95,15 +96,15 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { return false, common.ErrNotImplementedError } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } diff --git a/process/process_test.go b/process/process_test.go index 877992b25..5e1603290 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause package process import ( @@ -21,7 +22,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" ) var mu sync.Mutex @@ -38,7 +39,7 @@ func testGetProcess() Process { return *ret } -func Test_Pids(t *testing.T) { +func TestPids(t *testing.T) { ret, err := Pids() skipIfNotImplementedErr(t, err) if err != nil { @@ -49,7 +50,7 @@ func Test_Pids(t *testing.T) { } } -func Test_Pid_exists(t *testing.T) { +func TestPid_exists(t *testing.T) { checkPid := os.Getpid() ret, err := PidExists(int32(checkPid)) @@ -63,7 +64,7 @@ func Test_Pid_exists(t *testing.T) { } } -func Test_NewProcess(t *testing.T) { +func TestNewProcess(t *testing.T) { checkPid := os.Getpid() ret, err := NewProcess(int32(checkPid)) @@ -79,7 +80,7 @@ func Test_NewProcess(t *testing.T) { } } -func Test_Process_memory_maps(t *testing.T) { +func TestMemoryMaps(t *testing.T) { checkPid := os.Getpid() ret, err := NewProcess(int32(checkPid)) @@ -115,7 +116,7 @@ func Test_Process_memory_maps(t *testing.T) { } } -func Test_Process_MemoryInfo(t *testing.T) { +func TestMemoryInfo(t *testing.T) { p := testGetProcess() v, err := p.MemoryInfo() @@ -129,7 +130,7 @@ func Test_Process_MemoryInfo(t *testing.T) { } } -func Test_Process_CmdLine(t *testing.T) { +func TestCmdLine(t *testing.T) { p := testGetProcess() v, err := p.Cmdline() @@ -142,7 +143,7 @@ func Test_Process_CmdLine(t *testing.T) { } } -func Test_Process_CmdLineSlice(t *testing.T) { +func TestCmdLineSlice(t *testing.T) { p := testGetProcess() v, err := p.CmdlineSlice() @@ -155,7 +156,7 @@ func Test_Process_CmdLineSlice(t *testing.T) { } } -func Test_Process_Ppid(t *testing.T) { +func TestPpid(t *testing.T) { p := testGetProcess() v, err := p.Ppid() @@ -172,7 +173,7 @@ func Test_Process_Ppid(t *testing.T) { } } -func Test_Process_Status(t *testing.T) { +func TestStatus(t *testing.T) { p := testGetProcess() v, err := p.Status() @@ -188,7 +189,7 @@ func Test_Process_Status(t *testing.T) { } } -func Test_Process_Terminal(t *testing.T) { +func TestTerminal(t *testing.T) { p := testGetProcess() _, err := p.Terminal() @@ -198,7 +199,7 @@ func Test_Process_Terminal(t *testing.T) { } } -func Test_Process_IOCounters(t *testing.T) { +func TestIOCounters(t *testing.T) { p := testGetProcess() v, err := p.IOCounters() @@ -213,7 +214,7 @@ func Test_Process_IOCounters(t *testing.T) { } } -func Test_Process_NumCtx(t *testing.T) { +func TestNumCtx(t *testing.T) { p := testGetProcess() _, err := p.NumCtxSwitches() @@ -224,7 +225,7 @@ func Test_Process_NumCtx(t *testing.T) { } } -func Test_Process_Nice(t *testing.T) { +func TestNice(t *testing.T) { p := testGetProcess() // https://github.com/shirou/gopsutil/issues/1532 @@ -242,7 +243,7 @@ func Test_Process_Nice(t *testing.T) { } } -func Test_Process_Groups(t *testing.T) { +func TestGroups(t *testing.T) { p := testGetProcess() v, err := p.Groups() @@ -258,7 +259,7 @@ func Test_Process_Groups(t *testing.T) { } } -func Test_Process_NumThread(t *testing.T) { +func TestNumThread(t *testing.T) { p := testGetProcess() n, err := p.NumThreads() @@ -271,7 +272,7 @@ func Test_Process_NumThread(t *testing.T) { } } -func Test_Process_Threads(t *testing.T) { +func TestThreads(t *testing.T) { p := testGetProcess() n, err := p.NumThreads() @@ -293,7 +294,7 @@ func Test_Process_Threads(t *testing.T) { } } -func Test_Process_Name(t *testing.T) { +func TestName(t *testing.T) { p := testGetProcess() n, err := p.Name() @@ -306,7 +307,7 @@ func Test_Process_Name(t *testing.T) { } } -func Test_Process_Long_Name_With_Spaces(t *testing.T) { +func TestLong_Name_With_Spaces(t *testing.T) { tmpdir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("unable to create temp dir %v", err) @@ -352,7 +353,7 @@ func Test_Process_Long_Name_With_Spaces(t *testing.T) { cmd.Process.Kill() } -func Test_Process_Long_Name(t *testing.T) { +func TestLong_Name(t *testing.T) { tmpdir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("unable to create temp dir %v", err) @@ -398,7 +399,7 @@ func Test_Process_Long_Name(t *testing.T) { cmd.Process.Kill() } -func Test_Process_Name_Against_Python(t *testing.T) { +func TestName_Against_Python(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("only applies to posix") } @@ -454,7 +455,7 @@ func Test_Process_Name_Against_Python(t *testing.T) { } } -func Test_Process_Exe(t *testing.T) { +func TestExe(t *testing.T) { p := testGetProcess() n, err := p.Exe() @@ -467,7 +468,7 @@ func Test_Process_Exe(t *testing.T) { } } -func Test_Process_CpuPercent(t *testing.T) { +func TestCpuPercent(t *testing.T) { p := testGetProcess() _, err := p.Percent(0) skipIfNotImplementedErr(t, err) @@ -488,7 +489,7 @@ func Test_Process_CpuPercent(t *testing.T) { } } -func Test_Process_CpuPercentLoop(t *testing.T) { +func TestCpuPercentLoop(t *testing.T) { p := testGetProcess() numcpu := runtime.NumCPU() @@ -506,7 +507,7 @@ func Test_Process_CpuPercentLoop(t *testing.T) { } } -func Test_Process_CreateTime(t *testing.T) { +func TestCreateTime(t *testing.T) { if os.Getenv("CI") == "true" { t.Skip("Skip CI") } @@ -531,7 +532,7 @@ func Test_Process_CreateTime(t *testing.T) { } } -func Test_Parent(t *testing.T) { +func TestParent(t *testing.T) { p := testGetProcess() c, err := p.Parent() @@ -547,7 +548,7 @@ func Test_Parent(t *testing.T) { } } -func Test_Connections(t *testing.T) { +func TestConnections(t *testing.T) { p := testGetProcess() addr, err := net.ResolveTCPAddr("tcp", "localhost:0") // dynamically get a random open port from OS @@ -630,7 +631,7 @@ func Test_Connections(t *testing.T) { } } -func Test_Children(t *testing.T) { +func TestChildren(t *testing.T) { p := testGetProcess() var cmd *exec.Cmd @@ -662,7 +663,7 @@ func Test_Children(t *testing.T) { } } -func Test_Username(t *testing.T) { +func TestUsername(t *testing.T) { myPid := os.Getpid() currentUser, _ := user.Current() myUsername := currentUser.Username @@ -675,7 +676,7 @@ func Test_Username(t *testing.T) { t.Log(pidUsername) } -func Test_CPUTimes(t *testing.T) { +func TestCPUTimes(t *testing.T) { pid := os.Getpid() process, err := NewProcess(int32(pid)) skipIfNotImplementedErr(t, err) @@ -707,7 +708,7 @@ func Test_CPUTimes(t *testing.T) { assert.True(t, measuredElapsed < float64(spinSeconds)*5, message) } -func Test_OpenFiles(t *testing.T) { +func TestOpenFiles(t *testing.T) { fp, err := os.Open("process_test.go") assert.Nil(t, err) defer func() { @@ -730,7 +731,7 @@ func Test_OpenFiles(t *testing.T) { } } -func Test_Kill(t *testing.T) { +func TestKill(t *testing.T) { var cmd *exec.Cmd if runtime.GOOS == "windows" { cmd = exec.Command("ping", "localhost", "-n", "4") @@ -748,7 +749,7 @@ func Test_Kill(t *testing.T) { cmd.Wait() } -func Test_IsRunning(t *testing.T) { +func TestIsRunning(t *testing.T) { var cmd *exec.Cmd if runtime.GOOS == "windows" { cmd = exec.Command("ping", "localhost", "-n", "2") @@ -778,7 +779,7 @@ func Test_IsRunning(t *testing.T) { } } -func Test_Process_Environ(t *testing.T) { +func TestEnviron(t *testing.T) { tmpdir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("unable to create temp dir %v", err) @@ -832,7 +833,7 @@ func Test_Process_Environ(t *testing.T) { } } -func Test_Process_Cwd(t *testing.T) { +func TestCwd(t *testing.T) { myPid := os.Getpid() currentWorkingDirectory, _ := os.Getwd() diff --git a/process/process_windows.go b/process/process_windows.go index f2053d985..f3111649a 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package process @@ -18,9 +18,9 @@ import ( "unicode/utf16" "unsafe" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/shirou/gopsutil/v4/net" "golang.org/x/sys/windows" ) @@ -466,15 +466,15 @@ func (p *Process) UsernameWithContext(ctx context.Context) (string, error) { return domain + "\\" + user, err } -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) UidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GidsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { +func (p *Process) GroupsWithContext(ctx context.Context) ([]uint32, error) { return nil, common.ErrNotImplementedError } diff --git a/process/process_windows_32bit.go b/process/process_windows_32bit.go index db4d45334..2b231c79d 100644 --- a/process/process_windows_32bit.go +++ b/process/process_windows_32bit.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build (windows && 386) || (windows && arm) -// +build windows,386 windows,arm package process @@ -8,7 +8,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" ) diff --git a/process/process_windows_64bit.go b/process/process_windows_64bit.go index 74c6212cf..befe52139 100644 --- a/process/process_windows_64bit.go +++ b/process/process_windows_64bit.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build (windows && amd64) || (windows && arm64) -// +build windows,amd64 windows,arm64 package process @@ -7,7 +7,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" ) diff --git a/process/types_darwin.go b/process/types_darwin.go index 3cde887d3..7dc9351dd 100644 --- a/process/types_darwin.go +++ b/process/types_darwin.go @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -6,7 +7,6 @@ // - all pointer in ExternProc to uint64 //go:build ignore -// +build ignore /* Input to cgo -godefs. diff --git a/process/types_freebsd.go b/process/types_freebsd.go index 8dce06266..47d2bb894 100644 --- a/process/types_freebsd.go +++ b/process/types_freebsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // We still need editing by hands. // go tool cgo -godefs types_freebsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_freebsd_amd64.go diff --git a/process/types_openbsd.go b/process/types_openbsd.go index 75f2344a9..73a885607 100644 --- a/process/types_openbsd.go +++ b/process/types_openbsd.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build ignore -// +build ignore // We still need editing by hands. // go tool cgo -godefs types_openbsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_openbsd_amd64.go @@ -44,6 +44,7 @@ const ( KernProcProc = 8 // only return procs KernProcPathname = 12 // path to executable KernProcArgs = 55 // get/set arguments/proctitle + KernProcCwd = 78 // get current working directory KernProcArgv = 1 KernProcEnv = 3 ) diff --git a/sensors/ex_linux.go b/sensors/ex_linux.go new file mode 100644 index 000000000..081d64f36 --- /dev/null +++ b/sensors/ex_linux.go @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build linux + +package sensors + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" +) + +// ExTemperature represents Linux dependent temperature sensor data +type ExTemperature struct { + SensorKey string `json:"key"` + Min float64 `json:"min"` // Temperature min value. + Lowest float64 `json:"lowest"` // Historical minimum temperature + Highest float64 `json:"highest"` // Historical maximum temperature +} + +type ExLinux struct{} + +func NewExLinux() *ExLinux { + return &ExLinux{} +} + +func (ex *ExLinux) TemperatureWithContext(ctx context.Context) ([]ExTemperature, error) { + var warns Warnings + + files, err := getTemperatureFiles(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get temperature files, %w", err) + } + + temperatures := make([]ExTemperature, 0, len(files)) + for _, file := range files { + var raw []byte + + // 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 /temp1 + basepath := filepath.Join(directory, basename) + + // Get the label of the temperature you are reading + label := "" + + if raw, _ = os.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 + if raw, err = os.ReadFile(filepath.Join(directory, "name")); err != nil { + warns.Add(err) + continue + } + + name := strings.TrimSpace(string(raw)) + + if label != "" { + name = name + "_" + label + } + + // Add discovered temperature sensor to the list + temperatures = append(temperatures, ExTemperature{ + SensorKey: name, + Min: optionalValueReadFromFile(basepath+"_min") / hostTemperatureScale, + Lowest: optionalValueReadFromFile(basepath+"_lowest") / hostTemperatureScale, + Highest: optionalValueReadFromFile(basepath+"_highest") / hostTemperatureScale, + }) + } + + return temperatures, warns.Reference() +} diff --git a/sensors/sensors.go b/sensors/sensors.go new file mode 100644 index 000000000..feb399626 --- /dev/null +++ b/sensors/sensors.go @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: BSD-3-Clause + +package sensors + +import ( + "context" + "encoding/json" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +type Warnings = common.Warnings + +var invoke common.Invoker = common.Invoke{} + +type TemperatureStat struct { + SensorKey string `json:"sensorKey"` + Temperature float64 `json:"temperature"` + High float64 `json:"sensorHigh"` + Critical float64 `json:"sensorCritical"` +} + +func (t TemperatureStat) String() string { + s, _ := json.Marshal(t) + return string(s) +} + +func SensorsTemperatures() ([]TemperatureStat, error) { + return TemperaturesWithContext(context.Background()) +} diff --git a/sensors/sensors_aix.go b/sensors/sensors_aix.go new file mode 100644 index 000000000..d40f2b073 --- /dev/null +++ b/sensors/sensors_aix.go @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build aix + +package sensors + +import ( + "context" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +const ( + hostTemperatureScale = 1000.0 // Not part of the linked file, but kept just in case it becomes relevant +) + +func VirtualizationWithContext(ctx context.Context) (string, string, error) { + return "", "", common.ErrNotImplementedError +} diff --git a/host/host_darwin_cgo.go b/sensors/sensors_darwin_cgo.go similarity index 68% rename from host/host_darwin_cgo.go rename to sensors/sensors_darwin_cgo.go index ffdc7b78f..153cf0721 100644 --- a/host/host_darwin_cgo.go +++ b/sensors/sensors_darwin_cgo.go @@ -1,14 +1,17 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build darwin && cgo -// +build darwin,cgo -package host +package sensors // #cgo LDFLAGS: -framework IOKit // #include "smc_darwin.h" import "C" -import "context" +import ( + "context" + "unsafe" +) -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { temperatureKeys := []string{ C.AMBIENT_AIR_0, C.AMBIENT_AIR_1, @@ -34,13 +37,15 @@ func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, err } var temperatures []TemperatureStat - C.gopsutil_v3_open_smc() - defer C.gopsutil_v3_close_smc() + C.gopsutil_v4_open_smc() + defer C.gopsutil_v4_close_smc() for _, key := range temperatureKeys { + ckey := C.CString(key) + defer C.free(unsafe.Pointer(ckey)) temperatures = append(temperatures, TemperatureStat{ SensorKey: key, - Temperature: float64(C.gopsutil_v3_get_temperature(C.CString(key))), + Temperature: float64(C.gopsutil_v4_get_temperature(ckey)), }) } return temperatures, nil diff --git a/sensors/sensors_darwin_nocgo.go b/sensors/sensors_darwin_nocgo.go new file mode 100644 index 000000000..45c85069e --- /dev/null +++ b/sensors/sensors_darwin_nocgo.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build darwin && !cgo + +package sensors + +import ( + "context" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + return []TemperatureStat{}, common.ErrNotImplementedError +} diff --git a/sensors/sensors_fallback.go b/sensors/sensors_fallback.go new file mode 100644 index 000000000..ec5c0c5b2 --- /dev/null +++ b/sensors/sensors_fallback.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !aix + +package sensors + +import ( + "context" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + return []TemperatureStat{}, common.ErrNotImplementedError +} diff --git a/sensors/sensors_freebsd.go b/sensors/sensors_freebsd.go new file mode 100644 index 000000000..f7bb29c4f --- /dev/null +++ b/sensors/sensors_freebsd.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build freebsd + +package freebsd + +import ( + "context" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + return []TemperatureStat{}, common.ErrNotImplementedError +} diff --git a/sensors/sensors_linux.go b/sensors/sensors_linux.go new file mode 100644 index 000000000..6899d2dcc --- /dev/null +++ b/sensors/sensors_linux.go @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build linux + +package sensors + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +// from utmp.h +const ( + hostTemperatureScale = 1000.0 +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + var warns Warnings + + files, err := getTemperatureFiles(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get tempreteure files, %w", err) + } + + if len(files) == 0 { // handle distributions without hwmon, like raspbian #391, parse legacy thermal_zone files + files, err = filepath.Glob(common.HostSysWithContext(ctx, "/class/thermal/thermal_zone*/")) + if err != nil { + return nil, err + } + temperatures := make([]TemperatureStat, 0, len(files)) + + for _, file := range files { + // Get the name of the temperature you are reading + name, err := os.ReadFile(filepath.Join(file, "type")) + if err != nil { + warns.Add(err) + continue + } + // Get the temperature reading + current, err := os.ReadFile(filepath.Join(file, "temp")) + if err != nil { + warns.Add(err) + continue + } + temperature, err := strconv.ParseInt(strings.TrimSpace(string(current)), 10, 64) + if err != nil { + warns.Add(err) + continue + } + + temperatures = append(temperatures, TemperatureStat{ + SensorKey: strings.TrimSpace(string(name)), + Temperature: float64(temperature) / 1000.0, + }) + } + 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 + // power/ temp1_label temp2_label temp3_label temp4_label temp5_label temp6_label temp7_label + // 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 { + 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 /temp1 + basepath := filepath.Join(directory, basename) + + // Get the label of the temperature you are reading + label := "" + + if raw, _ = os.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 + if raw, err = os.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 + if raw, err = os.ReadFile(file); err != nil { + warns.Add(err) + continue + } + + if temperature, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { + warns.Add(err) + continue + } + + // Add discovered temperature sensor to the list + temperatures = append(temperatures, TemperatureStat{ + SensorKey: name, + Temperature: temperature / hostTemperatureScale, + High: optionalValueReadFromFile(basepath+"_max") / hostTemperatureScale, + Critical: optionalValueReadFromFile(basepath+"_crit") / hostTemperatureScale, + }) + } + + return temperatures, warns.Reference() +} + +func getTemperatureFiles(ctx context.Context) ([]string, error) { + var files []string + var err error + + // 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.HostSysWithContext(ctx, "/class/hwmon/hwmon*/temp*_input")); err != nil { + return nil, err + } + + if len(files) == 0 { + // CentOS has an intermediate /device directory: + // https://github.com/giampaolo/psutil/issues/971 + if files, err = filepath.Glob(common.HostSysWithContext(ctx, "/class/hwmon/hwmon*/device/temp*_input")); err != nil { + return nil, err + } + } + + return files, nil +} + +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 = os.ReadFile(filename); err != nil { + return 0 + } + + if value, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { + return 0 + } + + return value +} diff --git a/sensors/sensors_netbsd.go b/sensors/sensors_netbsd.go new file mode 100644 index 000000000..f2e2f7f2a --- /dev/null +++ b/sensors/sensors_netbsd.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build netbsd + +package sensors + +import ( + "context" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + return []TemperatureStat{}, common.ErrNotImplementedError +} diff --git a/sensors/sensors_openbsd.go b/sensors/sensors_openbsd.go new file mode 100644 index 000000000..8ae3198e0 --- /dev/null +++ b/sensors/sensors_openbsd.go @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build openbsd + +package openbsd + +import ( + "context" + + "github.com/shirou/gopsutil/v4/internal/common" +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + return []TemperatureStat{}, common.ErrNotImplementedError +} diff --git a/sensors/sensors_solaris.go b/sensors/sensors_solaris.go new file mode 100644 index 000000000..c5d1bce8d --- /dev/null +++ b/sensors/sensors_solaris.go @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build solaris + +package sensors + +import ( + "context" + "encoding/csv" + "io" + "strconv" + "strings" +) + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + var ret []TemperatureStat + + out, err := invoke.CommandWithContext(ctx, "ipmitool", "-c", "sdr", "list") + if err != nil { + return ret, err + } + + r := csv.NewReader(strings.NewReader(string(out))) + // Output may contain errors, e.g. "bmc_send_cmd: Permission denied", don't expect a consistent number of records + r.FieldsPerRecord = -1 + for { + record, err := r.Read() + if err == io.EOF { + break + } + if err != nil { + return ret, err + } + // CPU1 Temp,40,degrees C,ok + if len(record) < 3 || record[1] == "" || record[2] != "degrees C" { + continue + } + v, err := strconv.ParseFloat(record[1], 64) + if err != nil { + return ret, err + } + ts := TemperatureStat{ + SensorKey: strings.TrimSuffix(record[0], " Temp"), + Temperature: v, + } + ret = append(ret, ts) + } + + return ret, nil +} diff --git a/sensors/sensors_test.go b/sensors/sensors_test.go new file mode 100644 index 000000000..454316a9c --- /dev/null +++ b/sensors/sensors_test.go @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BSD-3-Clause + +package sensors + +import ( + "fmt" + "testing" +) + +func TestTemperatureStat_String(t *testing.T) { + v := TemperatureStat{ + SensorKey: "CPU", + Temperature: 1.1, + High: 30.1, + Critical: 0.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, %v", fmt.Sprintf("%v", v)) + } +} diff --git a/sensors/sensors_windows.go b/sensors/sensors_windows.go new file mode 100644 index 000000000..32b9ee492 --- /dev/null +++ b/sensors/sensors_windows.go @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BSD-3-Clause +//go:build windows + +package sensors + +import ( + "context" + "math" + + "github.com/shirou/gopsutil/v4/internal/common" + "github.com/yusufpapurcu/wmi" +) + +type msAcpi_ThermalZoneTemperature struct { + Active bool + CriticalTripPoint uint32 + CurrentTemperature uint32 + InstanceName string +} + +func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { + var ret []TemperatureStat + var dst []msAcpi_ThermalZoneTemperature + q := wmi.CreateQuery(&dst, "") + if err := common.WMIQueryWithContext(ctx, q, &dst, nil, "root/wmi"); err != nil { + return ret, err + } + + for _, v := range dst { + ts := TemperatureStat{ + SensorKey: v.InstanceName, + Temperature: kelvinToCelsius(v.CurrentTemperature, 2), + } + ret = append(ret, ts) + } + + return ret, nil +} + +func kelvinToCelsius(temp uint32, n int) float64 { + // wmi return temperature Kelvin * 10, so need to divide the result by 10, + // and then minus 273.15 to get °Celsius. + t := float64(temp/10) - 273.15 + n10 := math.Pow10(n) + return math.Trunc((t+0.5/n10)*n10) / n10 +} diff --git a/host/smc_darwin.c b/sensors/smc_darwin.c similarity index 94% rename from host/smc_darwin.c rename to sensors/smc_darwin.c index 0197d95b4..c91a90cd0 100644 --- a/host/smc_darwin.c +++ b/sensors/smc_darwin.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause #include #include #include "smc_darwin.h" @@ -68,7 +69,7 @@ typedef struct { static const int SMC_KEY_SIZE = 4; // number of characters in an SMC key. static io_connect_t conn; // our connection to the SMC. -kern_return_t gopsutil_v3_open_smc(void) { +kern_return_t gopsutil_v4_open_smc(void) { kern_return_t result; io_service_t service; @@ -85,7 +86,7 @@ kern_return_t gopsutil_v3_open_smc(void) { return result; } -kern_return_t gopsutil_v3_close_smc(void) { return IOServiceClose(conn); } +kern_return_t gopsutil_v4_close_smc(void) { return IOServiceClose(conn); } static uint32_t to_uint32(char *key) { uint32_t ans = 0; @@ -154,7 +155,7 @@ static kern_return_t read_smc(char *key, smc_return_t *result_smc) { return result; } -double gopsutil_v3_get_temperature(char *key) { +double gopsutil_v4_get_temperature(char *key) { kern_return_t result; smc_return_t result_smc; diff --git a/host/smc_darwin.h b/sensors/smc_darwin.h similarity index 83% rename from host/smc_darwin.h rename to sensors/smc_darwin.h index e3013abdb..e49abb512 100644 --- a/host/smc_darwin.h +++ b/sensors/smc_darwin.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: BSD-3-Clause #ifndef __SMC_H__ #define __SMC_H__ 1 @@ -25,8 +26,8 @@ #define THUNDERBOLT_1 "TI1P" #define WIRELESS_MODULE "TW0P" -kern_return_t gopsutil_v3_open_smc(void); -kern_return_t gopsutil_v3_close_smc(void); -double gopsutil_v3_get_temperature(char *); +kern_return_t gopsutil_v4_open_smc(void); +kern_return_t gopsutil_v4_close_smc(void); +double gopsutil_v4_get_temperature(char *); #endif // __SMC_H__ diff --git a/winservices/manager.go b/winservices/manager.go index c9957f729..07a56af1a 100644 --- a/winservices/manager.go +++ b/winservices/manager.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package winservices diff --git a/winservices/winservices.go b/winservices/winservices.go index 93ec0e104..0c85a0179 100644 --- a/winservices/winservices.go +++ b/winservices/winservices.go @@ -1,5 +1,5 @@ +// SPDX-License-Identifier: BSD-3-Clause //go:build windows -// +build windows package winservices