diff --git a/.github/labeler.yml b/.github/labeler.yml index 4b43d26..dde462a 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 09093cd..9aea984 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 7e5a66d..bdd22a7 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 864b1f6..da1cca5 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 fea8e7e..1e21451 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 1cd739e..0000000 --- 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 eb826f4..0000000 --- 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 39f65e8..0000000 --- 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 4b5f498..4acad1f 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 f759a46..0000000 --- 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 83bc23d..56f53c3 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 1439d1d..bc766bd 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 9c1e70b..559dc5f 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 a77b4db..329ef83 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 41f395e..79a458b 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 1d5f077..3a02024 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 e067e99..1af8566 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 a958623..5548cf9 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 fef53e5..19b1e9d 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 57e1452..25ececa 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 089f603..245c1ec 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 d3f4735..c68d6bf 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 8b7f4c3..e4799bc 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 57e1452..25ececa 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 8b7f4c3..e4799bc 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 57e1452..25ececa 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 27a709d..33334f8 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 da467e2..f78c61a 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 e06f305..f67d071 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 1f66be3..2cda5cd 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 57e1452..25ececa 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 57e1452..25ececa 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 fe33290..33233d3 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 5e87839..40a6f43 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 d659058..464156d 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 5e87839..40a6f43 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 d659058..464156d 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 d659058..464156d 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 a2e99d8..bff2e0c 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 2820a3f..9413e2a 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 4231ad1..d8ba1d3 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 dd9362c..527d985 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 688660a..2e4dd30 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 e10612f..4476b91 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 0000000..7d4d93a --- /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 0000000..2a3dc63 --- /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 0000000..e3dbb13 --- /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 0d4b253..310ea04 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 bc71712..3fe7fae 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 aa534df..a0d0829 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 17e2b9c..e427325 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 9362d9e..6ed7400 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 27c24c9..3a98b61 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 1f099b7..8d55ca3 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 36525f6..17f0f7b 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 9b53106..10006fe 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 7fa1783..4660b14 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 d86a308..3f43631 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 7fa1783..4660b14 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 f6b3f80..15fae41 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 ada9f9e..e94d212 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 d313737..b376f87 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 c21421c..c4b903f 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 dfe48f8..d01c864 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 81ff239..713e38e 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 f4c139f..66e1795 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 c1bd52e..9070ff0 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 86054a6..f23a293 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 ae1cf57..465296e 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 8374b94..3620c16 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 5d6ea86..f849da9 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 5adae5c..534577c 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 1e73524..d69d838 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 e17db3e..86d6a4e 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 8aab04f..ba1e4c5 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 cb9ec7a..7b702aa 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 47f5551..6fc14fe 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 c0326f5..63a6aec 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 abb43c8..2329fb9 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 6a65fe2..fc471f6 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 dda7ba0..1c0abca 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 4904874..f3409d9 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 5ef80f9..2d0f35b 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 434ca12..ca7a7f9 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 1d6e6bf..14ee186 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 aa8157a..c5ed8bd 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 1c0a781..64e8112 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 ee94863..b69d2f6 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 0000000..7d66666 --- /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 0000000..de9674b --- /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 f9a2961..b67f8fb 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 873ed4a..068f106 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 8caeed2..1efc353 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 293bd4d..512e569 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 6285ba9..0000000 --- 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 a393ca1..bc83979 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 9a5382d..97aa05a 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 88453d2..0d31eb1 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 8af74b0..603a0ba 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 f7d6ede..5021f5e 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 41bec3c..4fe188b 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 5d4c1a9..04bda6c 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 46e0c5d..3e241b1 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 1e57448..480e72d 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 7abbbb8..1b7ee97 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 cd0b4dd..0e6fc8b 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 edf1be5..c4c8390 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 50207e5..8aa049c 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 50207e5..8aa049c 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 50207e5..8aa049c 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 50207e5..8aa049c 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 5b324ef..23f5cb9 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 51f5bee..e81f123 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 bb03a0b..080fdb8 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 6ea432a..738af60 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 c114ec7..84763ab 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 488f1df..f3cddb7 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 325015c..f21c5e8 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 b299d7a..df820a4 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 2d23b9b..b1d674e 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 f0ac57d..e5f1590 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 20fb42d..d8c1061 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 7a123b6..584004b 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 e7e0d83..91ab6ae 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 fef67f8..371cc98 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 d3b7585..24b1371 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 b83ad6d..7daad6f 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 3378cff..4e35ab7 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 79154d7..50a62d4 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 2b087b1..b225af1 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 81cdd53..fe1e5b9 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 5e8d43d..6e75e74 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 5e25e50..642aabc 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 f1a7845..53f9ae8 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 f590e2e..53cdcee 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 8f36c70..89a682e 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 efbc710..2065321 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 58d76f3..00fa19a 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 424ea26..77db9b4 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 4af7e5c..2715b89 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 301b231..766ed2f 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 147cfdc..113ff2e 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 94cedfd..504f13f 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 aadc766..d3205c2 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 a4aaada..888cc57 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 0da5090..ec48a07 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 78b3912..eb5b5b0 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 bbbf287..e325432 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 25d50ac..cfb4117 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 51d9286..97001f3 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 ce80188..fb7d5c0 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 3e41fd1..e633066 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 4069805..3e35f3f 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 daf2614..e964b69 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 1d5d611..df00588 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 99b339b..3713f4a 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 1790fa5..38e032b 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 5241dfa..a55c7b4 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 0000000..0a12fe2 --- /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 0000000..4f1573b --- /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 edaf268..0da71a9 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 22a6a4e..916bff3 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 67e11df..2d03dd0 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 cc6a76d..bc3c0ed 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 ef867d7..4f3e57c 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 9839a04..8b0eb9f 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 a05a0fa..a33c5f1 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 e5da7dc..cc6657d 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 c939316..097a93e 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 4e0d9a0..c7f5668 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 697fd87..ba882c8 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 9a56785..d9cae71 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 214a91e..05bfdaf 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 6b6fb78..390621d 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 d1f54ec..0a41b3e 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 e37d5ab..2510bb0 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 de2b26c..552e93f 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 d187abf..73e5b72 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 2488f18..57b5861 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 3661b16..f39a645 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 7a7b480..f9f838f 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 b5259f8..c17a102 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 1ae353d..836d6c8 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 c911267..06d0d9a 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 0536020..5e0aa70 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 79ddb0f..c069a4a 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 8c7fb1a..4666cbd 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 8e0e412..f71a457 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 9d8cf8e..e2327fb 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 0f3a62f..3890eda 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 81feaa8..df59abe 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 8c34f88..a45a5b7 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 e3fce90..f63a21e 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 8a7b637..f86b7bf 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 0680d08..86ed126 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 e136be1..e62deee 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 bf8baf0..155a49c 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 20ca547..a46f1b9 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 bd5c958..0000000 --- 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 a45072e..0000000 --- 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 8897196..0000000 --- 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 eae0e71..b7ccaa8 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 25bbe49..b6c31dd 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 79d8ac3..b886066 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 72f4db9..60e8438 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 cb846e2..71fc3b9 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 5d38434..12f62cd 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 81aca01..c713f6b 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 1bb27ab..ba27662 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 263829f..dcc0561 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 176661c..5231007 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 b353e5e..a135224 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 cbd6bdc..f1f3df3 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 858f08e..bbdfc96 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 d903474..129bb60 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 1a5d0c4..23793e9 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 40b10e1..3d21183 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 08ab333..279ba9f 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 560e627..f3b70ec 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 81ae0b9..75ed306 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 73ac082..3dc301c 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 557435b..8f1d6c8 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 87df812..9b9b77a 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 a58c5eb..7f85fac 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 f4ed024..5b84706 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 8607422..3229bb3 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 b94429f..6f74ce7 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 a3291b8..9104545 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 076f095..e3e0d36 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 bc4bc06..726758c 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 a01f9ec..caa9d3f 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 201a58c..2b11404 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 93c078d..74e96c0 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 dd4bd47..04f86f1 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 877992b..5e16032 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 f2053d9..f311164 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 db4d453..2b231c7 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 74c6212..befe521 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 3cde887..7dc9351 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 8dce062..47d2bb8 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 75f2344..73a8856 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 0000000..081d64f --- /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 0000000..feb3996 --- /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 0000000..d40f2b0 --- /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 ffdc7b7..153cf07 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 0000000..45c8506 --- /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 0000000..ec5c0c5 --- /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 0000000..f7bb29c --- /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 0000000..6899d2d --- /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 0000000..f2e2f7f --- /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 0000000..8ae3198 --- /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 0000000..c5d1bce --- /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 0000000..454316a --- /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 0000000..32b9ee4 --- /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 0197d95..c91a90c 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 e3013ab..e49abb5 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 c9957f7..07a56af 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 93ec0e1..0c85a01 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