├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── SECURITY.md ├── dependabot.yml ├── labeler.yml ├── release.yml └── workflows │ ├── build_test.yml │ ├── labeler.yml │ ├── lint.yml │ ├── release.yml │ ├── sbom_generator.yml │ ├── shellcheck.yml │ └── test.yml ├── .gitignore ├── .golangci.yml ├── LICENSE ├── Makefile ├── README.md ├── common └── env.go ├── cpu ├── cpu.go ├── cpu_aix.go ├── cpu_aix_cgo.go ├── cpu_aix_nocgo.go ├── cpu_darwin.go ├── cpu_darwin_arm64.go ├── cpu_darwin_fallback.go ├── cpu_darwin_test.go ├── cpu_dragonfly.go ├── cpu_dragonfly_amd64.go ├── cpu_fallback.go ├── cpu_freebsd.go ├── cpu_freebsd_386.go ├── cpu_freebsd_amd64.go ├── cpu_freebsd_arm.go ├── cpu_freebsd_arm64.go ├── cpu_freebsd_test.go ├── cpu_linux.go ├── cpu_linux_test.go ├── cpu_netbsd.go ├── cpu_netbsd_amd64.go ├── cpu_netbsd_arm.go ├── cpu_netbsd_arm64.go ├── cpu_openbsd.go ├── cpu_openbsd_386.go ├── cpu_openbsd_amd64.go ├── cpu_openbsd_arm.go ├── cpu_openbsd_arm64.go ├── cpu_openbsd_riscv64.go ├── cpu_plan9.go ├── cpu_plan9_test.go ├── cpu_solaris.go ├── cpu_solaris_test.go ├── cpu_test.go ├── cpu_windows.go └── testdata │ ├── aix │ ├── prtconf │ ├── sar-u-PALL101 │ └── sar-u101 │ ├── freebsd │ ├── 1cpu_2core.txt │ ├── 1cpu_4core.txt │ └── 2cpu_4core.txt │ ├── linux │ ├── 424 │ │ └── proc │ │ │ └── stat │ ├── 1037 │ │ └── proc │ │ │ └── cpuinfo │ └── times_empty │ │ └── proc │ │ └── stat │ ├── plan9 │ └── 2cores │ │ ├── dev │ │ ├── cputype │ │ ├── sysstat │ │ └── time │ │ └── proc │ │ ├── 1 │ │ └── status │ │ ├── 72 │ │ └── status │ │ ├── 331 │ │ └── .gitkeep │ │ ├── 54384 │ │ └── status │ │ └── 54412 │ │ └── status │ └── solaris │ ├── 1cpu_1core_isainfo.txt │ ├── 1cpu_1core_psrinfo.txt │ ├── 2cpu_12core_isainfo.txt │ ├── 2cpu_12core_psrinfo.txt │ ├── 2cpu_1core_isainfo.txt │ ├── 2cpu_1core_psrinfo.txt │ ├── 2cpu_8core_isainfo.txt │ └── 2cpu_8core_psrinfo.txt ├── disk ├── disk.go ├── disk_aix.go ├── disk_aix_cgo.go ├── disk_aix_nocgo.go ├── disk_darwin.go ├── disk_fallback.go ├── disk_freebsd.go ├── disk_freebsd_386.go ├── disk_freebsd_amd64.go ├── disk_freebsd_arm.go ├── disk_freebsd_arm64.go ├── disk_linux.go ├── disk_netbsd.go ├── disk_netbsd_amd64.go ├── disk_netbsd_arm.go ├── disk_netbsd_arm64.go ├── disk_openbsd.go ├── disk_openbsd_386.go ├── disk_openbsd_amd64.go ├── disk_openbsd_arm.go ├── disk_openbsd_arm64.go ├── disk_openbsd_riscv64.go ├── disk_solaris.go ├── disk_test.go ├── disk_unix.go ├── disk_windows.go ├── types_freebsd.go ├── types_netbsd.go └── types_openbsd.go ├── doc.go ├── docker ├── docker.go ├── docker_linux.go ├── docker_linux_test.go ├── docker_notlinux.go └── main_test.go ├── go.mod ├── go.sum ├── host ├── freebsd_headers │ └── utxdb.h ├── host.go ├── host_aix.go ├── host_aix_ppc64.go ├── host_aix_test.go ├── host_bsd.go ├── host_darwin.go ├── host_darwin_amd64.go ├── host_darwin_arm64.go ├── host_fallback.go ├── host_freebsd.go ├── host_freebsd_386.go ├── host_freebsd_amd64.go ├── host_freebsd_arm.go ├── host_freebsd_arm64.go ├── host_linux.go ├── host_linux_386.go ├── host_linux_amd64.go ├── host_linux_arm.go ├── host_linux_arm64.go ├── host_linux_loong64.go ├── host_linux_mips.go ├── host_linux_mips64.go ├── host_linux_mips64le.go ├── host_linux_mipsle.go ├── host_linux_ppc64.go ├── host_linux_ppc64le.go ├── host_linux_riscv64.go ├── host_linux_s390x.go ├── host_linux_test.go ├── host_netbsd.go ├── host_openbsd.go ├── host_openbsd_386.go ├── host_openbsd_amd64.go ├── host_openbsd_arm.go ├── host_openbsd_arm64.go ├── host_openbsd_riscv64.go ├── host_posix.go ├── host_solaris.go ├── host_test.go ├── host_windows.go ├── testdata │ └── linux │ │ └── lsbStruct │ │ ├── arch │ │ └── lsb-release │ │ └── ubuntu_22_04 │ │ └── lsb-release ├── types_darwin.go ├── types_freebsd.go ├── types_linux.go └── types_openbsd.go ├── internal └── common │ ├── binary.go │ ├── common.go │ ├── common_darwin.go │ ├── common_freebsd.go │ ├── common_linux.go │ ├── common_netbsd.go │ ├── common_openbsd.go │ ├── common_test.go │ ├── common_testing.go │ ├── common_unix.go │ ├── common_windows.go │ ├── endian.go │ ├── sleep.go │ ├── sleep_test.go │ └── warnings.go ├── load ├── load.go ├── load_aix.go ├── load_aix_cgo.go ├── load_aix_nocgo.go ├── load_bsd.go ├── load_darwin.go ├── load_fallback.go ├── load_freebsd.go ├── load_linux.go ├── load_openbsd.go ├── load_solaris.go ├── load_test.go └── load_windows.go ├── mem ├── ex_linux.go ├── ex_windows.go ├── mem.go ├── mem_aix.go ├── mem_aix_cgo.go ├── mem_aix_nocgo.go ├── mem_bsd.go ├── mem_bsd_test.go ├── mem_darwin.go ├── mem_darwin_test.go ├── mem_fallback.go ├── mem_freebsd.go ├── mem_linux.go ├── mem_linux_test.go ├── mem_netbsd.go ├── mem_openbsd.go ├── mem_openbsd_386.go ├── mem_openbsd_amd64.go ├── mem_openbsd_arm.go ├── mem_openbsd_arm64.go ├── mem_openbsd_riscv64.go ├── mem_plan9.go ├── mem_plan9_test.go ├── mem_solaris.go ├── mem_solaris_test.go ├── mem_test.go ├── mem_windows.go ├── testdata │ ├── linux │ │ └── virtualmemory │ │ │ ├── anonhugepages │ │ │ └── proc │ │ │ │ └── meminfo │ │ │ ├── intelcorei5 │ │ │ └── proc │ │ │ │ └── meminfo │ │ │ └── issue1002 │ │ │ └── proc │ │ │ └── meminfo │ └── plan9 │ │ └── virtualmemory │ │ └── dev │ │ └── swap └── types_openbsd.go ├── mktypes.sh ├── net ├── net.go ├── net_aix.go ├── net_aix_cgo.go ├── net_aix_nocgo.go ├── net_darwin.go ├── net_darwin_test.go ├── net_fallback.go ├── net_freebsd.go ├── net_linux.go ├── net_linux_test.go ├── net_openbsd.go ├── net_solaris.go ├── net_test.go ├── net_unix.go ├── net_windows.go └── types_darwin.go ├── process ├── process.go ├── process_bsd.go ├── process_darwin.go ├── process_darwin_amd64.go ├── process_darwin_arm64.go ├── process_fallback.go ├── process_freebsd.go ├── process_freebsd_386.go ├── process_freebsd_amd64.go ├── process_freebsd_arm.go ├── process_freebsd_arm64.go ├── process_linux.go ├── process_linux_test.go ├── process_openbsd.go ├── process_openbsd_386.go ├── process_openbsd_amd64.go ├── process_openbsd_arm.go ├── process_openbsd_arm64.go ├── process_openbsd_riscv64.go ├── process_plan9.go ├── process_posix.go ├── process_posix_test.go ├── process_race_test.go ├── process_solaris.go ├── process_test.go ├── process_windows.go ├── process_windows_32bit.go ├── process_windows_64bit.go ├── testdata │ ├── linux │ │ ├── 1 │ │ │ ├── comm │ │ │ ├── smaps │ │ │ └── status │ │ ├── 1060 │ │ │ ├── comm │ │ │ └── status │ │ └── 68927 │ │ │ ├── comm │ │ │ └── stat │ └── lx_brandz │ │ └── 1 │ │ └── stat ├── types_darwin.go ├── types_freebsd.go └── types_openbsd.go ├── sensors ├── ex_linux.go ├── sensors.go ├── sensors_aix.go ├── sensors_darwin.go ├── sensors_darwin_arm64.go ├── sensors_fallback.go ├── sensors_freebsd.go ├── sensors_linux.go ├── sensors_netbsd.go ├── sensors_openbsd.go ├── sensors_solaris.go ├── sensors_test.go └── sensors_windows.go ├── windows_memo.rst └── winservices ├── manager.go └── winservices.go /.gitattributes: -------------------------------------------------------------------------------- 1 | # ensure that line endings for Windows builds are properly formatted 2 | # see https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#how-to-use 3 | # at "Multiple OS Example" section 4 | *.go text eol=lf 5 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: shirou 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve gopsutil 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | [A clear and concise description of what the bug is.] 9 | 10 | **To Reproduce** 11 | ```go 12 | // paste example code reproducing the bug you are reporting 13 | ``` 14 | 15 | **Expected behavior** 16 | [A clear and concise description of what you expected to happen.] 17 | 18 | **Environment (please complete the following information):** 19 | - [ ] Windows: [paste the result of `ver`] 20 | - [ ] Linux: [paste contents of `/etc/os-release` and the result of `uname -a`] 21 | - [ ] Mac OS: [paste the result of `sw_vers` and `uname -a` 22 | - [ ] FreeBSD: [paste the result of `freebsd-version -k -r -u` and `uname -a`] 23 | - [ ] OpenBSD: [paste the result of `uname -a`] 24 | 25 | **Additional context** 26 | [Cross-compiling? Paste the command you are using to cross-compile and the result of the corresponding `go env`] 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for gopsutil 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | [A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]] 9 | 10 | **Describe the solution you'd like** 11 | [A clear and concise description of what you want to happen.] 12 | 13 | **Describe alternatives you've considered** 14 | [A clear and concise description of any alternative solutions or features you've considered.] 15 | 16 | **Additional context** 17 | [Add any other context or screenshots about the feature request here.] 18 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Security updates are applied only to the latest release. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. 10 | 11 | Please disclose it at [Security Advisories](https://github.com/shirou/gopsutil/security/advisories/new). 12 | 13 | This project is maintained by a team of volunteers on a reasonable-effort basis. As such, vulnerability reports will be investigated and fixed or disclosed as soon as possible. 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gomod 4 | directory: / 5 | schedule: 6 | interval: daily 7 | - package-ecosystem: github-actions 8 | directory: / 9 | schedule: 10 | interval: daily 11 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | package:cpu: 2 | - cpu/* 3 | package:disk: 4 | - disk/* 5 | package:docker: 6 | - docker/* 7 | package:host: 8 | - host/* 9 | package:load: 10 | - load/* 11 | package:mem: 12 | - mem/* 13 | package:net: 14 | - net/* 15 | package:process: 16 | - process/* 17 | package:sensors: 18 | - sensors/* 19 | package:winservices: 20 | - winservices/* 21 | os:linux: 22 | - ./**/*_linux.go 23 | - ./**/*_linux_mips64.go 24 | - ./**/*_linux_386.go 25 | - ./**/*_linux_test.go 26 | - ./**/*_linux_s390x.go 27 | - ./**/*_linux_amd64.go 28 | - ./**/*_linux_arm64.go 29 | - ./**/*_linux_arm.go 30 | - ./**/*_posix.go 31 | os:freebsd: 32 | - ./**/*_freebsd.go 33 | - ./**/*_freebsd_386.go 34 | - ./**/*_freebsd_test.go 35 | - ./**/*_freebsd_amd64.go 36 | - ./**/*_freebsd_arm64.go 37 | - ./**/*_freebsd_arm.go 38 | - ./**/*_bsd.go 39 | - ./**/*_posix.go 40 | os:darwin: 41 | - ./**/*_darwin.go 42 | - ./**/*_darwin_386.go 43 | - ./**/*_darwin_test.go 44 | - ./**/*_darwin_amd64.go 45 | - ./**/*_darwin_arm64.go 46 | - ./**/*_posix.go 47 | os:openbsd: 48 | - ./**/*_openbsd.go 49 | - ./**/*_openbsd_386.go 50 | - ./**/*_openbsd_test.go 51 | - ./**/*_openbsd_amd64.go 52 | - ./**/*_openbsd_arm64.go 53 | - ./**/*_openbsd_arm.go 54 | - ./**/*_bsd.go 55 | - ./**/*_posix.go 56 | os:windows: 57 | - ./**/*_windows.go 58 | - ./**/*_windows_386.go 59 | - ./**/*_windows_test.go 60 | - ./**/*_windows_amd64.go 61 | - ./**/*_windows_32bit.go 62 | - ./**/*_windows_64bit.go 63 | os:solaris: 64 | - ./**/*_solaris.go 65 | - ./**/*_posix.go 66 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - ignore-for-release 5 | - dependencies 6 | authors: 7 | - dependabot[bot] 8 | categories: 9 | - title: "cpu" 10 | labels: 11 | - "package:cpu" 12 | - title: "disk" 13 | labels: 14 | - "package:disk" 15 | - title: "docker" 16 | labels: 17 | - "package:docker" 18 | - title: "host" 19 | labels: 20 | - "package:host" 21 | - title: "load" 22 | labels: 23 | - "package:load" 24 | - title: "mem" 25 | labels: 26 | - "package:mem" 27 | - title: "net" 28 | labels: 29 | - "package:net" 30 | - title: "process" 31 | labels: 32 | - "package:process" 33 | - title: "winservices" 34 | labels: 35 | - "package:winservices" 36 | - title: Other Changes 37 | labels: 38 | - "*" -------------------------------------------------------------------------------- /.github/workflows/build_test.yml: -------------------------------------------------------------------------------- 1 | name: Build Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | go-versions: 18 | runs-on: ubuntu-latest 19 | outputs: 20 | versions: ${{ steps.versions.outputs.value }} 21 | steps: 22 | - id: versions 23 | run: | 24 | versions=$(curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])') 25 | echo "value=${versions}" >> $GITHUB_OUTPUT 26 | build_test: 27 | needs: go-versions 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | go-version: ${{fromJson(needs.go-versions.outputs.versions)}} 32 | runs-on: ubuntu-22.04 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 36 | - name: Install Go 37 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 38 | with: 39 | go-version: ${{ matrix.go-version }} 40 | - name: Build Test v3 41 | run: | 42 | make build_test 43 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: "Pull Request Labeler" 2 | 3 | on: 4 | pull_request_target: 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | triage: 11 | permissions: 12 | contents: read # for actions/labeler to determine modified files 13 | pull-requests: write # for actions/labeler to add labels to PRs 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4.3.0 17 | with: 18 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | schedule: 5 | - cron: '0 1 1 * *' # UTC 01:00 on the first day of the Month 6 | 7 | permissions: 8 | contents: write 9 | 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 15 | - name: Release 16 | run: make release 17 | -------------------------------------------------------------------------------- /.github/workflows/sbom_generator.yml: -------------------------------------------------------------------------------- 1 | name: SBOM Generator 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | permissions: read-all 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 16 | - uses: advanced-security/sbom-generator-action@6fe43abf522b2e7a19bc769aec1e6c848614b517 # v0.0.2 17 | id: sbom 18 | env: 19 | GITHUB_TOKEN: ${{ github.token }} 20 | - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 21 | with: 22 | path: ${{steps.sbom.outputs.fileName }} 23 | name: "SBOM" 24 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck.yml: -------------------------------------------------------------------------------- 1 | name: Shellcheck 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | shellcheck: 18 | name: Shellcheck 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 22 | - name: Run ShellCheck 23 | uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # v2.0.0 24 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | go-versions: 18 | runs-on: ubuntu-latest 19 | outputs: 20 | versions: ${{ steps.versions.outputs.value }} 21 | steps: 22 | - id: versions 23 | run: | 24 | versions=$(curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])') 25 | echo "value=${versions}" >> $GITHUB_OUTPUT 26 | test: 27 | needs: go-versions 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | go-version: ${{fromJson(needs.go-versions.outputs.versions)}} 32 | os: [ubuntu-22.04, ubuntu-24.04, windows-2019, windows-2022, windows-2025, macos-13, macos-14, macos-15] 33 | runs-on: ${{ matrix.os }} 34 | steps: 35 | - name: Checkout code 36 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 37 | - name: Install Go 38 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 39 | with: 40 | go-version: ${{ matrix.go-version }} 41 | - name: Test 42 | run: | 43 | go test -coverprofile='coverage.out' -covermode=atomic ./... 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | #* 3 | _obj 4 | *.tmp 5 | .idea 6 | vendor 7 | -------------------------------------------------------------------------------- /common/env.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package common 3 | 4 | type EnvKeyType string 5 | 6 | // EnvKey is a context key that can be used to set programmatically the environment 7 | // gopsutil relies on to perform calls against the OS. 8 | // Example of use: 9 | // 10 | // ctx := context.WithValue(context.Background(), common.EnvKey, EnvMap{common.HostProcEnvKey: "/myproc"}) 11 | // avg, err := load.AvgWithContext(ctx) 12 | var EnvKey = EnvKeyType("env") 13 | 14 | const ( 15 | HostProcEnvKey EnvKeyType = "HOST_PROC" 16 | HostSysEnvKey EnvKeyType = "HOST_SYS" 17 | HostEtcEnvKey EnvKeyType = "HOST_ETC" 18 | HostVarEnvKey EnvKeyType = "HOST_VAR" 19 | HostRunEnvKey EnvKeyType = "HOST_RUN" 20 | HostDevEnvKey EnvKeyType = "HOST_DEV" 21 | HostRootEnvKey EnvKeyType = "HOST_ROOT" 22 | HostProcMountinfo EnvKeyType = "HOST_PROC_MOUNTINFO" 23 | ) 24 | 25 | type EnvMap map[EnvKeyType]string 26 | -------------------------------------------------------------------------------- /cpu/cpu_aix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix 3 | 4 | package cpu 5 | 6 | import ( 7 | "context" 8 | ) 9 | 10 | func Times(percpu bool) ([]TimesStat, error) { 11 | return TimesWithContext(context.Background(), percpu) 12 | } 13 | 14 | func Info() ([]InfoStat, error) { 15 | return InfoWithContext(context.Background()) 16 | } 17 | -------------------------------------------------------------------------------- /cpu/cpu_aix_cgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && cgo 3 | 4 | package cpu 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/power-devops/perfstat" 10 | ) 11 | 12 | func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { 13 | var ret []TimesStat 14 | if percpu { 15 | cpus, err := perfstat.CpuStat() 16 | if err != nil { 17 | return nil, err 18 | } 19 | for _, c := range cpus { 20 | ct := &TimesStat{ 21 | CPU: c.Name, 22 | Idle: float64(c.Idle), 23 | User: float64(c.User), 24 | System: float64(c.Sys), 25 | Iowait: float64(c.Wait), 26 | } 27 | ret = append(ret, *ct) 28 | } 29 | } else { 30 | c, err := perfstat.CpuUtilTotalStat() 31 | if err != nil { 32 | return nil, err 33 | } 34 | ct := &TimesStat{ 35 | CPU: "cpu-total", 36 | Idle: float64(c.IdlePct), 37 | User: float64(c.UserPct), 38 | System: float64(c.KernPct), 39 | Iowait: float64(c.WaitPct), 40 | } 41 | ret = append(ret, *ct) 42 | } 43 | return ret, nil 44 | } 45 | 46 | func InfoWithContext(ctx context.Context) ([]InfoStat, error) { 47 | c, err := perfstat.CpuTotalStat() 48 | if err != nil { 49 | return nil, err 50 | } 51 | info := InfoStat{ 52 | CPU: 0, 53 | Mhz: float64(c.ProcessorHz / 1000000), 54 | Cores: int32(c.NCpusCfg), 55 | } 56 | result := []InfoStat{info} 57 | return result, nil 58 | } 59 | 60 | func CountsWithContext(ctx context.Context, logical bool) (int, error) { 61 | c, err := perfstat.CpuTotalStat() 62 | if err != nil { 63 | return 0, err 64 | } 65 | return c.NCpusCfg, nil 66 | } 67 | -------------------------------------------------------------------------------- /cpu/cpu_darwin_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin && !arm64 3 | 4 | package cpu 5 | 6 | import "golang.org/x/sys/unix" 7 | 8 | func getFrequency() (float64, error) { 9 | // Use the rated frequency of the CPU. This is a static value and does not 10 | // account for low power or Turbo Boost modes. 11 | cpuFrequency, err := unix.SysctlUint64("hw.cpufrequency") 12 | return float64(cpuFrequency) / 1000000.0, err 13 | } 14 | -------------------------------------------------------------------------------- /cpu/cpu_darwin_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin 3 | 4 | package cpu 5 | 6 | import ( 7 | "os" 8 | "runtime" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestInfo_AppleSilicon(t *testing.T) { 16 | if runtime.GOARCH != "arm64" { 17 | t.Skip("wrong cpu type") 18 | } 19 | 20 | v, err := Info() 21 | require.NoErrorf(t, err, "cpu info should be implemented on darwin systems") 22 | 23 | for _, vv := range v { 24 | assert.NotEmptyf(t, vv.ModelName, "could not get CPU info: %v", vv) 25 | if vv.Mhz <= 0 && os.Getenv("CI") != "true" { 26 | t.Errorf("could not get frequency of: %s", vv.ModelName) 27 | } 28 | assert.LessOrEqualf(t, vv.Mhz, float64(6000), "cpu frequency is absurdly high value: %f MHz", vv.Mhz) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cpu/cpu_dragonfly_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Intr uint64 9 | Idle uint64 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !dragonfly && !plan9 && !aix 3 | 4 | package cpu 5 | 6 | import ( 7 | "context" 8 | "runtime" 9 | 10 | "github.com/shirou/gopsutil/v4/internal/common" 11 | ) 12 | 13 | func Times(percpu bool) ([]TimesStat, error) { 14 | return TimesWithContext(context.Background(), percpu) 15 | } 16 | 17 | func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { 18 | return []TimesStat{}, common.ErrNotImplementedError 19 | } 20 | 21 | func Info() ([]InfoStat, error) { 22 | return InfoWithContext(context.Background()) 23 | } 24 | 25 | func InfoWithContext(ctx context.Context) ([]InfoStat, error) { 26 | return []InfoStat{}, common.ErrNotImplementedError 27 | } 28 | 29 | func CountsWithContext(ctx context.Context, logical bool) (int, error) { 30 | return runtime.NumCPU(), nil 31 | } 32 | -------------------------------------------------------------------------------- /cpu/cpu_freebsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint32 6 | Nice uint32 7 | Sys uint32 8 | Intr uint32 9 | Idle uint32 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_freebsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Intr uint64 9 | Idle uint64 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_freebsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint32 6 | Nice uint32 7 | Sys uint32 8 | Intr uint32 9 | Idle uint32 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_freebsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Intr uint64 9 | Idle uint64 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_freebsd_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | import ( 5 | "path/filepath" 6 | "runtime" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | func TestParseDmesgBoot(t *testing.T) { 16 | if runtime.GOOS != "freebsd" { 17 | t.SkipNow() 18 | } 19 | 20 | cpuTests := []struct { 21 | file string 22 | cpuNum int 23 | cores int32 24 | }{ 25 | {"1cpu_2core.txt", 1, 2}, 26 | {"1cpu_4core.txt", 1, 4}, 27 | {"2cpu_4core.txt", 2, 4}, 28 | } 29 | for _, tt := range cpuTests { 30 | v, num, err := parseDmesgBoot(filepath.Join("testdata", "freebsd", tt.file)) 31 | require.NoErrorf(t, err, "parseDmesgBoot failed(%s), %v", tt.file, err) 32 | assert.Equalf(t, num, tt.cpuNum, "parseDmesgBoot wrong length(%s), %v", tt.file, err) 33 | assert.Equalf(t, v.Cores, tt.cores, "parseDmesgBoot wrong core(%s), %v", tt.file, err) 34 | assert.Truef(t, common.StringsContains(v.Flags, "fpu"), "parseDmesgBoot fail to parse features(%s), %v", tt.file, err) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cpu/cpu_netbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Intr uint64 9 | Idle uint64 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_netbsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint32 6 | Nice uint32 7 | Sys uint32 8 | Intr uint32 9 | Idle uint32 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_netbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Intr uint64 9 | Idle uint64 10 | } 11 | -------------------------------------------------------------------------------- /cpu/cpu_openbsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint32 6 | Nice uint32 7 | Sys uint32 8 | Spin uint32 9 | Intr uint32 10 | Idle uint32 11 | } 12 | -------------------------------------------------------------------------------- /cpu/cpu_openbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Spin uint64 9 | Intr uint64 10 | Idle uint64 11 | } 12 | -------------------------------------------------------------------------------- /cpu/cpu_openbsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint32 6 | Nice uint32 7 | Sys uint32 8 | Spin uint32 9 | Intr uint32 10 | Idle uint32 11 | } 12 | -------------------------------------------------------------------------------- /cpu/cpu_openbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Spin uint64 9 | Intr uint64 10 | Idle uint64 11 | } 12 | -------------------------------------------------------------------------------- /cpu/cpu_openbsd_riscv64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package cpu 3 | 4 | type cpuTimes struct { 5 | User uint64 6 | Nice uint64 7 | Sys uint64 8 | Spin uint64 9 | Intr uint64 10 | Idle uint64 11 | } 12 | -------------------------------------------------------------------------------- /cpu/cpu_plan9.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build plan9 3 | 4 | package cpu 5 | 6 | import ( 7 | "context" 8 | "os" 9 | "runtime" 10 | 11 | stats "github.com/lufia/plan9stats" 12 | 13 | "github.com/shirou/gopsutil/v4/internal/common" 14 | ) 15 | 16 | func Times(percpu bool) ([]TimesStat, error) { 17 | return TimesWithContext(context.Background(), percpu) 18 | } 19 | 20 | func TimesWithContext(ctx context.Context, _ bool) ([]TimesStat, error) { 21 | // BUG: percpu flag is not supported yet. 22 | root := os.Getenv("HOST_ROOT") 23 | c, err := stats.ReadCPUType(ctx, stats.WithRootDir(root)) 24 | if err != nil { 25 | return nil, err 26 | } 27 | s, err := stats.ReadCPUStats(ctx, stats.WithRootDir(root)) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return []TimesStat{ 32 | { 33 | CPU: c.Name, 34 | User: s.User.Seconds(), 35 | System: s.Sys.Seconds(), 36 | Idle: s.Idle.Seconds(), 37 | }, 38 | }, nil 39 | } 40 | 41 | func Info() ([]InfoStat, error) { 42 | return InfoWithContext(context.Background()) 43 | } 44 | 45 | func InfoWithContext(_ context.Context) ([]InfoStat, error) { 46 | return []InfoStat{}, common.ErrNotImplementedError 47 | } 48 | 49 | func CountsWithContext(_ context.Context, _ bool) (int, error) { 50 | return runtime.NumCPU(), nil 51 | } 52 | -------------------------------------------------------------------------------- /cpu/cpu_plan9_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build plan9 3 | 4 | package cpu 5 | 6 | import ( 7 | "path/filepath" 8 | "testing" 9 | 10 | "github.com/google/go-cmp/cmp" 11 | "github.com/google/go-cmp/cmp/cmpopts" 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | 15 | "github.com/shirou/gopsutil/v4/internal/common" 16 | ) 17 | 18 | var timesTests = []struct { 19 | mockedRootFS string 20 | stats []TimesStat 21 | }{ 22 | { 23 | "2cores", 24 | []TimesStat{ 25 | { 26 | CPU: "Core i7/Xeon", 27 | User: 2780.0 / 1000.0, 28 | System: 30020.0 / 1000.0, 29 | Idle: (1412961713341830*2)/1000000000.0 - 2.78 - 30.02, 30 | }, 31 | }, 32 | }, 33 | } 34 | 35 | func TestTimesPlan9(t *testing.T) { 36 | for _, tt := range timesTests { 37 | t.Run(tt.mockedRootFS, func(t *testing.T) { 38 | t.Setenv("HOST_ROOT", filepath.Join("testdata/plan9", tt.mockedRootFS)) 39 | stats, err := Times(false) 40 | common.SkipIfNotImplementedErr(t, err) 41 | require.NoError(t, err) 42 | eps := cmpopts.EquateApprox(0, 0.00000001) 43 | assert.Truef(t, cmp.Equal(stats, tt.stats, eps), "got: %+v\nwant: %+v", stats, tt.stats) 44 | }) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /cpu/testdata/aix/sar-u-PALL101: -------------------------------------------------------------------------------- 1 | 2 | AIX aix72-dylan 2 7 000000000000 05/15/24 3 | 4 | System configuration: lcpu=4 ent=4.00 mode=Capped 5 | 6 | 11:19:03 cpu %usr %sys %wio %idle physc %entc 7 | 11:19:13 0 1 11 0 88 1.00 25.0 8 | 1 0 0 0 100 1.00 25.0 9 | 2 0 0 0 100 1.00 25.0 10 | 3 0 0 0 100 1.00 25.0 11 | - 0 3 0 97 4.00 100.0 12 | -------------------------------------------------------------------------------- /cpu/testdata/aix/sar-u101: -------------------------------------------------------------------------------- 1 | 2 | AIX aix72-dylan 2 7 000000000000 05/15/24 3 | 4 | System configuration: lcpu=4 ent=4.00 mode=Capped 5 | 6 | 11:19:44 %usr %sys %wio %idle physc %entc 7 | 11:19:54 0 3 0 96 4.00 100.0 8 | -------------------------------------------------------------------------------- /cpu/testdata/freebsd/1cpu_2core.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 1992-2016 The FreeBSD Project. 2 | Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 3 | The Regents of the University of California. All rights reserved. 4 | FreeBSD is a registered trademark of The FreeBSD Foundation. 5 | FreeBSD 11.0-RELEASE-p2 #0: Mon Oct 24 06:55:27 UTC 2016 6 | root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 7 | FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0) 8 | VT(vga): resolution 640x480 9 | CPU: Intel(R) Core(TM) i3 CPU 550 @ 3.20GHz (3192.07-MHz K8-class CPU) 10 | Origin="GenuineIntel" Id=0x20655 Family=0x6 Model=0x25 Stepping=5 11 | Features=0xbfebfbff 12 | Features2=0x9ae3bd 13 | AMD Features=0x28100800 14 | AMD Features2=0x1 15 | VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID 16 | TSC: P-state invariant, performance statistics 17 | real memory = 8589934592 (8192 MB) 18 | avail memory = 8046452736 (7673 MB) 19 | Event timer "LAPIC" quality 600 20 | ACPI APIC Table: 21 | FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs 22 | FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 hardware threads 23 | random: unblocking device. 24 | ioapic0 irqs 0-23 on motherboard 25 | random: entropy device external interface 26 | kbd1 at kbdmux0 27 | netmap: loaded module 28 | module_register_init: MOD_LOAD (vesa, 0xffffffff8101c970, 0) error 19 29 | vtvga0: on motherboard 30 | cryptosoft0: on motherboard 31 | aesni0: No AESNI support. 32 | acpi0: on motherboard 33 | acpi0: Power Button (fixed) 34 | cpu0: on acpi0 35 | ACPI BIOS Warning (bug): Incorrect checksum in table [SSDT] - 0x3F, should be 0x1F (20160527/tbprint-229) 36 | cpu1: on acpi0 37 | cpu2: on acpi0 38 | cpu3: on acpi0 39 | attimer0: port 0x40-0x43 irq 0 on acpi0 40 | Timecounter "i8254" frequency 1193182 Hz quality 0 41 | Event timer "i8254" frequency 1193182 Hz quality 100 42 | atrtc0: port 0x70-0x71 irq 8 on acpi0 43 | Event timer "RTC" frequency 32768 Hz quality 0 -------------------------------------------------------------------------------- /cpu/testdata/freebsd/1cpu_4core.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 1992-2016 The FreeBSD Project. 2 | Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 3 | The Regents of the University of California. All rights reserved. 4 | FreeBSD is a registered trademark of The FreeBSD Foundation. 5 | FreeBSD 10.3-RELEASE-p4 #0: Sat May 28 12:23:44 UTC 2016 6 | root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 7 | FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512 8 | CPU: Intel(R) Xeon(R) CPU E5-1620 v2 @ 3.70GHz (3700.09-MHz K8-class CPU) 9 | Origin="GenuineIntel" Id=0x306e4 Family=0x6 Model=0x3e Stepping=4 10 | Features=0xbfebfbff 11 | Features2=0x7fbee3ff 12 | AMD Features=0x2c100800 13 | AMD Features2=0x1 14 | Structured Extended Features=0x281 15 | XSAVE Features=0x1 16 | VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID,VID,PostIntr 17 | TSC: P-state invariant, performance statistics 18 | real memory = 34368126976 (32776 MB) 19 | avail memory = 33228333056 (31689 MB) 20 | Event timer "LAPIC" quality 600 21 | ACPI APIC Table: < > 22 | FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs 23 | FreeBSD/SMP: 1 package(s) x 4 core(s) x 2 SMT threads 24 | cpu0 (BSP): APIC ID: 0 25 | cpu1 (AP): APIC ID: 1 26 | cpu2 (AP): APIC ID: 2 27 | cpu3 (AP): APIC ID: 3 28 | cpu4 (AP): APIC ID: 4 29 | cpu5 (AP): APIC ID: 5 30 | cpu6 (AP): APIC ID: 6 31 | cpu7 (AP): APIC ID: 7 32 | random: initialized 33 | ioapic0 irqs 0-23 on motherboard 34 | ioapic1 irqs 24-47 on motherboard 35 | kbd1 at kbdmux0 36 | cryptosoft0: on motherboard 37 | aesni0: on motherboard 38 | acpi0: on motherboard -------------------------------------------------------------------------------- /cpu/testdata/freebsd/2cpu_4core.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 1992-2011 The FreeBSD Project. 2 | Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 3 | The Regents of the University of California. All rights reserved. 4 | FreeBSD is a registered trademark of The FreeBSD Foundation. 5 | FreeBSD 8.2-RELEASE #1: Sat Mar 5 23:03:14 CET 2011 6 | root@host1:/usr/obj/usr/src/sys/MYKERNEL amd64 7 | Timecounter "i8254" frequency 1193182 Hz quality 0 8 | CPU: Intel(R) Xeon(R) CPU E5420 @ 2.50GHz (2500.11-MHz K8-class CPU) 9 | Origin = "GenuineIntel" Id = 0x10676 Family = 6 Model = 17 Stepping = 6 10 | Features=0xbfebfbff 11 | Features2=0xce3bd 12 | AMD Features=0x20100800 13 | AMD Features2=0x1 14 | TSC: P-state invariant 15 | real memory = 17179869184 (16384 MB) 16 | avail memory = 16531587072 (15765 MB) 17 | ACPI APIC Table: 18 | FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs 19 | FreeBSD/SMP: 2 package(s) x 4 core(s) 20 | cpu0 (BSP): APIC ID: 0 21 | cpu1 (AP): APIC ID: 1 22 | cpu2 (AP): APIC ID: 2 23 | cpu3 (AP): APIC ID: 3 24 | cpu4 (AP): APIC ID: 4 25 | cpu5 (AP): APIC ID: 5 26 | cpu6 (AP): APIC ID: 6 27 | cpu7 (AP): APIC ID: 7 28 | ioapic0 irqs 0-23 on motherboard 29 | ioapic1 irqs 24-47 on motherboard 30 | kbd1 at kbdmux0 31 | acpi0: on motherboard 32 | acpi0: [ITHREAD] 33 | acpi0: Power Button (fixed) 34 | unknown: I/O range not supported 35 | Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000 36 | acpi_timer0: <24-bit timer at 3.579545MHz> port 0x1008-0x100b on acpi0 37 | cpu0: on acpi0 38 | cpu1: on acpi0 39 | cpu2: on acpi0 40 | cpu3: on acpi0 41 | cpu4: on acpi0 42 | cpu5: on acpi0 43 | cpu6: on acpi0 44 | cpu7: on acpi0 45 | pcib0: port 0xcf8-0xcff on acpi0 -------------------------------------------------------------------------------- /cpu/testdata/linux/1037/proc/cpuinfo: -------------------------------------------------------------------------------- 1 | processor : 0 2 | Processor : ARMv7 Processor rev 4 (v7l) 3 | model name : ARMv7 Processor rev 4 (v7l) 4 | BogoMIPS : 42.43 5 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 6 | CPU implementer : 0x41 7 | CPU architecture: 7 8 | CPU variant : 0x0 9 | CPU part : 0xd03 10 | CPU revision : 4 11 | 12 | processor : 1 13 | Processor : ARMv7 Processor rev 4 (v7l) 14 | model name : ARMv7 Processor rev 4 (v7l) 15 | BogoMIPS : 42.43 16 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 17 | CPU implementer : 0x41 18 | CPU architecture: 7 19 | CPU variant : 0x0 20 | CPU part : 0xd03 21 | CPU revision : 4 22 | 23 | processor : 2 24 | Processor : ARMv7 Processor rev 4 (v7l) 25 | model name : ARMv7 Processor rev 4 (v7l) 26 | BogoMIPS : 42.43 27 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 28 | CPU implementer : 0x41 29 | CPU architecture: 7 30 | CPU variant : 0x0 31 | CPU part : 0xd03 32 | CPU revision : 4 33 | 34 | processor : 3 35 | Processor : ARMv7 Processor rev 4 (v7l) 36 | model name : ARMv7 Processor rev 4 (v7l) 37 | BogoMIPS : 42.43 38 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 39 | CPU implementer : 0x41 40 | CPU architecture: 7 41 | CPU variant : 0x0 42 | CPU part : 0xd03 43 | CPU revision : 4 44 | 45 | processor : 4 46 | Processor : ARMv7 Processor rev 2 (v7l) 47 | model name : ARMv7 Processor rev 2 (v7l) 48 | BogoMIPS : 29.52 49 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 50 | CPU implementer : 0x41 51 | CPU architecture: 7 52 | CPU variant : 0x0 53 | CPU part : 0xd09 54 | CPU revision : 2 55 | 56 | processor : 5 57 | Processor : ARMv7 Processor rev 2 (v7l) 58 | model name : ARMv7 Processor rev 2 (v7l) 59 | BogoMIPS : 29.52 60 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 61 | CPU implementer : 0x41 62 | CPU architecture: 7 63 | CPU variant : 0x0 64 | CPU part : 0xd09 65 | CPU revision : 2 66 | 67 | processor : 6 68 | Processor : ARMv7 Processor rev 2 (v7l) 69 | model name : ARMv7 Processor rev 2 (v7l) 70 | BogoMIPS : 29.52 71 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 72 | CPU implementer : 0x41 73 | CPU architecture: 7 74 | CPU variant : 0x0 75 | CPU part : 0xd09 76 | CPU revision : 2 77 | 78 | processor : 7 79 | Processor : ARMv7 Processor rev 2 (v7l) 80 | model name : ARMv7 Processor rev 2 (v7l) 81 | BogoMIPS : 29.52 82 | Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 83 | CPU implementer : 0x41 84 | CPU architecture: 7 85 | CPU variant : 0x0 86 | CPU part : 0xd09 87 | CPU revision : 2 88 | 89 | Hardware : MT8183 90 | Revision : 0000 91 | Serial : 29aa1cf5ba0159c3 92 | -------------------------------------------------------------------------------- /cpu/testdata/linux/424/proc/stat: -------------------------------------------------------------------------------- 1 | cpu 23644 6695 4764 134931750 22115 0 473 5892 0 0 2 | cpu0 6418 888 1230 33730755 5043 0 4 1046 0 0 3 | cpu1 6858 4870 1632 33716510 12327 0 235 1765 0 0 4 | cpu2 4859 622 915 33742072 2312 0 25 1546 0 0 5 | cpu3 5507 314 986 33742411 2432 0 208 1534 0 0 6 | intr 32552791 35 9 0 0 2335 0 3 0 2 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3107077 2985327 15704 0 6672 0 3218027 3063711 11558 0 6151 0 2160633 2194945 15838 0 6565 0 1595129 2134446 15337 0 5715 0 157 112837 717318 710764 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 | ctxt 41317767 8 | btime 1505515383 9 | processes 41562 10 | procs_running 1 11 | procs_blocked 0 12 | softirq 5433315 0 1644387 67542 1428221 0 0 12270 1573783 0 707112 -------------------------------------------------------------------------------- /cpu/testdata/linux/times_empty/proc/stat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shirou/gopsutil/15412ac7b3ab216de55a0963503c624e69c93a94/cpu/testdata/linux/times_empty/proc/stat -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/dev/cputype: -------------------------------------------------------------------------------- 1 | Core i7/Xeon 2403 2 | -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/dev/sysstat: -------------------------------------------------------------------------------- 1 | 0 59251106 37524162 1208203 65907 0 0 7 100 0 2 | 1 219155408 28582838 5017097 1002072 0 0 0 98 1 3 | -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/dev/time: -------------------------------------------------------------------------------- 1 | 1633882064 1633882064926300833 2825920097745864 1999997644 -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/proc/1/status: -------------------------------------------------------------------------------- 1 | init bootes Await 10 20 1404307210 110 20 0 116 10 10 -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/proc/331/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shirou/gopsutil/15412ac7b3ab216de55a0963503c624e69c93a94/cpu/testdata/plan9/2cores/proc/331/.gitkeep -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/proc/54384/status: -------------------------------------------------------------------------------- 1 | rc lufia Await 0 0 589160 8770 3260 0 248 10 10 -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/proc/54412/status: -------------------------------------------------------------------------------- 1 | git-remote-https lufia Semacquire 390 310 370670 0 0 0 98368 10 10 -------------------------------------------------------------------------------- /cpu/testdata/plan9/2cores/proc/72/status: -------------------------------------------------------------------------------- 1 | httpd none Open 2380 29690 1404804330 0 0 0 23616 10 10 -------------------------------------------------------------------------------- /cpu/testdata/solaris/1cpu_1core_isainfo.txt: -------------------------------------------------------------------------------- 1 | 64-bit amd64 applications 2 | rdseed adx avx2 fma bmi2 bmi1 rdrand f16c vmx avx xsave pclmulqdq 3 | aes movbe sse4.2 sse4.1 ssse3 popcnt tscp cx16 sse3 sse2 sse fxsr 4 | mmx cmov amd_sysc cx8 tsc fpu -------------------------------------------------------------------------------- /cpu/testdata/solaris/1cpu_1core_psrinfo.txt: -------------------------------------------------------------------------------- 1 | The physical processor has 1 virtual processor (0) 2 | x86 (GenuineIntel 406E3 family 6 model 78 step 3 clock 3312 MHz) 3 | Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz -------------------------------------------------------------------------------- /cpu/testdata/solaris/2cpu_12core_isainfo.txt: -------------------------------------------------------------------------------- 1 | 64-bit amd64 applications 2 | amd_svm amd_lzcnt popcnt amd_sse4a tscp ahf cx16 sse3 sse2 sse fxsr 3 | amd_3dnowx amd_3dnow amd_mmx mmx cmov amd_sysc cx8 tsc fpu 4 | -------------------------------------------------------------------------------- /cpu/testdata/solaris/2cpu_12core_psrinfo.txt: -------------------------------------------------------------------------------- 1 | The physical processor has 12 virtual processors (0-11) 2 | x86 (AuthenticAMD 100F91 family 16 model 9 step 1 clock 2300 MHz) 3 | AMD Opteron(tm) Processor 6176 [ Socket: G34 ] 4 | The physical processor has 12 virtual processors (12-23) 5 | x86 (AuthenticAMD 100F91 family 16 model 9 step 1 clock 2300 MHz) 6 | AMD Opteron(tm) Processor 6176 [ Socket: G34 ] 7 | -------------------------------------------------------------------------------- /cpu/testdata/solaris/2cpu_1core_isainfo.txt: -------------------------------------------------------------------------------- 1 | 64-bit amd64 applications 2 | rdseed adx avx2 fma bmi2 bmi1 rdrand f16c vmx avx xsave pclmulqdq 3 | aes movbe sse4.2 sse4.1 ssse3 popcnt tscp cx16 sse3 sse2 sse fxsr 4 | mmx cmov amd_sysc cx8 tsc fpu -------------------------------------------------------------------------------- /cpu/testdata/solaris/2cpu_1core_psrinfo.txt: -------------------------------------------------------------------------------- 1 | The physical processor has 1 virtual processor (0) 2 | x86 (GenuineIntel 406E3 family 6 model 78 step 3 clock 3312 MHz) 3 | Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz 4 | The physical processor has 1 virtual processor (1) 5 | x86 (GenuineIntel 406E3 family 6 model 78 step 3 clock 3312 MHz) 6 | Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz -------------------------------------------------------------------------------- /cpu/testdata/solaris/2cpu_8core_isainfo.txt: -------------------------------------------------------------------------------- 1 | 64-bit amd64 applications 2 | vmx avx xsave pclmulqdq aes sse4.2 sse4.1 ssse3 popcnt tscp cx16 3 | sse3 sse2 sse fxsr mmx cmov amd_sysc cx8 tsc fpu -------------------------------------------------------------------------------- /cpu/testdata/solaris/2cpu_8core_psrinfo.txt: -------------------------------------------------------------------------------- 1 | The physical processor has 8 cores and 16 virtual processors (0-7 16-23) 2 | The core has 2 virtual processors (0 16) 3 | The core has 2 virtual processors (1 17) 4 | The core has 2 virtual processors (2 18) 5 | The core has 2 virtual processors (3 19) 6 | The core has 2 virtual processors (4 20) 7 | The core has 2 virtual processors (5 21) 8 | The core has 2 virtual processors (6 22) 9 | The core has 2 virtual processors (7 23) 10 | x86 (GenuineIntel 206D7 family 6 model 45 step 7 clock 2600 MHz) 11 | Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz 12 | The physical processor has 8 cores and 16 virtual processors (8-15 24-31) 13 | The core has 2 virtual processors (8 24) 14 | The core has 2 virtual processors (9 25) 15 | The core has 2 virtual processors (10 26) 16 | The core has 2 virtual processors (11 27) 17 | The core has 2 virtual processors (12 28) 18 | The core has 2 virtual processors (13 29) 19 | The core has 2 virtual processors (14 30) 20 | The core has 2 virtual processors (15 31) 21 | x86 (GenuineIntel 206D7 family 6 model 45 step 7 clock 2600 MHz) 22 | Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz -------------------------------------------------------------------------------- /disk/disk_aix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix 3 | 4 | package disk 5 | 6 | import ( 7 | "context" 8 | "errors" 9 | "strings" 10 | 11 | "github.com/shirou/gopsutil/v4/internal/common" 12 | ) 13 | 14 | func IOCountersWithContext(_ context.Context, _ ...string) (map[string]IOCountersStat, error) { 15 | return nil, common.ErrNotImplementedError 16 | } 17 | 18 | func LabelWithContext(_ context.Context, _ string) (string, error) { 19 | return "", common.ErrNotImplementedError 20 | } 21 | 22 | // Using lscfg and a device name, we can get the device information 23 | // This is a pure go implementation, and should be moved to disk_aix_nocgo.go 24 | // if a more efficient CGO method is introduced in disk_aix_cgo.go 25 | func SerialNumberWithContext(ctx context.Context, name string) (string, error) { 26 | // This isn't linux, these aren't actual disk devices 27 | if strings.HasPrefix(name, "/dev/") { 28 | return "", errors.New("devices on /dev are not physical disks on aix") 29 | } 30 | out, err := invoke.CommandWithContext(ctx, "lscfg", "-vl", name) 31 | if err != nil { 32 | return "", err 33 | } 34 | 35 | ret := "" 36 | // Kind of inefficient, but it works 37 | lines := strings.Split(string(out), "\n") 38 | for line := 1; line < len(lines); line++ { 39 | v := strings.TrimSpace(lines[line]) 40 | if strings.HasPrefix(v, "Serial Number...............") { 41 | ret = strings.TrimPrefix(v, "Serial Number...............") 42 | if ret == "" { 43 | return "", errors.New("empty serial for disk") 44 | } 45 | return ret, nil 46 | } 47 | } 48 | 49 | return ret, errors.New("serial entry not found for disk") 50 | } 51 | -------------------------------------------------------------------------------- /disk/disk_aix_cgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && cgo 3 | 4 | package disk 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | 10 | "github.com/power-devops/perfstat" 11 | ) 12 | 13 | var FSType map[int]string 14 | 15 | func init() { 16 | FSType = map[int]string{ 17 | 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", 18 | 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", 19 | 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", 20 | 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", 21 | } 22 | } 23 | 24 | func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { 25 | f, err := perfstat.FileSystemStat() 26 | if err != nil { 27 | return nil, err 28 | } 29 | ret := make([]PartitionStat, len(f)) 30 | 31 | for _, fs := range f { 32 | fstyp, exists := FSType[fs.FSType] 33 | if !exists { 34 | fstyp = "unknown" 35 | } 36 | info := PartitionStat{ 37 | Device: fs.Device, 38 | Mountpoint: fs.MountPoint, 39 | Fstype: fstyp, 40 | } 41 | ret = append(ret, info) 42 | } 43 | 44 | return ret, err 45 | } 46 | 47 | func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { 48 | f, err := perfstat.FileSystemStat() 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | blocksize := uint64(512) 54 | for _, fs := range f { 55 | if path == fs.MountPoint { 56 | fstyp, exists := FSType[fs.FSType] 57 | if !exists { 58 | fstyp = "unknown" 59 | } 60 | info := UsageStat{ 61 | Path: path, 62 | Fstype: fstyp, 63 | Total: uint64(fs.TotalBlocks) * blocksize, 64 | Free: uint64(fs.FreeBlocks) * blocksize, 65 | Used: uint64(fs.TotalBlocks-fs.FreeBlocks) * blocksize, 66 | InodesTotal: uint64(fs.TotalInodes), 67 | InodesFree: uint64(fs.FreeInodes), 68 | InodesUsed: uint64(fs.TotalInodes - fs.FreeInodes), 69 | } 70 | info.UsedPercent = (float64(info.Used) / float64(info.Total)) * 100.0 71 | info.InodesUsedPercent = (float64(info.InodesUsed) / float64(info.InodesTotal)) * 100.0 72 | return &info, nil 73 | } 74 | } 75 | return nil, fmt.Errorf("mountpoint %s not found", path) 76 | } 77 | -------------------------------------------------------------------------------- /disk/disk_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !windows && !solaris && !aix 3 | 4 | package disk 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func IOCountersWithContext(_ context.Context, _ ...string) (map[string]IOCountersStat, error) { 13 | return nil, common.ErrNotImplementedError 14 | } 15 | 16 | func PartitionsWithContext(_ context.Context, _ bool) ([]PartitionStat, error) { 17 | return []PartitionStat{}, common.ErrNotImplementedError 18 | } 19 | 20 | func UsageWithContext(_ context.Context, _ string) (*UsageStat, error) { 21 | return nil, common.ErrNotImplementedError 22 | } 23 | 24 | func SerialNumberWithContext(_ context.Context, _ string) (string, error) { 25 | return "", common.ErrNotImplementedError 26 | } 27 | 28 | func LabelWithContext(_ context.Context, _ string) (string, error) { 29 | return "", common.ErrNotImplementedError 30 | } 31 | -------------------------------------------------------------------------------- /disk/disk_freebsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_freebsd.go 4 | 5 | package disk 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeofLongDouble = 0x8 14 | 15 | devstat_NO_DATA = 0x00 16 | devstat_READ = 0x01 17 | devstat_WRITE = 0x02 18 | devstat_FREE = 0x03 19 | ) 20 | 21 | const ( 22 | sizeOfdevstat = 0xf0 23 | ) 24 | 25 | type ( 26 | _C_short int16 27 | _C_int int32 28 | _C_long int32 29 | _C_long_long int64 30 | _C_long_double int64 31 | ) 32 | 33 | type devstat struct { 34 | Sequence0 uint32 35 | Allocated int32 36 | Start_count uint32 37 | End_count uint32 38 | Busy_from bintime 39 | Dev_links _Ctype_struct___0 40 | Device_number uint32 41 | Device_name [16]int8 42 | Unit_number int32 43 | Bytes [4]uint64 44 | Operations [4]uint64 45 | Duration [4]bintime 46 | Busy_time bintime 47 | Creation_time bintime 48 | Block_size uint32 49 | Tag_types [3]uint64 50 | Flags uint32 51 | Device_type uint32 52 | Priority uint32 53 | Id *byte 54 | Sequence1 uint32 55 | } 56 | 57 | type bintime struct { 58 | Sec int32 59 | Frac uint64 60 | } 61 | 62 | type _Ctype_struct___0 struct { 63 | Empty uint32 64 | } 65 | -------------------------------------------------------------------------------- /disk/disk_freebsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_freebsd.go 4 | 5 | package disk 6 | 7 | const ( 8 | sizeofPtr = 0x8 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x8 12 | sizeofLongLong = 0x8 13 | sizeofLongDouble = 0x8 14 | 15 | devstat_NO_DATA = 0x00 16 | devstat_READ = 0x01 17 | devstat_WRITE = 0x02 18 | devstat_FREE = 0x03 19 | ) 20 | 21 | const ( 22 | sizeOfdevstat = 0x120 23 | ) 24 | 25 | type ( 26 | _C_short int16 27 | _C_int int32 28 | _C_long int64 29 | _C_long_long int64 30 | _C_long_double int64 31 | ) 32 | 33 | type devstat struct { 34 | Sequence0 uint32 35 | Allocated int32 36 | Start_count uint32 37 | End_count uint32 38 | Busy_from bintime 39 | Dev_links _Ctype_struct___0 40 | Device_number uint32 41 | Device_name [16]int8 42 | Unit_number int32 43 | Bytes [4]uint64 44 | Operations [4]uint64 45 | Duration [4]bintime 46 | Busy_time bintime 47 | Creation_time bintime 48 | Block_size uint32 49 | Pad_cgo_0 [4]byte 50 | Tag_types [3]uint64 51 | Flags uint32 52 | Device_type uint32 53 | Priority uint32 54 | Pad_cgo_1 [4]byte 55 | ID *byte 56 | Sequence1 uint32 57 | Pad_cgo_2 [4]byte 58 | } 59 | 60 | type bintime struct { 61 | Sec int64 62 | Frac uint64 63 | } 64 | 65 | type _Ctype_struct___0 struct { 66 | Empty uint64 67 | } 68 | -------------------------------------------------------------------------------- /disk/disk_freebsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_freebsd.go 4 | 5 | package disk 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeofLongDouble = 0x8 14 | 15 | devstat_NO_DATA = 0x00 16 | devstat_READ = 0x01 17 | devstat_WRITE = 0x02 18 | devstat_FREE = 0x03 19 | ) 20 | 21 | const ( 22 | sizeOfdevstat = 0xf0 23 | ) 24 | 25 | type ( 26 | _C_short int16 27 | _C_int int32 28 | _C_long int32 29 | _C_long_long int64 30 | _C_long_double int64 31 | ) 32 | 33 | type devstat struct { 34 | Sequence0 uint32 35 | Allocated int32 36 | Start_count uint32 37 | End_count uint32 38 | Busy_from bintime 39 | Dev_links _Ctype_struct___0 40 | Device_number uint32 41 | Device_name [16]int8 42 | Unit_number int32 43 | Bytes [4]uint64 44 | Operations [4]uint64 45 | Duration [4]bintime 46 | Busy_time bintime 47 | Creation_time bintime 48 | Block_size uint32 49 | Tag_types [3]uint64 50 | Flags uint32 51 | Device_type uint32 52 | Priority uint32 53 | Id *byte 54 | Sequence1 uint32 55 | } 56 | 57 | type bintime struct { 58 | Sec int32 59 | Frac uint64 60 | } 61 | 62 | type _Ctype_struct___0 struct { 63 | Empty uint32 64 | } 65 | -------------------------------------------------------------------------------- /disk/disk_freebsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs disk/types_freebsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeofLongDouble = 0x8 16 | 17 | devstat_NO_DATA = 0x00 18 | devstat_READ = 0x01 19 | devstat_WRITE = 0x02 20 | devstat_FREE = 0x03 21 | ) 22 | 23 | const ( 24 | sizeOfdevstat = 0x120 25 | ) 26 | 27 | type ( 28 | _C_short int16 29 | _C_int int32 30 | _C_long int64 31 | _C_long_long int64 32 | _C_long_double int64 33 | ) 34 | 35 | type devstat struct { 36 | Sequence0 uint32 37 | Allocated int32 38 | Start_count uint32 39 | End_count uint32 40 | Busy_from bintime 41 | Dev_links _Ctype_struct___0 42 | Device_number uint32 43 | Device_name [16]int8 44 | Unit_number int32 45 | Bytes [4]uint64 46 | Operations [4]uint64 47 | Duration [4]bintime 48 | Busy_time bintime 49 | Creation_time bintime 50 | Block_size uint32 51 | Tag_types [3]uint64 52 | Flags uint32 53 | Device_type uint32 54 | Priority uint32 55 | Id *byte 56 | Sequence1 uint32 57 | Pad_cgo_0 [4]byte 58 | } 59 | type bintime struct { 60 | Sec int64 61 | Frac uint64 62 | } 63 | 64 | type _Ctype_struct___0 struct { 65 | Empty uint64 66 | } 67 | -------------------------------------------------------------------------------- /disk/disk_netbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build netbsd && amd64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs types_netbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | sizeOfStatvfs = 0xce0 11 | ) 12 | 13 | type ( 14 | Statvfs struct { 15 | Flag uint64 16 | Bsize uint64 17 | Frsize uint64 18 | Iosize uint64 19 | Blocks uint64 20 | Bfree uint64 21 | Bavail uint64 22 | Bresvd uint64 23 | Files uint64 24 | Ffree uint64 25 | Favail uint64 26 | Fresvd uint64 27 | Syncreads uint64 28 | Syncwrites uint64 29 | Asyncreads uint64 30 | Asyncwrites uint64 31 | Fsidx _Ctype_struct___0 32 | Fsid uint64 33 | Namemax uint64 34 | Owner uint32 35 | Spare [4]uint64 36 | Fstypename [32]uint8 37 | Mntonname [1024]uint8 38 | Mntfromname [1024]uint8 39 | Mntfromlabel [1024]uint8 40 | } 41 | ) 42 | 43 | type _Ctype_struct___0 struct { 44 | FsidVal [2]int32 45 | } 46 | -------------------------------------------------------------------------------- /disk/disk_netbsd_arm.go: -------------------------------------------------------------------------------- 1 | //go:build netbsd && arm 2 | // +build netbsd,arm 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs disk/types_netbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | sizeOfStatvfs = 0xcc8 11 | ) 12 | 13 | type ( 14 | Statvfs struct { 15 | Flag uint32 16 | Bsize uint32 17 | Frsize uint32 18 | Iosize uint32 19 | Blocks uint64 20 | Bfree uint64 21 | Bavail uint64 22 | Bresvd uint64 23 | Files uint64 24 | Ffree uint64 25 | Favail uint64 26 | Fresvd uint64 27 | Syncreads uint64 28 | Syncwrites uint64 29 | Asyncreads uint64 30 | Asyncwrites uint64 31 | Fsidx _Ctype_struct___0 32 | Fsid uint32 33 | Namemax uint32 34 | Owner uint32 35 | Pad_cgo_0 [4]byte 36 | Spare [4]uint64 37 | Fstypename [32]uint8 38 | Mntonname [1024]uint8 39 | Mntfromname [1024]uint8 40 | Mntfromlabel [1024]uint8 41 | } 42 | ) 43 | 44 | type _Ctype_struct___0 struct { 45 | FsidVal [2]int32 46 | } 47 | -------------------------------------------------------------------------------- /disk/disk_netbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build netbsd && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs types_netbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | sizeOfStatvfs = 0xce0 11 | ) 12 | 13 | type ( 14 | Statvfs struct { 15 | Flag uint64 16 | Bsize uint64 17 | Frsize uint64 18 | Iosize uint64 19 | Blocks uint64 20 | Bfree uint64 21 | Bavail uint64 22 | Bresvd uint64 23 | Files uint64 24 | Ffree uint64 25 | Favail uint64 26 | Fresvd uint64 27 | Syncreads uint64 28 | Syncwrites uint64 29 | Asyncreads uint64 30 | Asyncwrites uint64 31 | Fsidx _Ctype_struct___0 32 | Fsid uint64 33 | Namemax uint64 34 | Owner uint32 35 | Spare [4]uint64 36 | Fstypename [32]uint8 37 | Mntonname [1024]uint8 38 | Mntfromname [1024]uint8 39 | Mntfromlabel [1024]uint8 40 | } 41 | ) 42 | 43 | type _Ctype_struct___0 struct { 44 | FsidVal [2]int32 45 | } 46 | -------------------------------------------------------------------------------- /disk/disk_openbsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && 386 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs disk/types_openbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | devstat_NO_DATA = 0x00 11 | devstat_READ = 0x01 12 | devstat_WRITE = 0x02 13 | devstat_FREE = 0x03 14 | ) 15 | 16 | const ( 17 | sizeOfDiskstats = 0x60 18 | ) 19 | 20 | type Diskstats struct { 21 | Name [16]int8 22 | Busy int32 23 | Rxfer uint64 24 | Wxfer uint64 25 | Seek uint64 26 | Rbytes uint64 27 | Wbytes uint64 28 | Attachtime Timeval 29 | Timestamp Timeval 30 | Time Timeval 31 | } 32 | type Timeval struct { 33 | Sec int64 34 | Usec int32 35 | } 36 | 37 | type ( 38 | Diskstat struct{} 39 | bintime struct{} 40 | ) 41 | -------------------------------------------------------------------------------- /disk/disk_openbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 3 | // cgo -godefs types_openbsd.go 4 | 5 | package disk 6 | 7 | const ( 8 | devstat_NO_DATA = 0x00 9 | devstat_READ = 0x01 10 | devstat_WRITE = 0x02 11 | devstat_FREE = 0x03 12 | ) 13 | 14 | const ( 15 | sizeOfDiskstats = 0x70 16 | ) 17 | 18 | type Diskstats struct { 19 | Name [16]int8 20 | Busy int32 21 | Pad_cgo_0 [4]byte 22 | Rxfer uint64 23 | Wxfer uint64 24 | Seek uint64 25 | Rbytes uint64 26 | Wbytes uint64 27 | Attachtime Timeval 28 | Timestamp Timeval 29 | Time Timeval 30 | } 31 | type Timeval struct { 32 | Sec int64 33 | Usec int64 34 | } 35 | 36 | type ( 37 | Diskstat struct{} 38 | bintime struct{} 39 | ) 40 | -------------------------------------------------------------------------------- /disk/disk_openbsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && arm 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs disk/types_openbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | devstat_NO_DATA = 0x00 11 | devstat_READ = 0x01 12 | devstat_WRITE = 0x02 13 | devstat_FREE = 0x03 14 | ) 15 | 16 | const ( 17 | sizeOfDiskstats = 0x60 18 | ) 19 | 20 | type Diskstats struct { 21 | Name [16]int8 22 | Busy int32 23 | Rxfer uint64 24 | Wxfer uint64 25 | Seek uint64 26 | Rbytes uint64 27 | Wbytes uint64 28 | Attachtime Timeval 29 | Timestamp Timeval 30 | Time Timeval 31 | } 32 | type Timeval struct { 33 | Sec int64 34 | Usec int32 35 | } 36 | 37 | type ( 38 | Diskstat struct{} 39 | bintime struct{} 40 | ) 41 | -------------------------------------------------------------------------------- /disk/disk_openbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs disk/types_openbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | devstat_NO_DATA = 0x00 11 | devstat_READ = 0x01 12 | devstat_WRITE = 0x02 13 | devstat_FREE = 0x03 14 | ) 15 | 16 | const ( 17 | sizeOfDiskstats = 0x70 18 | ) 19 | 20 | type Diskstats struct { 21 | Name [16]int8 22 | Busy int32 23 | Rxfer uint64 24 | Wxfer uint64 25 | Seek uint64 26 | Rbytes uint64 27 | Wbytes uint64 28 | Attachtime Timeval 29 | Timestamp Timeval 30 | Time Timeval 31 | } 32 | type Timeval struct { 33 | Sec int64 34 | Usec int64 35 | } 36 | 37 | type ( 38 | Diskstat struct{} 39 | bintime struct{} 40 | ) 41 | -------------------------------------------------------------------------------- /disk/disk_openbsd_riscv64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && riscv64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs disk/types_openbsd.go 6 | 7 | package disk 8 | 9 | const ( 10 | devstat_NO_DATA = 0x00 11 | devstat_READ = 0x01 12 | devstat_WRITE = 0x02 13 | devstat_FREE = 0x03 14 | ) 15 | 16 | const ( 17 | sizeOfDiskstats = 0x70 18 | ) 19 | 20 | type ( 21 | Diskstats struct { 22 | Name [16]int8 23 | Busy int32 24 | Rxfer uint64 25 | Wxfer uint64 26 | Seek uint64 27 | Rbytes uint64 28 | Wbytes uint64 29 | Attachtime Timeval 30 | Timestamp Timeval 31 | Time Timeval 32 | } 33 | Timeval struct { 34 | Sec int64 35 | Usec int64 36 | } 37 | ) 38 | 39 | type ( 40 | Diskstat struct{} 41 | bintime struct{} 42 | ) 43 | -------------------------------------------------------------------------------- /disk/disk_unix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd || linux || darwin 3 | 4 | package disk 5 | 6 | import ( 7 | "context" 8 | "strconv" 9 | 10 | "golang.org/x/sys/unix" 11 | ) 12 | 13 | func UsageWithContext(_ context.Context, path string) (*UsageStat, error) { 14 | stat := unix.Statfs_t{} 15 | err := unix.Statfs(path, &stat) 16 | if err != nil { 17 | return nil, err 18 | } 19 | bsize := stat.Bsize 20 | 21 | ret := &UsageStat{ 22 | Path: unescapeFstab(path), 23 | Fstype: getFsType(stat), 24 | Total: (uint64(stat.Blocks) * uint64(bsize)), 25 | Free: (uint64(stat.Bavail) * uint64(bsize)), 26 | InodesTotal: (uint64(stat.Files)), 27 | InodesFree: (uint64(stat.Ffree)), 28 | } 29 | 30 | ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize) 31 | 32 | if (ret.Used + ret.Free) == 0 { 33 | ret.UsedPercent = 0 34 | } else { 35 | // We don't use ret.Total to calculate percent. 36 | // see https://github.com/shirou/gopsutil/issues/562 37 | ret.UsedPercent = (float64(ret.Used) / float64(ret.Used+ret.Free)) * 100.0 38 | } 39 | 40 | // if could not get InodesTotal, return empty 41 | if ret.InodesTotal < ret.InodesFree { 42 | return ret, nil 43 | } 44 | 45 | ret.InodesUsed = (ret.InodesTotal - ret.InodesFree) 46 | 47 | if ret.InodesTotal == 0 { 48 | ret.InodesUsedPercent = 0 49 | } else { 50 | ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0 51 | } 52 | 53 | return ret, nil 54 | } 55 | 56 | // Unescape escaped octal chars (like space 040, ampersand 046 and backslash 134) to their real value in fstab fields issue#555 57 | func unescapeFstab(path string) string { 58 | escaped, err := strconv.Unquote(`"` + path + `"`) 59 | if err != nil { 60 | return path 61 | } 62 | return escaped 63 | } 64 | -------------------------------------------------------------------------------- /disk/types_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // Hand writing: _Ctype_struct___0 5 | 6 | /* 7 | Input to cgo -godefs. 8 | 9 | */ 10 | 11 | package disk 12 | 13 | /* 14 | #include 15 | #include 16 | #include 17 | 18 | enum { 19 | sizeofPtr = sizeof(void*), 20 | }; 21 | 22 | // because statinfo has long double snap_time, redefine with changing long long 23 | struct statinfo2 { 24 | long cp_time[CPUSTATES]; 25 | long tk_nin; 26 | long tk_nout; 27 | struct devinfo *dinfo; 28 | long long snap_time; 29 | }; 30 | */ 31 | import "C" 32 | 33 | // Machine characteristics; for internal use. 34 | 35 | const ( 36 | sizeofPtr = C.sizeofPtr 37 | sizeofShort = C.sizeof_short 38 | sizeofInt = C.sizeof_int 39 | sizeofLong = C.sizeof_long 40 | sizeofLongLong = C.sizeof_longlong 41 | sizeofLongDouble = C.sizeof_longlong 42 | 43 | devstat_NO_DATA = 0x00 44 | devstat_READ = 0x01 45 | devstat_WRITE = 0x02 46 | devstat_FREE = 0x03 47 | ) 48 | 49 | const ( 50 | sizeOfdevstat = C.sizeof_struct_devstat 51 | ) 52 | 53 | // Basic types 54 | 55 | type ( 56 | _C_short C.short 57 | _C_int C.int 58 | _C_long C.long 59 | _C_long_long C.longlong 60 | _C_long_double C.longlong 61 | ) 62 | 63 | type ( 64 | devstat C.struct_devstat 65 | bintime C.struct_bintime 66 | ) 67 | -------------------------------------------------------------------------------- /disk/types_netbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // Hand writing: _Ctype_struct___0 5 | 6 | /* 7 | Input to cgo -godefs. 8 | */ 9 | 10 | package disk 11 | 12 | /* 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | */ 22 | import "C" 23 | 24 | const ( 25 | sizeOfStatvfs = C.sizeof_struct_statvfs 26 | ) 27 | 28 | type ( 29 | Statvfs C.struct_statvfs 30 | ) 31 | -------------------------------------------------------------------------------- /disk/types_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // Hand writing: _Ctype_struct___0 5 | 6 | /* 7 | Input to cgo -godefs. 8 | */ 9 | 10 | package disk 11 | 12 | /* 13 | #include 14 | #include 15 | #include 16 | */ 17 | import "C" 18 | 19 | const ( 20 | devstat_NO_DATA = 0x00 21 | devstat_READ = 0x01 22 | devstat_WRITE = 0x02 23 | devstat_FREE = 0x03 24 | ) 25 | 26 | const ( 27 | sizeOfDiskstats = C.sizeof_struct_diskstats 28 | ) 29 | 30 | type ( 31 | Diskstats C.struct_diskstats 32 | Timeval C.struct_timeval 33 | ) 34 | 35 | type ( 36 | Diskstat C.struct_diskstat 37 | bintime C.struct_bintime 38 | ) 39 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package gopsutil 3 | -------------------------------------------------------------------------------- /docker/docker.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package docker 3 | 4 | import ( 5 | "encoding/json" 6 | "errors" 7 | 8 | "github.com/shirou/gopsutil/v4/cpu" 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | var ( 13 | ErrDockerNotAvailable = errors.New("docker not available") 14 | ErrCgroupNotAvailable = errors.New("cgroup not available") 15 | ) 16 | 17 | var invoke common.Invoker = common.Invoke{} 18 | 19 | const nanoseconds = 1e9 20 | 21 | type CgroupCPUStat struct { 22 | cpu.TimesStat 23 | Usage float64 24 | } 25 | 26 | type CgroupMemStat struct { 27 | ContainerID string `json:"containerID"` 28 | Cache uint64 `json:"cache"` 29 | RSS uint64 `json:"rss"` 30 | RSSHuge uint64 `json:"rssHuge"` 31 | MappedFile uint64 `json:"mappedFile"` 32 | Pgpgin uint64 `json:"pgpgin"` 33 | Pgpgout uint64 `json:"pgpgout"` 34 | Pgfault uint64 `json:"pgfault"` 35 | Pgmajfault uint64 `json:"pgmajfault"` 36 | InactiveAnon uint64 `json:"inactiveAnon"` 37 | ActiveAnon uint64 `json:"activeAnon"` 38 | InactiveFile uint64 `json:"inactiveFile"` 39 | ActiveFile uint64 `json:"activeFile"` 40 | Unevictable uint64 `json:"unevictable"` 41 | HierarchicalMemoryLimit uint64 `json:"hierarchicalMemoryLimit"` 42 | TotalCache uint64 `json:"totalCache"` 43 | TotalRSS uint64 `json:"totalRss"` 44 | TotalRSSHuge uint64 `json:"totalRssHuge"` 45 | TotalMappedFile uint64 `json:"totalMappedFile"` 46 | TotalPgpgIn uint64 `json:"totalPgpgin"` 47 | TotalPgpgOut uint64 `json:"totalPgpgout"` 48 | TotalPgFault uint64 `json:"totalPgfault"` 49 | TotalPgMajFault uint64 `json:"totalPgmajfault"` 50 | TotalInactiveAnon uint64 `json:"totalInactiveAnon"` 51 | TotalActiveAnon uint64 `json:"totalActiveAnon"` 52 | TotalInactiveFile uint64 `json:"totalInactiveFile"` 53 | TotalActiveFile uint64 `json:"totalActiveFile"` 54 | TotalUnevictable uint64 `json:"totalUnevictable"` 55 | MemUsageInBytes uint64 `json:"memUsageInBytes"` 56 | MemMaxUsageInBytes uint64 `json:"memMaxUsageInBytes"` 57 | MemLimitInBytes uint64 `json:"memoryLimitInBytes"` 58 | MemFailCnt uint64 `json:"memoryFailcnt"` 59 | } 60 | 61 | func (m CgroupMemStat) String() string { 62 | s, _ := json.Marshal(m) 63 | return string(s) 64 | } 65 | 66 | type CgroupDockerStat struct { 67 | ContainerID string `json:"containerID"` 68 | Name string `json:"name"` 69 | Image string `json:"image"` 70 | Status string `json:"status"` 71 | Running bool `json:"running"` 72 | } 73 | 74 | func (c CgroupDockerStat) String() string { 75 | s, _ := json.Marshal(c) 76 | return string(s) 77 | } 78 | -------------------------------------------------------------------------------- /docker/docker_linux_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux 3 | 4 | package docker 5 | 6 | import ( 7 | "context" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestGetDockerIDList(_ *testing.T) { 15 | // If there is not docker environment, this test always fail. 16 | // not tested here 17 | /* 18 | _, err := GetDockerIDList() 19 | if err != nil { 20 | t.Errorf("error %v", err) 21 | } 22 | */ 23 | } 24 | 25 | func TestGetDockerStat(_ *testing.T) { 26 | // If there is not docker environment, this test always fail. 27 | // not tested here 28 | 29 | /* 30 | ret, err := GetDockerStat() 31 | if err != nil { 32 | t.Errorf("error %v", err) 33 | } 34 | if len(ret) == 0 { 35 | t.Errorf("ret is empty") 36 | } 37 | empty := CgroupDockerStat{} 38 | for _, v := range ret { 39 | if empty == v { 40 | t.Errorf("empty CgroupDockerStat") 41 | } 42 | if v.ContainerID == "" { 43 | t.Errorf("Could not get container id") 44 | } 45 | } 46 | */ 47 | } 48 | 49 | func TestCgroupCPU(t *testing.T) { 50 | v, _ := GetDockerIDList() 51 | for _, id := range v { 52 | v, err := CgroupCPUDockerWithContext(context.Background(), id) 53 | require.NoError(t, err) 54 | assert.NotEmptyf(t, v.CPU, "could not get CgroupCPU %v", v) 55 | 56 | } 57 | } 58 | 59 | func TestCgroupCPUInvalidId(t *testing.T) { 60 | _, err := CgroupCPUDockerWithContext(context.Background(), "bad id") 61 | assert.Errorf(t, err, "Expected path does not exist error") 62 | } 63 | 64 | func TestCgroupMem(t *testing.T) { 65 | v, _ := GetDockerIDList() 66 | for _, id := range v { 67 | v, err := CgroupMemDocker(id) 68 | require.NoError(t, err) 69 | empty := &CgroupMemStat{} 70 | assert.NotSamef(t, v, empty, "Could not CgroupMemStat %v", v) 71 | } 72 | } 73 | 74 | func TestCgroupMemInvalidId(t *testing.T) { 75 | _, err := CgroupMemDocker("bad id") 76 | assert.Errorf(t, err, "Expected path does not exist error") 77 | } 78 | -------------------------------------------------------------------------------- /docker/docker_notlinux.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !linux 3 | 4 | package docker 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | // GetDockerStat returns a list of Docker basic stats. 13 | // This requires certain permission. 14 | func GetDockerStat() ([]CgroupDockerStat, error) { 15 | return GetDockerStatWithContext(context.Background()) 16 | } 17 | 18 | func GetDockerStatWithContext(_ context.Context) ([]CgroupDockerStat, error) { 19 | return nil, ErrDockerNotAvailable 20 | } 21 | 22 | // GetDockerIDList returns a list of DockerID. 23 | // This requires certain permission. 24 | func GetDockerIDList() ([]string, error) { 25 | return GetDockerIDListWithContext(context.Background()) 26 | } 27 | 28 | func GetDockerIDListWithContext(_ context.Context) ([]string, error) { 29 | return nil, ErrDockerNotAvailable 30 | } 31 | 32 | // CgroupCPU returns specified cgroup id CPU status. 33 | // containerID is same as docker id if you use docker. 34 | // If you use container via systemd.slice, you could use 35 | // containerID = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ 36 | func CgroupCPU(containerID string, base string) (*CgroupCPUStat, error) { 37 | return CgroupCPUWithContext(context.Background(), containerID, base) 38 | } 39 | 40 | func CgroupCPUWithContext(_ context.Context, _ string, _ string) (*CgroupCPUStat, error) { 41 | return nil, ErrCgroupNotAvailable 42 | } 43 | 44 | func CgroupCPUDocker(containerID string) (*CgroupCPUStat, error) { 45 | return CgroupCPUDockerWithContext(context.Background(), containerID) 46 | } 47 | 48 | func CgroupCPUDockerWithContext(ctx context.Context, containerID string) (*CgroupCPUStat, error) { 49 | return CgroupCPUWithContext(ctx, containerID, common.HostSysWithContext(ctx, "fs/cgroup/cpuacct/docker")) 50 | } 51 | 52 | func CgroupMem(containerID string, base string) (*CgroupMemStat, error) { 53 | return CgroupMemWithContext(context.Background(), containerID, base) 54 | } 55 | 56 | func CgroupMemWithContext(_ context.Context, _ string, _ string) (*CgroupMemStat, error) { 57 | return nil, ErrCgroupNotAvailable 58 | } 59 | 60 | func CgroupMemDocker(containerID string) (*CgroupMemStat, error) { 61 | return CgroupMemDockerWithContext(context.Background(), containerID) 62 | } 63 | 64 | func CgroupMemDockerWithContext(ctx context.Context, containerID string) (*CgroupMemStat, error) { 65 | return CgroupMemWithContext(ctx, containerID, common.HostSysWithContext(ctx, "fs/cgroup/memory/docker")) 66 | } 67 | -------------------------------------------------------------------------------- /docker/main_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package docker 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | func TestSysAdvancedDockerInfo(_ *testing.T) { 10 | list, err := GetDockerIDList() 11 | if err != nil { 12 | fmt.Println(err) 13 | } 14 | for _, item := range list { 15 | fmt.Println(item) 16 | } 17 | /*docker,err := SysAdvancedDockerInfo() 18 | if err!= nil{ 19 | fmt.Println(err) 20 | } 21 | fmt.Printf("%#v",docker)*/ 22 | } 23 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/shirou/gopsutil/v4 2 | 3 | go 1.23 4 | 5 | require ( 6 | github.com/ebitengine/purego v0.8.4 7 | github.com/google/go-cmp v0.7.0 8 | github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 9 | github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c 10 | github.com/stretchr/testify v1.10.0 11 | github.com/tklauser/go-sysconf v0.3.12 12 | github.com/yusufpapurcu/wmi v1.2.4 13 | golang.org/x/sys v0.28.0 14 | ) 15 | 16 | require ( 17 | github.com/davecgh/go-spew v1.1.1 // indirect 18 | github.com/go-ole/go-ole v1.2.6 // indirect 19 | github.com/pmezard/go-difflib v1.0.0 // indirect 20 | github.com/tklauser/numcpus v0.6.1 // indirect 21 | gopkg.in/yaml.v3 v3.0.1 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /host/freebsd_headers/utxdb.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 | * 4 | * Copyright (c) 2010 Ed Schouten 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | * 28 | * $FreeBSD$ 29 | */ 30 | 31 | #ifndef _UTXDB_H_ 32 | #define _UTXDB_H_ 33 | 34 | #include 35 | 36 | #define _PATH_UTX_ACTIVE "/var/run/utx.active" 37 | #define _PATH_UTX_LASTLOGIN "/var/log/utx.lastlogin" 38 | #define _PATH_UTX_LOG "/var/log/utx.log" 39 | 40 | /* 41 | * Entries in struct futx are ordered by how often they are used. In 42 | * utx.log only entries will be written until the last non-zero byte, 43 | * which means we want to put the hostname at the end. Most primitive 44 | * records only store a ut_type and ut_tv, which means we want to store 45 | * those at the front. 46 | */ 47 | 48 | struct utmpx; 49 | 50 | struct futx { 51 | uint8_t fu_type; 52 | uint64_t fu_tv; 53 | char fu_id[8]; 54 | uint32_t fu_pid; 55 | char fu_user[32]; 56 | char fu_line[16]; 57 | char fu_host[128]; 58 | } __packed; 59 | 60 | void utx_to_futx(const struct utmpx *, struct futx *); 61 | struct utmpx *futx_to_utx(const struct futx *); 62 | 63 | #endif /* !_UTXDB_H_ */ 64 | -------------------------------------------------------------------------------- /host/host_aix_ppc64.go: -------------------------------------------------------------------------------- 1 | //go:build aix && ppc64 && cgo 2 | // +build aix,ppc64,cgo 3 | 4 | // Guessed at from the following document: 5 | // https://www.ibm.com/docs/sl/ibm-mq/9.2?topic=platforms-standard-data-types-aix-linux-windows 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x180 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type utmp struct { 26 | Type int16 27 | Pad_cgo_0 [2]byte 28 | Pid int32 29 | Line [32]int8 30 | Id [4]int8 31 | User [32]int8 32 | Host [256]int8 33 | Exit exit_status 34 | Session int32 35 | Tv timeval 36 | Addr_v6 [4]int32 37 | X__glibc_reserved [20]int8 38 | } 39 | 40 | type exit_status struct { 41 | Termination int16 42 | Exit int16 43 | } 44 | 45 | type timeval struct { 46 | Sec int64 47 | Usec int64 48 | } 49 | -------------------------------------------------------------------------------- /host/host_aix_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix 3 | 4 | package host 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestParseUptimeValidInput(t *testing.T) { 13 | testCases := []struct { 14 | input string 15 | expected uint64 16 | }{ 17 | {"11:54AM up 13 mins, 1 user, load average: 2.78, 2.62, 1.79", 13}, 18 | {"12:41PM up 1 hr, 1 user, load average: 2.47, 2.85, 2.83", 60}, 19 | {"07:43PM up 5 hrs, 1 user, load average: 3.27, 2.91, 2.72", 300}, 20 | {"11:18:23 up 83 days, 18:29, 4 users, load average: 0.16, 0.03, 0.01", 120629}, 21 | {"08:47PM up 2 days, 20 hrs, 1 user, load average: 2.47, 2.17, 2.17", 4080}, 22 | {"01:16AM up 4 days, 29 mins, 1 user, load average: 2.29, 2.31, 2.21", 5789}, 23 | } 24 | for _, tc := range testCases { 25 | got := parseUptime(tc.input) 26 | assert.Equalf(t, tc.expected, got, "parseUptime(%q) = %v, want %v", tc.input, got, tc.expected) 27 | } 28 | } 29 | 30 | func TestParseUptimeInvalidInput(t *testing.T) { 31 | testCases := []string{ 32 | "", // blank 33 | "2x", // invalid string 34 | "150", // integer 35 | } 36 | 37 | for _, tc := range testCases { 38 | got := parseUptime(tc) 39 | assert.LessOrEqualf(t, got, 0, "parseUptime(%q) expected zero to be returned, received %v", tc, got) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /host/host_bsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin || freebsd || openbsd || netbsd 3 | 4 | package host 5 | 6 | import ( 7 | "context" 8 | "sync/atomic" 9 | 10 | "golang.org/x/sys/unix" 11 | ) 12 | 13 | // cachedBootTime must be accessed via atomic.Load/StoreUint64 14 | var cachedBootTime uint64 15 | 16 | func BootTimeWithContext(_ context.Context) (uint64, error) { 17 | if enableBootTimeCache { 18 | t := atomic.LoadUint64(&cachedBootTime) 19 | if t != 0 { 20 | return t, nil 21 | } 22 | } 23 | tv, err := unix.SysctlTimeval("kern.boottime") 24 | if err != nil { 25 | return 0, err 26 | } 27 | 28 | if enableBootTimeCache { 29 | atomic.StoreUint64(&cachedBootTime, uint64(tv.Sec)) 30 | } 31 | 32 | return uint64(tv.Sec), nil 33 | } 34 | 35 | func UptimeWithContext(ctx context.Context) (uint64, error) { 36 | boot, err := BootTimeWithContext(ctx) 37 | if err != nil { 38 | return 0, err 39 | } 40 | return timeSince(boot), nil 41 | } 42 | -------------------------------------------------------------------------------- /host/host_darwin_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_darwin.go 4 | 5 | package host 6 | 7 | type Utmpx struct { 8 | User [256]int8 9 | ID [4]int8 10 | Line [32]int8 11 | Pid int32 12 | Type int16 13 | Pad_cgo_0 [6]byte 14 | Tv Timeval 15 | Host [256]int8 16 | Pad [16]uint32 17 | } 18 | 19 | type Timeval struct { 20 | Sec int32 21 | } 22 | -------------------------------------------------------------------------------- /host/host_darwin_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs host/types_darwin.go 6 | 7 | package host 8 | 9 | type Utmpx struct { 10 | User [256]int8 11 | Id [4]int8 12 | Line [32]int8 13 | Pid int32 14 | Type int16 15 | Tv Timeval 16 | Host [256]int8 17 | Pad [16]uint32 18 | } 19 | type Timeval struct { 20 | Sec int64 21 | Usec int32 22 | Pad_cgo_0 [4]byte 23 | } 24 | -------------------------------------------------------------------------------- /host/host_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !aix 3 | 4 | package host 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func HostIDWithContext(_ context.Context) (string, error) { 13 | return "", common.ErrNotImplementedError 14 | } 15 | 16 | func numProcs(_ context.Context) (uint64, error) { 17 | return 0, common.ErrNotImplementedError 18 | } 19 | 20 | func BootTimeWithContext(_ context.Context) (uint64, error) { 21 | return 0, common.ErrNotImplementedError 22 | } 23 | 24 | func UptimeWithContext(_ context.Context) (uint64, error) { 25 | return 0, common.ErrNotImplementedError 26 | } 27 | 28 | func UsersWithContext(_ context.Context) ([]UserStat, error) { 29 | return []UserStat{}, common.ErrNotImplementedError 30 | } 31 | 32 | func VirtualizationWithContext(_ context.Context) (string, string, error) { 33 | return "", "", common.ErrNotImplementedError 34 | } 35 | 36 | func KernelVersionWithContext(_ context.Context) (string, error) { 37 | return "", common.ErrNotImplementedError 38 | } 39 | 40 | func PlatformInformationWithContext(_ context.Context) (string, string, string, error) { 41 | return "", "", "", common.ErrNotImplementedError 42 | } 43 | 44 | func KernelArch() (string, error) { 45 | return "", common.ErrNotImplementedError 46 | } 47 | -------------------------------------------------------------------------------- /host/host_freebsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 3 | // cgo -godefs types_freebsd.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeOfUtmpx = 0xc5 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type Utmp struct { 24 | Line [8]int8 25 | Name [16]int8 26 | Host [16]int8 27 | Time int32 28 | } 29 | 30 | type Utmpx struct { 31 | Type uint8 32 | Tv uint64 33 | Id [8]int8 34 | Pid uint32 35 | User [32]int8 36 | Line [16]int8 37 | Host [128]int8 38 | } 39 | -------------------------------------------------------------------------------- /host/host_freebsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 3 | // cgo -godefs types_freebsd.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x8 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x8 12 | sizeofLongLong = 0x8 13 | sizeOfUtmpx = 0xc5 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int64 20 | _C_long_long int64 21 | ) 22 | 23 | type Utmp struct { 24 | Line [8]int8 25 | Name [16]int8 26 | Host [16]int8 27 | Time int32 28 | } 29 | 30 | type Utmpx struct { 31 | Type uint8 32 | Tv uint64 33 | Id [8]int8 34 | Pid uint32 35 | User [32]int8 36 | Line [16]int8 37 | Host [128]int8 38 | } 39 | -------------------------------------------------------------------------------- /host/host_freebsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 3 | // cgo -godefs types_freebsd.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x8 12 | sizeofLongLong = 0x8 13 | sizeOfUtmpx = 0xc5 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type Utmp struct { 24 | Line [8]int8 25 | Name [16]int8 26 | Host [16]int8 27 | Time int32 28 | } 29 | 30 | type Utmpx struct { 31 | Type uint8 32 | Tv uint64 33 | Id [8]int8 34 | Pid uint32 35 | User [32]int8 36 | Line [16]int8 37 | Host [128]int8 38 | } 39 | -------------------------------------------------------------------------------- /host/host_freebsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs host/types_freebsd.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmpx = 0xc5 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type Utmp struct { 26 | Line [8]int8 27 | Name [16]int8 28 | Host [16]int8 29 | Time int32 30 | } 31 | 32 | type Utmpx struct { 33 | Type uint8 34 | Tv uint64 35 | Id [8]int8 36 | Pid uint32 37 | User [32]int8 38 | Line [16]int8 39 | Host [128]int8 40 | } 41 | -------------------------------------------------------------------------------- /host/host_linux_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // ATTENTION - FILE MANUAL FIXED AFTER CGO. 3 | // Fixed line: Tv _Ctype_struct_timeval -> Tv UtTv 4 | // Created by cgo -godefs, MANUAL FIXED 5 | // cgo -godefs types_linux.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x4 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x4 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x180 16 | ) 17 | 18 | type ( 19 | _C_short int16 //nolint:revive //FIXME 20 | _C_int int32 //nolint:revive //FIXME 21 | _C_long int32 //nolint:revive //FIXME 22 | _C_long_long int64 //nolint:revive //FIXME 23 | ) 24 | 25 | type utmp struct { 26 | Type int16 27 | Pad_cgo_0 [2]byte //nolint:revive //FIXME 28 | Pid int32 29 | Line [32]int8 30 | ID [4]int8 31 | User [32]int8 32 | Host [256]int8 33 | Exit exit_status 34 | Session int32 35 | Tv UtTv 36 | Addr_v6 [4]int32 //nolint:revive //FIXME 37 | X__unused [20]int8 //nolint:revive //FIXME 38 | } 39 | 40 | type exit_status struct { //nolint:revive //FIXME 41 | Termination int16 42 | Exit int16 43 | } 44 | 45 | type UtTv struct { 46 | Sec int32 47 | Usec int32 48 | } 49 | -------------------------------------------------------------------------------- /host/host_linux_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x8 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x8 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int64 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte 26 | Pid int32 27 | Line [32]int8 28 | Id [4]int8 29 | User [32]int8 30 | Host [256]int8 31 | Exit exit_status 32 | Session int32 33 | Tv _Ctype_struct___0 34 | Addr_v6 [4]int32 35 | X__glibc_reserved [20]int8 36 | } 37 | 38 | type exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | 43 | type timeval struct { 44 | Sec int64 45 | Usec int64 46 | } 47 | 48 | type _Ctype_struct___0 struct { 49 | Sec int32 50 | Usec int32 51 | } 52 | -------------------------------------------------------------------------------- /host/host_linux_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go | sed "s/uint8/int8/g" 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte 26 | Pid int32 27 | Line [32]int8 28 | Id [4]int8 29 | User [32]int8 30 | Host [256]int8 31 | Exit exit_status 32 | Session int32 33 | Tv timeval 34 | Addr_v6 [4]int32 35 | X__glibc_reserved [20]int8 36 | } 37 | 38 | type exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | 43 | type timeval struct { 44 | Sec int32 45 | Usec int32 46 | } 47 | -------------------------------------------------------------------------------- /host/host_linux_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 3 | 4 | package host 5 | 6 | const ( 7 | sizeofPtr = 0x8 8 | sizeofShort = 0x2 9 | sizeofInt = 0x4 10 | sizeofLong = 0x8 11 | sizeofLongLong = 0x8 12 | sizeOfUtmp = 0x190 13 | ) 14 | 15 | type ( 16 | _C_short int16 17 | _C_int int32 18 | _C_long int64 19 | _C_long_long int64 20 | ) 21 | 22 | type ( 23 | utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte // changed by hand #1603 26 | Pid int32 27 | Line [32]int8 // changed by hand 28 | Id [4]int8 // changed by hand 29 | User [32]int8 // changed by hand 30 | Host [256]int8 // changed by hand 31 | Exit exit_status 32 | Session int64 33 | Tv timeval 34 | Addr_v6 [4]int32 35 | X__glibc_reserved [20]uint8 36 | Pad_cgo_1 [4]byte 37 | } 38 | exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | timeval struct { 43 | Sec int64 44 | Usec int64 45 | } 46 | ) 47 | -------------------------------------------------------------------------------- /host/host_linux_loong64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 3 | // cgo -godefs host/types_linux.go 4 | 5 | //go:build linux && loong64 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x190 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type ( 26 | utmp struct { 27 | Type int16 28 | Pid int32 29 | Line [32]int8 30 | Id [4]int8 31 | User [32]int8 32 | Host [256]int8 33 | Exit exit_status 34 | Session int64 35 | Tv timeval 36 | Addr_v6 [4]int32 37 | X__glibc_reserved [20]int8 38 | Pad_cgo_0 [4]byte 39 | } 40 | exit_status struct { 41 | Termination int16 42 | Exit int16 43 | } 44 | timeval struct { 45 | Sec int64 46 | Usec int64 47 | } 48 | ) 49 | -------------------------------------------------------------------------------- /host/host_linux_mips.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte 26 | Pid int32 27 | Line [32]int8 28 | Id [4]int8 29 | User [32]int8 30 | Host [256]int8 31 | Exit exit_status 32 | Session int32 33 | Tv timeval 34 | Addr_v6 [4]int32 35 | X__unused [20]int8 36 | } 37 | 38 | type exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | 43 | type timeval struct { 44 | Sec int32 45 | Usec int32 46 | } 47 | -------------------------------------------------------------------------------- /host/host_linux_mips64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte 26 | Pid int32 27 | Line [32]int8 28 | Id [4]int8 29 | User [32]int8 30 | Host [256]int8 31 | Exit exit_status 32 | Session int32 33 | Tv timeval 34 | Addr_v6 [4]int32 35 | X__unused [20]int8 36 | } 37 | 38 | type exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | 43 | type timeval struct { 44 | Sec int32 45 | Usec int32 46 | } 47 | -------------------------------------------------------------------------------- /host/host_linux_mips64le.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte 26 | Pid int32 27 | Line [32]int8 28 | Id [4]int8 29 | User [32]int8 30 | Host [256]int8 31 | Exit exit_status 32 | Session int32 33 | Tv timeval 34 | Addr_v6 [4]int32 35 | X__unused [20]int8 36 | } 37 | 38 | type exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | 43 | type timeval struct { 44 | Sec int32 45 | Usec int32 46 | } 47 | -------------------------------------------------------------------------------- /host/host_linux_mipsle.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x4 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x4 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int32 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pad_cgo_0 [2]byte 26 | Pid int32 27 | Line [32]int8 28 | Id [4]int8 29 | User [32]int8 30 | Host [256]int8 31 | Exit exit_status 32 | Session int32 33 | Tv timeval 34 | Addr_v6 [4]int32 35 | X__unused [20]int8 36 | } 37 | 38 | type exit_status struct { 39 | Termination int16 40 | Exit int16 41 | } 42 | 43 | type timeval struct { 44 | Sec int32 45 | Usec int32 46 | } 47 | -------------------------------------------------------------------------------- /host/host_linux_ppc64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux && ppc64 3 | 4 | // Created by cgo -godefs - DO NOT EDIT 5 | // cgo -godefs types_linux.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x180 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type utmp struct { 26 | Type int16 27 | Pad_cgo_0 [2]byte 28 | Pid int32 29 | Line [32]int8 30 | Id [4]int8 31 | User [32]int8 32 | Host [256]int8 33 | Exit exit_status 34 | Session int32 35 | Tv timeval 36 | Addr_v6 [4]int32 37 | X__glibc_reserved [20]int8 38 | } 39 | 40 | type exit_status struct { 41 | Termination int16 42 | Exit int16 43 | } 44 | 45 | type timeval struct { 46 | Sec int64 47 | Usec int64 48 | } 49 | -------------------------------------------------------------------------------- /host/host_linux_ppc64le.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux && ppc64le 3 | 4 | // Created by cgo -godefs - DO NOT EDIT 5 | // cgo -godefs types_linux.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x180 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type utmp struct { 26 | Type int16 27 | Pad_cgo_0 [2]byte 28 | Pid int32 29 | Line [32]int8 30 | Id [4]int8 31 | User [32]int8 32 | Host [256]int8 33 | Exit exit_status 34 | Session int32 35 | Tv timeval 36 | Addr_v6 [4]int32 37 | X__glibc_reserved [20]int8 38 | } 39 | 40 | type exit_status struct { 41 | Termination int16 42 | Exit int16 43 | } 44 | 45 | type timeval struct { 46 | Sec int64 47 | Usec int64 48 | } 49 | -------------------------------------------------------------------------------- /host/host_linux_riscv64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_linux.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x8 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x8 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x180 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int64 20 | _C_long_long int64 21 | ) 22 | 23 | type utmp struct { 24 | Type int16 25 | Pid int32 26 | Line [32]int8 27 | Id [4]int8 28 | User [32]int8 29 | Host [256]int8 30 | Exit exit_status 31 | Session int32 32 | Tv _Ctype_struct___0 33 | Addr_v6 [4]int32 34 | X__glibc_reserved [20]uint8 35 | } 36 | 37 | type exit_status struct { 38 | Termination int16 39 | Exit int16 40 | } 41 | 42 | type timeval struct { 43 | Sec int64 44 | Usec int64 45 | } 46 | 47 | type _Ctype_struct___0 struct { 48 | Sec int32 49 | Usec int32 50 | } 51 | -------------------------------------------------------------------------------- /host/host_linux_s390x.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux && s390x 3 | 4 | // Created by cgo -godefs - DO NOT EDIT 5 | // cgo -godefs types_linux.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x180 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type utmp struct { 26 | Type int16 27 | Pad_cgo_0 [2]byte 28 | Pid int32 29 | Line [32]int8 30 | Id [4]int8 31 | User [32]int8 32 | Host [256]int8 33 | Exit exit_status 34 | Session int32 35 | Tv timeval 36 | Addr_v6 [4]int32 37 | X__glibc_reserved [20]int8 38 | } 39 | 40 | type exit_status struct { 41 | Termination int16 42 | Exit int16 43 | } 44 | 45 | type timeval struct { 46 | Sec int64 47 | Usec int64 48 | } 49 | -------------------------------------------------------------------------------- /host/host_linux_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux 3 | 4 | package host 5 | 6 | import ( 7 | "context" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/shirou/gopsutil/v4/common" 14 | ) 15 | 16 | func TestGetRedhatishVersion(t *testing.T) { 17 | var ret string 18 | c := []string{"Rawhide"} 19 | ret = getRedhatishVersion(c) 20 | assert.Equalf(t, "rawhide", ret, "Could not get version rawhide: %v", ret) 21 | 22 | c = []string{"Fedora release 15 (Lovelock)"} 23 | ret = getRedhatishVersion(c) 24 | assert.Equalf(t, "15", ret, "Could not get version fedora: %v", ret) 25 | 26 | c = []string{"Enterprise Linux Server release 5.5 (Carthage)"} 27 | ret = getRedhatishVersion(c) 28 | assert.Equalf(t, "5.5", ret, "Could not get version redhat enterprise: %v", ret) 29 | 30 | c = []string{""} 31 | ret = getRedhatishVersion(c) 32 | assert.Emptyf(t, ret, "Could not get version with no value: %v", ret) 33 | } 34 | 35 | func TestGetRedhatishPlatform(t *testing.T) { 36 | var ret string 37 | c := []string{"red hat"} 38 | ret = getRedhatishPlatform(c) 39 | assert.Equalf(t, "redhat", ret, "Could not get platform redhat: %v", ret) 40 | 41 | c = []string{"Fedora release 15 (Lovelock)"} 42 | ret = getRedhatishPlatform(c) 43 | assert.Equalf(t, "fedora", ret, "Could not get platform fedora: %v", ret) 44 | 45 | c = []string{"Enterprise Linux Server release 5.5 (Carthage)"} 46 | ret = getRedhatishPlatform(c) 47 | assert.Equalf(t, "enterprise", ret, "Could not get platform redhat enterprise: %v", ret) 48 | 49 | c = []string{""} 50 | ret = getRedhatishPlatform(c) 51 | assert.Emptyf(t, ret, "Could not get platform with no value: %v", ret) 52 | } 53 | 54 | func TestGetlsbStruct(t *testing.T) { 55 | cases := []struct { 56 | root string 57 | id string 58 | release string 59 | codename string 60 | description string 61 | }{ 62 | {"arch", "Arch", "rolling", "", "Arch Linux"}, 63 | {"ubuntu_22_04", "Ubuntu", "22.04", "jammy", "Ubuntu 22.04.2 LTS"}, 64 | } 65 | 66 | for _, tt := range cases { 67 | tt := tt 68 | t.Run(tt.root, func(t *testing.T) { 69 | ctx := context.WithValue(context.Background(), 70 | common.EnvKey, 71 | common.EnvMap{common.HostEtcEnvKey: "./testdata/linux/lsbStruct/" + tt.root}, 72 | ) 73 | 74 | v, err := getlsbStruct(ctx) 75 | require.NoError(t, err) 76 | assert.Equalf(t, v.ID, tt.id, "ID: want %v, got %v", tt.id, v.ID) 77 | assert.Equalf(t, v.Release, tt.release, "Release: want %v, got %v", tt.release, v.Release) 78 | assert.Equalf(t, v.Codename, tt.codename, "Codename: want %v, got %v", tt.codename, v.Codename) 79 | assert.Equalf(t, v.Description, tt.description, "Description: want %v, got %v", tt.description, v.Description) 80 | 81 | t.Log(v) 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /host/host_netbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build netbsd 3 | 4 | package host 5 | 6 | import ( 7 | "context" 8 | "strings" 9 | 10 | "golang.org/x/sys/unix" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | func HostIDWithContext(_ context.Context) (string, error) { 16 | return "", common.ErrNotImplementedError 17 | } 18 | 19 | func numProcs(_ context.Context) (uint64, error) { 20 | return 0, common.ErrNotImplementedError 21 | } 22 | 23 | func PlatformInformationWithContext(_ context.Context) (string, string, string, error) { 24 | platform := "" 25 | family := "" 26 | version := "" 27 | 28 | p, err := unix.Sysctl("kern.ostype") 29 | if err == nil { 30 | platform = strings.ToLower(p) 31 | } 32 | v, err := unix.Sysctl("kern.osrelease") 33 | if err == nil { 34 | version = strings.ToLower(v) 35 | } 36 | 37 | return platform, family, version, nil 38 | } 39 | 40 | func VirtualizationWithContext(_ context.Context) (string, string, error) { 41 | return "", "", common.ErrNotImplementedError 42 | } 43 | 44 | func UsersWithContext(_ context.Context) ([]UserStat, error) { 45 | var ret []UserStat 46 | return ret, common.ErrNotImplementedError 47 | } 48 | 49 | func KernelVersionWithContext(ctx context.Context) (string, error) { 50 | _, _, version, err := PlatformInformationWithContext(ctx) 51 | return version, err 52 | } 53 | -------------------------------------------------------------------------------- /host/host_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd 3 | 4 | package host 5 | 6 | import ( 7 | "bytes" 8 | "context" 9 | "encoding/binary" 10 | "io" 11 | "os" 12 | "strings" 13 | "unsafe" 14 | 15 | "golang.org/x/sys/unix" 16 | 17 | "github.com/shirou/gopsutil/v4/internal/common" 18 | "github.com/shirou/gopsutil/v4/process" 19 | ) 20 | 21 | const ( 22 | UTNameSize = 32 /* see MAXLOGNAME in */ 23 | UTLineSize = 8 24 | UTHostSize = 16 25 | ) 26 | 27 | func HostIDWithContext(_ context.Context) (string, error) { 28 | return "", common.ErrNotImplementedError 29 | } 30 | 31 | func numProcs(ctx context.Context) (uint64, error) { 32 | procs, err := process.PidsWithContext(ctx) 33 | if err != nil { 34 | return 0, err 35 | } 36 | return uint64(len(procs)), nil 37 | } 38 | 39 | func PlatformInformationWithContext(_ context.Context) (string, string, string, error) { 40 | platform := "" 41 | family := "" 42 | version := "" 43 | 44 | p, err := unix.Sysctl("kern.ostype") 45 | if err == nil { 46 | platform = strings.ToLower(p) 47 | } 48 | v, err := unix.Sysctl("kern.osrelease") 49 | if err == nil { 50 | version = strings.ToLower(v) 51 | } 52 | 53 | return platform, family, version, nil 54 | } 55 | 56 | func VirtualizationWithContext(_ context.Context) (string, string, error) { 57 | return "", "", common.ErrNotImplementedError 58 | } 59 | 60 | func UsersWithContext(_ context.Context) ([]UserStat, error) { 61 | var ret []UserStat 62 | utmpfile := "/var/run/utmp" 63 | file, err := os.Open(utmpfile) 64 | if err != nil { 65 | return ret, err 66 | } 67 | defer file.Close() 68 | 69 | buf, err := io.ReadAll(file) 70 | if err != nil { 71 | return ret, err 72 | } 73 | 74 | entrySize := int(unsafe.Sizeof(Utmp{})) 75 | count := len(buf) / entrySize 76 | 77 | for i := 0; i < count; i++ { 78 | b := buf[i*entrySize : i*entrySize+entrySize] 79 | var u Utmp 80 | br := bytes.NewReader(b) 81 | err := binary.Read(br, binary.LittleEndian, &u) 82 | if err != nil || u.Time == 0 || u.Name[0] == 0 { 83 | continue 84 | } 85 | user := UserStat{ 86 | User: common.IntToString(u.Name[:]), 87 | Terminal: common.IntToString(u.Line[:]), 88 | Host: common.IntToString(u.Host[:]), 89 | Started: int(u.Time), 90 | } 91 | 92 | ret = append(ret, user) 93 | } 94 | 95 | return ret, nil 96 | } 97 | 98 | func KernelVersionWithContext(ctx context.Context) (string, error) { 99 | _, _, version, err := PlatformInformationWithContext(ctx) 100 | return version, err 101 | } 102 | -------------------------------------------------------------------------------- /host/host_openbsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && 386 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs host/types_openbsd.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x4 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x4 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x130 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int32 22 | _C_long_long int64 23 | ) 24 | 25 | type Utmp struct { 26 | Line [8]int8 27 | Name [32]int8 28 | Host [256]int8 29 | Time int64 30 | } 31 | type Timeval struct { 32 | Sec int64 33 | Usec int32 34 | } 35 | -------------------------------------------------------------------------------- /host/host_openbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_openbsd.go 4 | 5 | package host 6 | 7 | const ( 8 | sizeofPtr = 0x8 9 | sizeofShort = 0x2 10 | sizeofInt = 0x4 11 | sizeofLong = 0x8 12 | sizeofLongLong = 0x8 13 | sizeOfUtmp = 0x130 14 | ) 15 | 16 | type ( 17 | _C_short int16 18 | _C_int int32 19 | _C_long int64 20 | _C_long_long int64 21 | ) 22 | 23 | type Utmp struct { 24 | Line [8]int8 25 | Name [32]int8 26 | Host [256]int8 27 | Time int64 28 | } 29 | 30 | type Timeval struct { 31 | Sec int64 32 | Usec int64 33 | } 34 | -------------------------------------------------------------------------------- /host/host_openbsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && arm 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs host/types_openbsd.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x4 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x4 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x130 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int32 22 | _C_long_long int64 23 | ) 24 | 25 | type Utmp struct { 26 | Line [8]int8 27 | Name [32]int8 28 | Host [256]int8 29 | Time int64 30 | } 31 | type Timeval struct { 32 | Sec int64 33 | Usec int32 34 | } 35 | -------------------------------------------------------------------------------- /host/host_openbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs host/types_openbsd.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x130 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type Utmp struct { 26 | Line [8]int8 27 | Name [32]int8 28 | Host [256]int8 29 | Time int64 30 | } 31 | type Timeval struct { 32 | Sec int64 33 | Usec int64 34 | } 35 | -------------------------------------------------------------------------------- /host/host_openbsd_riscv64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && riscv64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs host/types_openbsd.go 6 | 7 | package host 8 | 9 | const ( 10 | sizeofPtr = 0x8 11 | sizeofShort = 0x2 12 | sizeofInt = 0x4 13 | sizeofLong = 0x8 14 | sizeofLongLong = 0x8 15 | sizeOfUtmp = 0x130 16 | ) 17 | 18 | type ( 19 | _C_short int16 20 | _C_int int32 21 | _C_long int64 22 | _C_long_long int64 23 | ) 24 | 25 | type ( 26 | Utmp struct { 27 | Line [8]int8 28 | Name [32]int8 29 | Host [256]int8 30 | Time int64 31 | } 32 | Timeval struct { 33 | Sec int64 34 | Usec int64 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /host/host_posix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux || freebsd || openbsd || netbsd || darwin || solaris 3 | 4 | package host 5 | 6 | import "golang.org/x/sys/unix" 7 | 8 | func KernelArch() (string, error) { 9 | var utsname unix.Utsname 10 | err := unix.Uname(&utsname) 11 | if err != nil { 12 | return "", err 13 | } 14 | return unix.ByteSliceToString(utsname.Machine[:]), nil 15 | } 16 | -------------------------------------------------------------------------------- /host/testdata/linux/lsbStruct/arch/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID="Arch" 2 | DISTRIB_RELEASE="rolling" 3 | DISTRIB_DESCRIPTION="Arch Linux" 4 | -------------------------------------------------------------------------------- /host/testdata/linux/lsbStruct/ubuntu_22_04/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=Ubuntu 2 | DISTRIB_RELEASE=22.04 3 | DISTRIB_CODENAME=jammy 4 | DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS" -------------------------------------------------------------------------------- /host/types_darwin.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // plus hand editing about timeval 5 | 6 | /* 7 | Input to cgo -godefs. 8 | */ 9 | 10 | package host 11 | 12 | /* 13 | #include 14 | #include 15 | */ 16 | import "C" 17 | 18 | type ( 19 | Utmpx C.struct_utmpx 20 | Timeval C.struct_timeval 21 | ) 22 | -------------------------------------------------------------------------------- /host/types_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | /* 5 | Input to cgo -godefs. 6 | */ 7 | 8 | package host 9 | 10 | /* 11 | #define KERNEL 12 | #include 13 | #include 14 | #include 15 | #include "freebsd_headers/utxdb.h" 16 | 17 | enum { 18 | sizeofPtr = sizeof(void*), 19 | }; 20 | 21 | */ 22 | import "C" 23 | 24 | // Machine characteristics; for internal use. 25 | 26 | const ( 27 | sizeofPtr = C.sizeofPtr 28 | sizeofShort = C.sizeof_short 29 | sizeofInt = C.sizeof_int 30 | sizeofLong = C.sizeof_long 31 | sizeofLongLong = C.sizeof_longlong 32 | sizeOfUtmpx = C.sizeof_struct_futx 33 | ) 34 | 35 | // Basic types 36 | 37 | type ( 38 | _C_short C.short 39 | _C_int C.int 40 | _C_long C.long 41 | _C_long_long C.longlong 42 | ) 43 | 44 | type ( 45 | Utmp C.struct_utmp // for FreeBSD 9.0 compatibility 46 | Utmpx C.struct_futx 47 | ) 48 | -------------------------------------------------------------------------------- /host/types_linux.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | /* 5 | Input to cgo -godefs. 6 | */ 7 | 8 | package host 9 | 10 | /* 11 | #include 12 | #include 13 | 14 | enum { 15 | sizeofPtr = sizeof(void*), 16 | }; 17 | 18 | */ 19 | import "C" 20 | 21 | // Machine characteristics; for internal use. 22 | 23 | const ( 24 | sizeofPtr = C.sizeofPtr 25 | sizeofShort = C.sizeof_short 26 | sizeofInt = C.sizeof_int 27 | sizeofLong = C.sizeof_long 28 | sizeofLongLong = C.sizeof_longlong 29 | sizeOfUtmp = C.sizeof_struct_utmp 30 | ) 31 | 32 | // Basic types 33 | 34 | type ( 35 | _C_short C.short 36 | _C_int C.int 37 | _C_long C.long 38 | _C_long_long C.longlong 39 | ) 40 | 41 | type ( 42 | utmp C.struct_utmp 43 | exit_status C.struct_exit_status 44 | timeval C.struct_timeval 45 | ) 46 | -------------------------------------------------------------------------------- /host/types_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | /* 5 | Input to cgo -godefs. 6 | */ 7 | 8 | package host 9 | 10 | /* 11 | #define KERNEL 12 | #include 13 | #include 14 | #include 15 | 16 | enum { 17 | sizeofPtr = sizeof(void*), 18 | }; 19 | 20 | */ 21 | import "C" 22 | 23 | // Machine characteristics; for internal use. 24 | 25 | const ( 26 | sizeofPtr = C.sizeofPtr 27 | sizeofShort = C.sizeof_short 28 | sizeofInt = C.sizeof_int 29 | sizeofLong = C.sizeof_long 30 | sizeofLongLong = C.sizeof_longlong 31 | sizeOfUtmp = C.sizeof_struct_utmp 32 | ) 33 | 34 | // Basic types 35 | 36 | type ( 37 | _C_short C.short 38 | _C_int C.int 39 | _C_long C.long 40 | _C_long_long C.longlong 41 | ) 42 | 43 | type ( 44 | Utmp C.struct_utmp 45 | Timeval C.struct_timeval 46 | ) 47 | -------------------------------------------------------------------------------- /internal/common/common_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd || openbsd 3 | 4 | package common 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "strings" 11 | "unsafe" 12 | 13 | "golang.org/x/sys/unix" 14 | ) 15 | 16 | func SysctlUint(mib string) (uint64, error) { 17 | buf, err := unix.SysctlRaw(mib) 18 | if err != nil { 19 | return 0, err 20 | } 21 | if len(buf) == 8 { // 64 bit 22 | return *(*uint64)(unsafe.Pointer(&buf[0])), nil 23 | } 24 | if len(buf) == 4 { // 32bit 25 | t := *(*uint32)(unsafe.Pointer(&buf[0])) 26 | return uint64(t), nil 27 | } 28 | return 0, fmt.Errorf("unexpected size: %s, %d", mib, len(buf)) 29 | } 30 | 31 | func DoSysctrl(mib string) ([]string, error) { 32 | cmd := exec.Command("sysctl", "-n", mib) 33 | cmd.Env = getSysctrlEnv(os.Environ()) 34 | out, err := cmd.Output() 35 | if err != nil { 36 | return []string{}, err 37 | } 38 | v := strings.Replace(string(out), "{ ", "", 1) 39 | v = strings.Replace(string(v), " }", "", 1) 40 | values := strings.Fields(string(v)) 41 | 42 | return values, nil 43 | } 44 | 45 | func CallSyscall(mib []int32) ([]byte, uint64, error) { 46 | mibptr := unsafe.Pointer(&mib[0]) 47 | miblen := uint64(len(mib)) 48 | 49 | // get required buffer size 50 | length := uint64(0) 51 | _, _, err := unix.Syscall6( 52 | unix.SYS___SYSCTL, 53 | uintptr(mibptr), 54 | uintptr(miblen), 55 | 0, 56 | uintptr(unsafe.Pointer(&length)), 57 | 0, 58 | 0) 59 | if err != 0 { 60 | var b []byte 61 | return b, length, err 62 | } 63 | if length == 0 { 64 | var b []byte 65 | return b, length, err 66 | } 67 | // get proc info itself 68 | buf := make([]byte, length) 69 | _, _, err = unix.Syscall6( 70 | unix.SYS___SYSCTL, 71 | uintptr(mibptr), 72 | uintptr(miblen), 73 | uintptr(unsafe.Pointer(&buf[0])), 74 | uintptr(unsafe.Pointer(&length)), 75 | 0, 76 | 0) 77 | if err != 0 { 78 | return buf, length, err 79 | } 80 | 81 | return buf, length, nil 82 | } 83 | -------------------------------------------------------------------------------- /internal/common/common_netbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build netbsd 3 | 4 | package common 5 | 6 | import ( 7 | "os" 8 | "os/exec" 9 | "strings" 10 | "unsafe" 11 | 12 | "golang.org/x/sys/unix" 13 | ) 14 | 15 | func DoSysctrl(mib string) ([]string, error) { 16 | cmd := exec.Command("sysctl", "-n", mib) 17 | cmd.Env = getSysctrlEnv(os.Environ()) 18 | out, err := cmd.Output() 19 | if err != nil { 20 | return []string{}, err 21 | } 22 | v := strings.Replace(string(out), "{ ", "", 1) 23 | v = strings.Replace(string(v), " }", "", 1) 24 | values := strings.Fields(string(v)) 25 | 26 | return values, nil 27 | } 28 | 29 | func CallSyscall(mib []int32) ([]byte, uint64, error) { 30 | mibptr := unsafe.Pointer(&mib[0]) 31 | miblen := uint64(len(mib)) 32 | 33 | // get required buffer size 34 | length := uint64(0) 35 | _, _, err := unix.Syscall6( 36 | unix.SYS___SYSCTL, 37 | uintptr(mibptr), 38 | uintptr(miblen), 39 | 0, 40 | uintptr(unsafe.Pointer(&length)), 41 | 0, 42 | 0) 43 | if err != 0 { 44 | var b []byte 45 | return b, length, err 46 | } 47 | if length == 0 { 48 | var b []byte 49 | return b, length, err 50 | } 51 | // get proc info itself 52 | buf := make([]byte, length) 53 | _, _, err = unix.Syscall6( 54 | unix.SYS___SYSCTL, 55 | uintptr(mibptr), 56 | uintptr(miblen), 57 | uintptr(unsafe.Pointer(&buf[0])), 58 | uintptr(unsafe.Pointer(&length)), 59 | 0, 60 | 0) 61 | if err != 0 { 62 | return buf, length, err 63 | } 64 | 65 | return buf, length, nil 66 | } 67 | -------------------------------------------------------------------------------- /internal/common/common_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd 3 | 4 | package common 5 | 6 | import ( 7 | "os" 8 | "os/exec" 9 | "strings" 10 | "unsafe" 11 | 12 | "golang.org/x/sys/unix" 13 | ) 14 | 15 | func DoSysctrl(mib string) ([]string, error) { 16 | cmd := exec.Command("sysctl", "-n", mib) 17 | cmd.Env = getSysctrlEnv(os.Environ()) 18 | out, err := cmd.Output() 19 | if err != nil { 20 | return []string{}, err 21 | } 22 | v := strings.Replace(string(out), "{ ", "", 1) 23 | v = strings.Replace(string(v), " }", "", 1) 24 | values := strings.Fields(string(v)) 25 | 26 | return values, nil 27 | } 28 | 29 | func CallSyscall(mib []int32) ([]byte, uint64, error) { 30 | mibptr := unsafe.Pointer(&mib[0]) 31 | miblen := uint64(len(mib)) 32 | 33 | // get required buffer size 34 | length := uint64(0) 35 | _, _, err := unix.Syscall6( 36 | unix.SYS___SYSCTL, 37 | uintptr(mibptr), 38 | uintptr(miblen), 39 | 0, 40 | uintptr(unsafe.Pointer(&length)), 41 | 0, 42 | 0) 43 | if err != 0 { 44 | var b []byte 45 | return b, length, err 46 | } 47 | if length == 0 { 48 | var b []byte 49 | return b, length, err 50 | } 51 | // get proc info itself 52 | buf := make([]byte, length) 53 | _, _, err = unix.Syscall6( 54 | unix.SYS___SYSCTL, 55 | uintptr(mibptr), 56 | uintptr(miblen), 57 | uintptr(unsafe.Pointer(&buf[0])), 58 | uintptr(unsafe.Pointer(&length)), 59 | 0, 60 | 0) 61 | if err != 0 { 62 | return buf, length, err 63 | } 64 | 65 | return buf, length, nil 66 | } 67 | -------------------------------------------------------------------------------- /internal/common/common_testing.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package common 3 | 4 | import ( 5 | "errors" 6 | "testing" 7 | ) 8 | 9 | func SkipIfNotImplementedErr(tb testing.TB, err error) { 10 | tb.Helper() 11 | if errors.Is(err, ErrNotImplementedError) { 12 | tb.Skip("not implemented") 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /internal/common/common_unix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux || freebsd || darwin || openbsd 3 | 4 | package common 5 | 6 | import ( 7 | "context" 8 | "errors" 9 | "os/exec" 10 | "strconv" 11 | "strings" 12 | ) 13 | 14 | func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ...string) ([]string, error) { 15 | var cmd []string 16 | if pid == 0 { // will get from all processes. 17 | cmd = []string{"-a", "-n", "-P"} 18 | } else { 19 | cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))} 20 | } 21 | cmd = append(cmd, args...) 22 | out, err := invoke.CommandWithContext(ctx, "lsof", cmd...) 23 | if err != nil { 24 | if errors.Is(err, exec.ErrNotFound) { 25 | return []string{}, err 26 | } 27 | // if no pid found, lsof returns code 1. 28 | if err.Error() == "exit status 1" && len(out) == 0 { 29 | return []string{}, nil 30 | } 31 | } 32 | lines := strings.Split(string(out), "\n") 33 | 34 | var ret []string 35 | for _, l := range lines[1:] { 36 | if len(l) == 0 { 37 | continue 38 | } 39 | ret = append(ret, l) 40 | } 41 | return ret, nil 42 | } 43 | -------------------------------------------------------------------------------- /internal/common/endian.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package common 3 | 4 | import "unsafe" 5 | 6 | // IsLittleEndian checks if the current platform uses little-endian. 7 | // copied from https://github.com/ntrrg/ntgo/blob/v0.8.0/runtime/infrastructure.go#L16 (MIT License) 8 | func IsLittleEndian() bool { 9 | var x int16 = 0x0011 10 | return *(*byte)(unsafe.Pointer(&x)) == 0x11 11 | } 12 | -------------------------------------------------------------------------------- /internal/common/sleep.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package common 3 | 4 | import ( 5 | "context" 6 | "time" 7 | ) 8 | 9 | // Sleep awaits for provided interval. 10 | // Can be interrupted by context cancellation. 11 | func Sleep(ctx context.Context, interval time.Duration) error { 12 | timer := time.NewTimer(interval) 13 | select { 14 | case <-ctx.Done(): 15 | if !timer.Stop() { 16 | <-timer.C 17 | } 18 | return ctx.Err() 19 | case <-timer.C: 20 | return nil 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /internal/common/sleep_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package common_test 3 | 4 | import ( 5 | "context" 6 | "errors" 7 | "testing" 8 | "time" 9 | 10 | "github.com/shirou/gopsutil/v4/internal/common" 11 | ) 12 | 13 | func TestSleep(test *testing.T) { 14 | const dt = 50 * time.Millisecond 15 | t := func(name string, ctx context.Context, expected error) { 16 | test.Run(name, func(test *testing.T) { 17 | err := common.Sleep(ctx, dt) 18 | if !errors.Is(err, expected) { 19 | test.Errorf("expected %v, got %v", expected, err) 20 | } 21 | }) 22 | } 23 | 24 | ctx := context.Background() 25 | canceled, cancel := context.WithCancel(ctx) 26 | cancel() 27 | 28 | t("background context", ctx, nil) 29 | t("canceled context", canceled, context.Canceled) 30 | } 31 | -------------------------------------------------------------------------------- /internal/common/warnings.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package common 3 | 4 | import "fmt" 5 | 6 | type Warnings struct { 7 | List []error 8 | Verbose bool 9 | } 10 | 11 | func (w *Warnings) Add(err error) { 12 | w.List = append(w.List, err) 13 | } 14 | 15 | func (w *Warnings) Reference() error { 16 | if len(w.List) > 0 { 17 | return w 18 | } 19 | return nil 20 | } 21 | 22 | func (w *Warnings) Error() string { 23 | if w.Verbose { 24 | str := "" 25 | for i, e := range w.List { 26 | str += fmt.Sprintf("\tError %d: %s\n", i, e.Error()) 27 | } 28 | return str 29 | } 30 | return fmt.Sprintf("Number of warnings: %v", len(w.List)) 31 | } 32 | -------------------------------------------------------------------------------- /load/load.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package load 3 | 4 | import ( 5 | "encoding/json" 6 | 7 | "github.com/shirou/gopsutil/v4/internal/common" 8 | ) 9 | 10 | var invoke common.Invoker = common.Invoke{} 11 | 12 | type AvgStat struct { 13 | Load1 float64 `json:"load1"` 14 | Load5 float64 `json:"load5"` 15 | Load15 float64 `json:"load15"` 16 | } 17 | 18 | func (l AvgStat) String() string { 19 | s, _ := json.Marshal(l) 20 | return string(s) 21 | } 22 | 23 | type MiscStat struct { 24 | ProcsTotal int `json:"procsTotal"` 25 | ProcsCreated int `json:"procsCreated"` 26 | ProcsRunning int `json:"procsRunning"` 27 | ProcsBlocked int `json:"procsBlocked"` 28 | Ctxt int `json:"ctxt"` 29 | } 30 | 31 | func (m MiscStat) String() string { 32 | s, _ := json.Marshal(m) 33 | return string(s) 34 | } 35 | -------------------------------------------------------------------------------- /load/load_aix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix 3 | 4 | package load 5 | 6 | import ( 7 | "context" 8 | ) 9 | 10 | func Avg() (*AvgStat, error) { 11 | return AvgWithContext(context.Background()) 12 | } 13 | 14 | // Misc returns miscellaneous host-wide statistics. 15 | // darwin use ps command to get process running/blocked count. 16 | // Almost same as Darwin implementation, but state is different. 17 | func Misc() (*MiscStat, error) { 18 | return MiscWithContext(context.Background()) 19 | } 20 | -------------------------------------------------------------------------------- /load/load_aix_cgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && cgo 3 | 4 | package load 5 | 6 | /* 7 | #cgo LDFLAGS: -L/usr/lib -lperfstat 8 | 9 | #include 10 | #include 11 | */ 12 | import "C" 13 | 14 | import ( 15 | "context" 16 | "unsafe" 17 | 18 | "github.com/power-devops/perfstat" 19 | ) 20 | 21 | func AvgWithContext(ctx context.Context) (*AvgStat, error) { 22 | c, err := perfstat.CpuTotalStat() 23 | if err != nil { 24 | return nil, err 25 | } 26 | ret := &AvgStat{ 27 | Load1: float64(c.LoadAvg1), 28 | Load5: float64(c.LoadAvg5), 29 | Load15: float64(c.LoadAvg15), 30 | } 31 | 32 | return ret, nil 33 | } 34 | 35 | func MiscWithContext(ctx context.Context) (*MiscStat, error) { 36 | info := C.struct_procentry64{} 37 | cpid := C.pid_t(0) 38 | 39 | ret := MiscStat{} 40 | for { 41 | // getprocs first argument is a void* 42 | num, err := C.getprocs64(unsafe.Pointer(&info), C.sizeof_struct_procentry64, nil, 0, &cpid, 1) 43 | if err != nil { 44 | return nil, err 45 | } 46 | 47 | ret.ProcsTotal++ 48 | switch info.pi_state { 49 | case C.SACTIVE: 50 | ret.ProcsRunning++ 51 | case C.SSTOP: 52 | ret.ProcsBlocked++ 53 | } 54 | 55 | if num == 0 { 56 | break 57 | } 58 | } 59 | return &ret, nil 60 | } 61 | -------------------------------------------------------------------------------- /load/load_aix_nocgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && !cgo 3 | 4 | package load 5 | 6 | import ( 7 | "context" 8 | "regexp" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | var separator = regexp.MustCompile(`,?\s+`) 16 | 17 | func AvgWithContext(ctx context.Context) (*AvgStat, error) { 18 | line, err := invoke.CommandWithContext(ctx, "uptime") 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | idx := strings.Index(string(line), "load average:") 24 | if idx < 0 { 25 | return nil, common.ErrNotImplementedError 26 | } 27 | ret := &AvgStat{} 28 | 29 | p := separator.Split(string(line[idx:]), 5) 30 | if 4 < len(p) && p[0] == "load" && p[1] == "average:" { 31 | if t, err := strconv.ParseFloat(p[2], 64); err == nil { 32 | ret.Load1 = t 33 | } 34 | if t, err := strconv.ParseFloat(p[3], 64); err == nil { 35 | ret.Load5 = t 36 | } 37 | if t, err := strconv.ParseFloat(p[4], 64); err == nil { 38 | ret.Load15 = t 39 | } 40 | return ret, nil 41 | } 42 | 43 | return nil, common.ErrNotImplementedError 44 | } 45 | 46 | func MiscWithContext(ctx context.Context) (*MiscStat, error) { 47 | out, err := invoke.CommandWithContext(ctx, "ps", "-Ao", "state") 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | ret := &MiscStat{} 53 | for _, line := range strings.Split(string(out), "\n") { 54 | ret.ProcsTotal++ 55 | switch line { 56 | case "R": 57 | case "A": 58 | ret.ProcsRunning++ 59 | case "T": 60 | ret.ProcsBlocked++ 61 | default: 62 | continue 63 | } 64 | } 65 | return ret, nil 66 | } 67 | -------------------------------------------------------------------------------- /load/load_bsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd || openbsd 3 | 4 | package load 5 | 6 | import ( 7 | "context" 8 | "strings" 9 | "unsafe" 10 | 11 | "golang.org/x/sys/unix" 12 | ) 13 | 14 | func Avg() (*AvgStat, error) { 15 | return AvgWithContext(context.Background()) 16 | } 17 | 18 | func AvgWithContext(_ context.Context) (*AvgStat, error) { 19 | // This SysctlRaw method borrowed from 20 | // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go 21 | type loadavg struct { 22 | load [3]uint32 23 | scale int 24 | } 25 | b, err := unix.SysctlRaw("vm.loadavg") 26 | if err != nil { 27 | return nil, err 28 | } 29 | load := *(*loadavg)(unsafe.Pointer((&b[0]))) 30 | scale := float64(load.scale) 31 | ret := &AvgStat{ 32 | Load1: float64(load.load[0]) / scale, 33 | Load5: float64(load.load[1]) / scale, 34 | Load15: float64(load.load[2]) / scale, 35 | } 36 | 37 | return ret, nil 38 | } 39 | 40 | type forkstat struct { 41 | forks int 42 | vforks int 43 | __tforks int //nolint:revive //FIXME 44 | } 45 | 46 | // Misc returns miscellaneous host-wide statistics. 47 | // darwin use ps command to get process running/blocked count. 48 | // Almost same as Darwin implementation, but state is different. 49 | func Misc() (*MiscStat, error) { 50 | return MiscWithContext(context.Background()) 51 | } 52 | 53 | func MiscWithContext(ctx context.Context) (*MiscStat, error) { 54 | out, err := invoke.CommandWithContext(ctx, "ps", "axo", "state") 55 | if err != nil { 56 | return nil, err 57 | } 58 | lines := strings.Split(string(out), "\n") 59 | 60 | ret := MiscStat{} 61 | for _, l := range lines { 62 | if strings.Contains(l, "R") { 63 | ret.ProcsRunning++ 64 | } else if strings.Contains(l, "D") { 65 | ret.ProcsBlocked++ 66 | } 67 | } 68 | 69 | f, err := getForkStat() 70 | if err != nil { 71 | return nil, err 72 | } 73 | ret.ProcsCreated = f.forks 74 | 75 | return &ret, nil 76 | } 77 | -------------------------------------------------------------------------------- /load/load_darwin.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin 3 | 4 | package load 5 | 6 | import ( 7 | "context" 8 | "strings" 9 | "unsafe" 10 | 11 | "golang.org/x/sys/unix" 12 | ) 13 | 14 | func Avg() (*AvgStat, error) { 15 | return AvgWithContext(context.Background()) 16 | } 17 | 18 | func AvgWithContext(_ context.Context) (*AvgStat, error) { 19 | // This SysctlRaw method borrowed from 20 | // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go 21 | // this implementation is common with BSDs 22 | type loadavg struct { 23 | load [3]uint32 24 | scale int 25 | } 26 | b, err := unix.SysctlRaw("vm.loadavg") 27 | if err != nil { 28 | return nil, err 29 | } 30 | load := *(*loadavg)(unsafe.Pointer((&b[0]))) 31 | scale := float64(load.scale) 32 | ret := &AvgStat{ 33 | Load1: float64(load.load[0]) / scale, 34 | Load5: float64(load.load[1]) / scale, 35 | Load15: float64(load.load[2]) / scale, 36 | } 37 | 38 | return ret, nil 39 | } 40 | 41 | // Misc returns miscellaneous host-wide statistics. 42 | // darwin use ps command to get process running/blocked count. 43 | // Almost same as FreeBSD implementation, but state is different. 44 | // U means 'Uninterruptible Sleep'. 45 | func Misc() (*MiscStat, error) { 46 | return MiscWithContext(context.Background()) 47 | } 48 | 49 | func MiscWithContext(ctx context.Context) (*MiscStat, error) { 50 | out, err := invoke.CommandWithContext(ctx, "ps", "axo", "state") 51 | if err != nil { 52 | return nil, err 53 | } 54 | lines := strings.Split(string(out), "\n") 55 | 56 | ret := MiscStat{} 57 | for _, l := range lines { 58 | if strings.Contains(l, "R") { 59 | ret.ProcsRunning++ 60 | } else if strings.Contains(l, "U") { 61 | // uninterruptible sleep == blocked 62 | ret.ProcsBlocked++ 63 | } 64 | } 65 | 66 | return &ret, nil 67 | } 68 | -------------------------------------------------------------------------------- /load/load_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !darwin && !linux && !freebsd && !openbsd && !windows && !solaris && !aix 3 | 4 | package load 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func Avg() (*AvgStat, error) { 13 | return AvgWithContext(context.Background()) 14 | } 15 | 16 | func AvgWithContext(_ context.Context) (*AvgStat, error) { 17 | return nil, common.ErrNotImplementedError 18 | } 19 | 20 | func Misc() (*MiscStat, error) { 21 | return MiscWithContext(context.Background()) 22 | } 23 | 24 | func MiscWithContext(_ context.Context) (*MiscStat, error) { 25 | return nil, common.ErrNotImplementedError 26 | } 27 | -------------------------------------------------------------------------------- /load/load_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd 3 | 4 | package load 5 | 6 | func getForkStat() (forkstat, error) { 7 | return forkstat{}, nil 8 | } 9 | -------------------------------------------------------------------------------- /load/load_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd 3 | 4 | package load 5 | 6 | import ( 7 | "unsafe" 8 | 9 | "golang.org/x/sys/unix" 10 | ) 11 | 12 | func getForkStat() (forkstat, error) { 13 | b, err := unix.SysctlRaw("kern.forkstat") 14 | if err != nil { 15 | return forkstat{}, err 16 | } 17 | return *(*forkstat)(unsafe.Pointer((&b[0]))), nil 18 | } 19 | -------------------------------------------------------------------------------- /load/load_solaris.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build solaris 3 | 4 | package load 5 | 6 | import ( 7 | "bufio" 8 | "bytes" 9 | "context" 10 | "strconv" 11 | "strings" 12 | ) 13 | 14 | func Avg() (*AvgStat, error) { 15 | return AvgWithContext(context.Background()) 16 | } 17 | 18 | func AvgWithContext(ctx context.Context) (*AvgStat, error) { 19 | out, err := invoke.CommandWithContext(ctx, "kstat", "-p", "unix:0:system_misc:avenrun_*") 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | avg := &AvgStat{} 25 | scanner := bufio.NewScanner(bytes.NewReader(out)) 26 | for scanner.Scan() { 27 | flds := strings.Fields(scanner.Text()) 28 | if len(flds) < 2 { 29 | continue 30 | } 31 | var tgt *float64 32 | switch { 33 | case strings.HasSuffix(flds[0], ":avenrun_1min"): 34 | tgt = &avg.Load1 35 | case strings.HasSuffix(flds[0], ":avenrun_5min"): 36 | tgt = &avg.Load5 37 | case strings.HasSuffix(flds[0], ":avenrun_15min"): 38 | tgt = &avg.Load15 39 | default: 40 | continue 41 | } 42 | v, err := strconv.ParseInt(flds[1], 10, 64) 43 | if err != nil { 44 | return nil, err 45 | } 46 | *tgt = float64(v) / (1 << 8) 47 | } 48 | if err = scanner.Err(); err != nil { 49 | return nil, err 50 | } 51 | 52 | return avg, nil 53 | } 54 | 55 | func Misc() (*MiscStat, error) { 56 | return MiscWithContext(context.Background()) 57 | } 58 | 59 | func MiscWithContext(ctx context.Context) (*MiscStat, error) { 60 | out, err := invoke.CommandWithContext(ctx, "ps", "-efo", "s") 61 | if err != nil { 62 | return nil, err 63 | } 64 | lines := strings.Split(string(out), "\n") 65 | 66 | ret := MiscStat{} 67 | for _, l := range lines { 68 | if l == "O" { 69 | ret.ProcsRunning++ 70 | } 71 | } 72 | 73 | return &ret, nil 74 | } 75 | -------------------------------------------------------------------------------- /load/load_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | package load 3 | 4 | import ( 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | 11 | "github.com/shirou/gopsutil/v4/internal/common" 12 | ) 13 | 14 | func TestAvg(t *testing.T) { 15 | v, err := Avg() 16 | common.SkipIfNotImplementedErr(t, err) 17 | require.NoError(t, err) 18 | 19 | empty := &AvgStat{} 20 | assert.NotSamef(t, v, empty, "error load: %v", v) 21 | t.Log(v) 22 | } 23 | 24 | func TestAvgStat_String(t *testing.T) { 25 | v := AvgStat{ 26 | Load1: 10.1, 27 | Load5: 20.1, 28 | Load15: 30.1, 29 | } 30 | e := `{"load1":10.1,"load5":20.1,"load15":30.1}` 31 | assert.JSONEqf(t, e, fmt.Sprintf("%v", v), "LoadAvgStat string is invalid: %v", v) 32 | t.Log(e) 33 | } 34 | 35 | func TestMisc(t *testing.T) { 36 | v, err := Misc() 37 | common.SkipIfNotImplementedErr(t, err) 38 | require.NoError(t, err) 39 | 40 | empty := &MiscStat{} 41 | assert.NotSamef(t, v, empty, "error load: %v", v) 42 | t.Log(v) 43 | } 44 | 45 | func TestMiscStatString(t *testing.T) { 46 | v := MiscStat{ 47 | ProcsTotal: 4, 48 | ProcsCreated: 5, 49 | ProcsRunning: 1, 50 | ProcsBlocked: 2, 51 | Ctxt: 3, 52 | } 53 | e := `{"procsTotal":4,"procsCreated":5,"procsRunning":1,"procsBlocked":2,"ctxt":3}` 54 | assert.JSONEqf(t, e, fmt.Sprintf("%v", v), "TestMiscString string is invalid: %v", v) 55 | t.Log(e) 56 | } 57 | 58 | func BenchmarkLoad(b *testing.B) { 59 | loadAvg := func(tb testing.TB) { 60 | tb.Helper() 61 | v, err := Avg() 62 | common.SkipIfNotImplementedErr(tb, err) 63 | require.NoErrorf(tb, err, "error %v", err) 64 | empty := &AvgStat{} 65 | assert.NotSamef(tb, v, empty, "error load: %v", v) 66 | } 67 | 68 | b.Run("FirstCall", func(b *testing.B) { 69 | loadAvg(b) 70 | }) 71 | 72 | b.Run("SubsequentCalls", func(b *testing.B) { 73 | for i := 0; i < b.N; i++ { 74 | loadAvg(b) 75 | } 76 | }) 77 | } 78 | -------------------------------------------------------------------------------- /load/load_windows.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build windows 3 | 4 | package load 5 | 6 | import ( 7 | "context" 8 | "math" 9 | "sync" 10 | "time" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | var ( 16 | loadErr error 17 | loadAvg1M = 0.0 18 | loadAvg5M = 0.0 19 | loadAvg15M = 0.0 20 | loadAvgMutex sync.RWMutex 21 | loadAvgGoroutineOnce sync.Once 22 | ) 23 | 24 | // loadAvgGoroutine updates avg data by fetching current load by interval 25 | // TODO instead of this goroutine, we can register a Win32 counter just as psutil does 26 | // see https://psutil.readthedocs.io/en/latest/#psutil.getloadavg 27 | // code https://github.com/giampaolo/psutil/blob/8415355c8badc9c94418b19bdf26e622f06f0cce/psutil/arch/windows/wmi.c 28 | func loadAvgGoroutine(ctx context.Context) { 29 | var ( 30 | samplingFrequency = 5 * time.Second 31 | loadAvgFactor1M = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds()) 32 | loadAvgFactor5M = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds()) 33 | loadAvgFactor15M = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds()) 34 | currentLoad float64 35 | ) 36 | 37 | counter, err := common.ProcessorQueueLengthCounter() 38 | if err != nil || counter == nil { 39 | return 40 | } 41 | 42 | tick := time.NewTicker(samplingFrequency).C 43 | 44 | f := func() { 45 | currentLoad, err = counter.GetValue() 46 | loadAvgMutex.Lock() 47 | loadErr = err 48 | loadAvg1M = loadAvg1M*loadAvgFactor1M + currentLoad*(1-loadAvgFactor1M) 49 | loadAvg5M = loadAvg5M*loadAvgFactor5M + currentLoad*(1-loadAvgFactor5M) 50 | loadAvg15M = loadAvg15M*loadAvgFactor15M + currentLoad*(1-loadAvgFactor15M) 51 | loadAvgMutex.Unlock() 52 | } 53 | 54 | f() // run first time 55 | for { 56 | select { 57 | case <-ctx.Done(): 58 | return 59 | case <-tick: 60 | f() 61 | } 62 | } 63 | } 64 | 65 | // Avg for Windows may return 0 values for the first few 5 second intervals 66 | func Avg() (*AvgStat, error) { 67 | return AvgWithContext(context.Background()) 68 | } 69 | 70 | func AvgWithContext(ctx context.Context) (*AvgStat, error) { 71 | loadAvgGoroutineOnce.Do(func() { 72 | go loadAvgGoroutine(ctx) 73 | }) 74 | loadAvgMutex.RLock() 75 | defer loadAvgMutex.RUnlock() 76 | ret := AvgStat{ 77 | Load1: loadAvg1M, 78 | Load5: loadAvg5M, 79 | Load15: loadAvg15M, 80 | } 81 | 82 | return &ret, loadErr 83 | } 84 | 85 | func Misc() (*MiscStat, error) { 86 | return MiscWithContext(context.Background()) 87 | } 88 | 89 | func MiscWithContext(_ context.Context) (*MiscStat, error) { 90 | ret := MiscStat{} 91 | 92 | return &ret, common.ErrNotImplementedError 93 | } 94 | -------------------------------------------------------------------------------- /mem/ex_linux.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | "encoding/json" 9 | ) 10 | 11 | type ExVirtualMemory struct { 12 | ActiveFile uint64 `json:"activefile"` 13 | InactiveFile uint64 `json:"inactivefile"` 14 | ActiveAnon uint64 `json:"activeanon"` 15 | InactiveAnon uint64 `json:"inactiveanon"` 16 | Unevictable uint64 `json:"unevictable"` 17 | } 18 | 19 | func (v ExVirtualMemory) String() string { 20 | s, _ := json.Marshal(v) 21 | return string(s) 22 | } 23 | 24 | type ExLinux struct{} 25 | 26 | func NewExLinux() *ExLinux { 27 | return &ExLinux{} 28 | } 29 | 30 | func (ex *ExLinux) VirtualMemory() (*ExVirtualMemory, error) { 31 | return ex.VirtualMemoryWithContext(context.Background()) 32 | } 33 | 34 | func (ex *ExLinux) VirtualMemoryWithContext(ctx context.Context) (*ExVirtualMemory, error) { 35 | _, vmEx, err := fillFromMeminfoWithContext(ctx) 36 | if err != nil { 37 | return nil, err 38 | } 39 | return vmEx, nil 40 | } 41 | -------------------------------------------------------------------------------- /mem/ex_windows.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build windows 3 | 4 | package mem 5 | 6 | import ( 7 | "unsafe" 8 | ) 9 | 10 | // ExVirtualMemory represents Windows specific information 11 | // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex 12 | // https://learn.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-performance_information 13 | type ExVirtualMemory struct { 14 | CommitLimit uint64 `json:"commitLimit"` 15 | CommitTotal uint64 `json:"commitTotal"` 16 | VirtualTotal uint64 `json:"virtualTotal"` 17 | VirtualAvail uint64 `json:"virtualAvail"` 18 | } 19 | 20 | type ExWindows struct{} 21 | 22 | func NewExWindows() *ExWindows { 23 | return &ExWindows{} 24 | } 25 | 26 | func (e *ExWindows) VirtualMemory() (*ExVirtualMemory, error) { 27 | var memInfo memoryStatusEx 28 | memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) 29 | // If mem == 0 since this is an error according to GlobalMemoryStatusEx documentation 30 | // In that case, use err which is constructed from GetLastError(), 31 | // see https://pkg.go.dev/golang.org/x/sys/windows#LazyProc.Call 32 | mem, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) 33 | if mem == 0 { 34 | return nil, err 35 | } 36 | 37 | var perfInfo performanceInformation 38 | perfInfo.cb = uint32(unsafe.Sizeof(perfInfo)) 39 | // Analogous to above: perf == 0 is an error according to the GetPerformanceInfo documentation, 40 | // use err in that case 41 | perf, _, err := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb)) 42 | if perf == 0 { 43 | return nil, err 44 | } 45 | 46 | ret := &ExVirtualMemory{ 47 | CommitLimit: perfInfo.commitLimit * perfInfo.pageSize, 48 | CommitTotal: perfInfo.commitTotal * perfInfo.pageSize, 49 | VirtualTotal: memInfo.ullTotalVirtual, 50 | VirtualAvail: memInfo.ullAvailVirtual, 51 | } 52 | 53 | return ret, nil 54 | } 55 | -------------------------------------------------------------------------------- /mem/mem_aix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func VirtualMemory() (*VirtualMemoryStat, error) { 13 | return VirtualMemoryWithContext(context.Background()) 14 | } 15 | 16 | func SwapMemory() (*SwapMemoryStat, error) { 17 | return SwapMemoryWithContext(context.Background()) 18 | } 19 | 20 | func SwapDevices() ([]*SwapDevice, error) { 21 | return nil, common.ErrNotImplementedError 22 | } 23 | -------------------------------------------------------------------------------- /mem/mem_aix_cgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && cgo 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/power-devops/perfstat" 10 | ) 11 | 12 | func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { 13 | m, err := perfstat.MemoryTotalStat() 14 | if err != nil { 15 | return nil, err 16 | } 17 | pagesize := uint64(4096) 18 | ret := VirtualMemoryStat{ 19 | Total: uint64(m.RealTotal) * pagesize, 20 | Available: uint64(m.RealAvailable) * pagesize, 21 | Free: uint64(m.RealFree) * pagesize, 22 | Used: uint64(m.RealInUse) * pagesize, 23 | UsedPercent: 100 * float64(m.RealInUse) / float64(m.RealTotal), 24 | Active: uint64(m.VirtualActive) * pagesize, 25 | SwapTotal: uint64(m.PgSpTotal) * pagesize, 26 | SwapFree: uint64(m.PgSpFree) * pagesize, 27 | } 28 | return &ret, nil 29 | } 30 | 31 | func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { 32 | m, err := perfstat.MemoryTotalStat() 33 | if err != nil { 34 | return nil, err 35 | } 36 | pagesize := uint64(4096) 37 | swapUsed := uint64(m.PgSpTotal-m.PgSpFree-m.PgSpRsvd) * pagesize 38 | swapTotal := uint64(m.PgSpTotal) * pagesize 39 | ret := SwapMemoryStat{ 40 | Total: swapTotal, 41 | Free: uint64(m.PgSpFree) * pagesize, 42 | Used: swapUsed, 43 | UsedPercent: float64(100*swapUsed) / float64(swapTotal), 44 | Sin: uint64(m.PgSpIn), 45 | Sout: uint64(m.PgSpOut), 46 | PgIn: uint64(m.PageIn), 47 | PgOut: uint64(m.PageOut), 48 | PgFault: uint64(m.PageFaults), 49 | } 50 | return &ret, nil 51 | } 52 | -------------------------------------------------------------------------------- /mem/mem_aix_nocgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && !cgo 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | "strconv" 9 | "strings" 10 | 11 | "github.com/shirou/gopsutil/v4/internal/common" 12 | ) 13 | 14 | func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { 15 | vmem, swap, err := callSVMon(ctx, true) 16 | if err != nil { 17 | return nil, err 18 | } 19 | if vmem.Total == 0 { 20 | return nil, common.ErrNotImplementedError 21 | } 22 | vmem.SwapTotal = swap.Total 23 | vmem.SwapFree = swap.Free 24 | return vmem, nil 25 | } 26 | 27 | func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { 28 | _, swap, err := callSVMon(ctx, false) 29 | if err != nil { 30 | return nil, err 31 | } 32 | if swap.Total == 0 { 33 | return nil, common.ErrNotImplementedError 34 | } 35 | return swap, nil 36 | } 37 | 38 | func callSVMon(ctx context.Context, virt bool) (*VirtualMemoryStat, *SwapMemoryStat, error) { 39 | out, err := invoke.CommandWithContext(ctx, "svmon", "-G") 40 | if err != nil { 41 | return nil, nil, err 42 | } 43 | 44 | pagesize := uint64(4096) 45 | vmem := &VirtualMemoryStat{} 46 | swap := &SwapMemoryStat{} 47 | for _, line := range strings.Split(string(out), "\n") { 48 | if virt && strings.HasPrefix(line, "memory") { 49 | p := strings.Fields(line) 50 | if len(p) > 2 { 51 | if t, err := strconv.ParseUint(p[1], 10, 64); err == nil { 52 | vmem.Total = t * pagesize 53 | } 54 | if t, err := strconv.ParseUint(p[2], 10, 64); err == nil { 55 | vmem.Used = t * pagesize 56 | if vmem.Total > 0 { 57 | vmem.UsedPercent = 100 * float64(vmem.Used) / float64(vmem.Total) 58 | } 59 | } 60 | if t, err := strconv.ParseUint(p[3], 10, 64); err == nil { 61 | vmem.Free = t * pagesize 62 | } 63 | } 64 | } else if strings.HasPrefix(line, "pg space") { 65 | p := strings.Fields(line) 66 | if len(p) > 3 { 67 | if t, err := strconv.ParseUint(p[2], 10, 64); err == nil { 68 | swap.Total = t * pagesize 69 | } 70 | if t, err := strconv.ParseUint(p[3], 10, 64); err == nil { 71 | swap.Free = swap.Total - t*pagesize 72 | } 73 | } 74 | break 75 | } 76 | } 77 | return vmem, swap, nil 78 | } 79 | -------------------------------------------------------------------------------- /mem/mem_bsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd || openbsd || netbsd 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | const swapCommand = "swapctl" 14 | 15 | // swapctl column indexes 16 | const ( 17 | nameCol = 0 18 | totalKiBCol = 1 19 | usedKiBCol = 2 20 | ) 21 | 22 | func SwapDevices() ([]*SwapDevice, error) { 23 | return SwapDevicesWithContext(context.Background()) 24 | } 25 | 26 | func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) { 27 | output, err := invoke.CommandWithContext(ctx, swapCommand, "-lk") 28 | if err != nil { 29 | return nil, fmt.Errorf("could not execute %q: %w", swapCommand, err) 30 | } 31 | 32 | return parseSwapctlOutput(string(output)) 33 | } 34 | 35 | func parseSwapctlOutput(output string) ([]*SwapDevice, error) { 36 | lines := strings.Split(output, "\n") 37 | if len(lines) == 0 { 38 | return nil, fmt.Errorf("could not parse output of %q: no lines in %q", swapCommand, output) 39 | } 40 | 41 | // Check header headerFields are as expected. 42 | header := lines[0] 43 | header = strings.ToLower(header) 44 | header = strings.ReplaceAll(header, ":", "") 45 | headerFields := strings.Fields(header) 46 | if len(headerFields) < usedKiBCol { 47 | return nil, fmt.Errorf("couldn't parse %q: too few fields in header %q", swapCommand, header) 48 | } 49 | if headerFields[nameCol] != "device" { 50 | return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[nameCol], "device") 51 | } 52 | if headerFields[totalKiBCol] != "1kb-blocks" && headerFields[totalKiBCol] != "1k-blocks" { 53 | return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[totalKiBCol], "1kb-blocks") 54 | } 55 | if headerFields[usedKiBCol] != "used" { 56 | return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[usedKiBCol], "used") 57 | } 58 | 59 | var swapDevices []*SwapDevice 60 | for _, line := range lines[1:] { 61 | if line == "" { 62 | continue // the terminal line is typically empty 63 | } 64 | fields := strings.Fields(line) 65 | if len(fields) < usedKiBCol { 66 | return nil, fmt.Errorf("couldn't parse %q: too few fields", swapCommand) 67 | } 68 | 69 | totalKiB, err := strconv.ParseUint(fields[totalKiBCol], 10, 64) 70 | if err != nil { 71 | return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapCommand, err) 72 | } 73 | 74 | usedKiB, err := strconv.ParseUint(fields[usedKiBCol], 10, 64) 75 | if err != nil { 76 | return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapCommand, err) 77 | } 78 | 79 | swapDevices = append(swapDevices, &SwapDevice{ 80 | Name: fields[nameCol], 81 | UsedBytes: usedKiB * 1024, 82 | FreeBytes: (totalKiB - usedKiB) * 1024, 83 | }) 84 | } 85 | 86 | return swapDevices, nil 87 | } 88 | -------------------------------------------------------------------------------- /mem/mem_bsd_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd || openbsd 3 | 4 | package mem 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | const validFreeBSD = `Device: 1kB-blocks Used: 14 | /dev/gpt/swapfs 1048576 1234 15 | /dev/md0 1048576 666 16 | ` 17 | 18 | const validOpenBSD = `Device 1K-blocks Used Avail Capacity Priority 19 | /dev/wd0b 655025 1234 653791 1% 0 20 | ` 21 | 22 | const invalid = `Device: 512-blocks Used: 23 | /dev/gpt/swapfs 1048576 1234 24 | /dev/md0 1048576 666 25 | ` 26 | 27 | func TestParseSwapctlOutput_FreeBSD(t *testing.T) { 28 | stats, err := parseSwapctlOutput(validFreeBSD) 29 | require.NoError(t, err) 30 | 31 | assert.Equal(t, SwapDevice{ 32 | Name: "/dev/gpt/swapfs", 33 | UsedBytes: 1263616, 34 | FreeBytes: 1072478208, 35 | }, *stats[0]) 36 | 37 | assert.Equal(t, SwapDevice{ 38 | Name: "/dev/md0", 39 | UsedBytes: 681984, 40 | FreeBytes: 1073059840, 41 | }, *stats[1]) 42 | } 43 | 44 | func TestParseSwapctlOutput_OpenBSD(t *testing.T) { 45 | stats, err := parseSwapctlOutput(validOpenBSD) 46 | require.NoError(t, err) 47 | 48 | assert.Equal(t, SwapDevice{ 49 | Name: "/dev/wd0b", 50 | UsedBytes: 1234 * 1024, 51 | FreeBytes: 653791 * 1024, 52 | }, *stats[0]) 53 | } 54 | 55 | func TestParseSwapctlOutput_Invalid(t *testing.T) { 56 | _, err := parseSwapctlOutput(invalid) 57 | assert.Error(t, err) 58 | } 59 | 60 | func TestParseSwapctlOutput_Empty(t *testing.T) { 61 | _, err := parseSwapctlOutput("") 62 | assert.Error(t, err) 63 | } 64 | -------------------------------------------------------------------------------- /mem/mem_darwin_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin 3 | 4 | package mem 5 | 6 | import ( 7 | "strconv" 8 | "strings" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestVirtualMemoryDarwin(t *testing.T) { 16 | v, err := VirtualMemory() 17 | require.NoError(t, err) 18 | 19 | outBytes, err := invoke.Command("/usr/sbin/sysctl", "hw.memsize") 20 | require.NoError(t, err) 21 | outString := string(outBytes) 22 | outString = strings.TrimSpace(outString) 23 | outParts := strings.Split(outString, " ") 24 | actualTotal, err := strconv.ParseInt(outParts[1], 10, 64) 25 | require.NoError(t, err) 26 | assert.Equal(t, uint64(actualTotal), v.Total) 27 | 28 | assert.Positive(t, v.Available) 29 | assert.Equalf(t, v.Available, v.Free+v.Inactive, "%v", v) 30 | 31 | assert.Positive(t, v.Used) 32 | assert.Less(t, v.Used, v.Total) 33 | 34 | assert.Positive(t, v.UsedPercent) 35 | assert.Less(t, v.UsedPercent, 100.0) 36 | 37 | assert.Positive(t, v.Free) 38 | assert.Less(t, v.Free, v.Available) 39 | 40 | assert.Positive(t, v.Active) 41 | assert.Less(t, v.Active, v.Total) 42 | 43 | assert.Positive(t, v.Inactive) 44 | assert.Less(t, v.Inactive, v.Total) 45 | 46 | assert.Positive(t, v.Wired) 47 | assert.Less(t, v.Wired, v.Total) 48 | } 49 | -------------------------------------------------------------------------------- /mem/mem_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !darwin && !linux && !freebsd && !openbsd && !solaris && !windows && !plan9 && !aix && !netbsd 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func VirtualMemory() (*VirtualMemoryStat, error) { 13 | return VirtualMemoryWithContext(context.Background()) 14 | } 15 | 16 | func VirtualMemoryWithContext(_ context.Context) (*VirtualMemoryStat, error) { 17 | return nil, common.ErrNotImplementedError 18 | } 19 | 20 | func SwapMemory() (*SwapMemoryStat, error) { 21 | return SwapMemoryWithContext(context.Background()) 22 | } 23 | 24 | func SwapMemoryWithContext(_ context.Context) (*SwapMemoryStat, error) { 25 | return nil, common.ErrNotImplementedError 26 | } 27 | 28 | func SwapDevices() ([]*SwapDevice, error) { 29 | return SwapDevicesWithContext(context.Background()) 30 | } 31 | 32 | func SwapDevicesWithContext(_ context.Context) ([]*SwapDevice, error) { 33 | return nil, common.ErrNotImplementedError 34 | } 35 | -------------------------------------------------------------------------------- /mem/mem_netbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build netbsd 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | "errors" 9 | "fmt" 10 | 11 | "golang.org/x/sys/unix" 12 | ) 13 | 14 | func GetPageSize() (uint64, error) { 15 | return GetPageSizeWithContext(context.Background()) 16 | } 17 | 18 | func GetPageSizeWithContext(_ context.Context) (uint64, error) { 19 | uvmexp, err := unix.SysctlUvmexp("vm.uvmexp2") 20 | if err != nil { 21 | return 0, err 22 | } 23 | return uint64(uvmexp.Pagesize), nil 24 | } 25 | 26 | func VirtualMemory() (*VirtualMemoryStat, error) { 27 | return VirtualMemoryWithContext(context.Background()) 28 | } 29 | 30 | func VirtualMemoryWithContext(_ context.Context) (*VirtualMemoryStat, error) { 31 | uvmexp, err := unix.SysctlUvmexp("vm.uvmexp2") 32 | if err != nil { 33 | return nil, err 34 | } 35 | p := uint64(uvmexp.Pagesize) 36 | 37 | ret := &VirtualMemoryStat{ 38 | Total: uint64(uvmexp.Npages) * p, 39 | Free: uint64(uvmexp.Free) * p, 40 | Active: uint64(uvmexp.Active) * p, 41 | Inactive: uint64(uvmexp.Inactive) * p, 42 | Cached: 0, // not available 43 | Wired: uint64(uvmexp.Wired) * p, 44 | } 45 | 46 | ret.Available = ret.Inactive + ret.Cached + ret.Free 47 | ret.Used = ret.Total - ret.Available 48 | ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0 49 | 50 | // Get buffers from vm.bufmem sysctl 51 | ret.Buffers, err = unix.SysctlUint64("vm.bufmem") 52 | if err != nil { 53 | return nil, err 54 | } 55 | 56 | return ret, nil 57 | } 58 | 59 | // Return swapctl summary info 60 | func SwapMemory() (*SwapMemoryStat, error) { 61 | return SwapMemoryWithContext(context.Background()) 62 | } 63 | 64 | func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { 65 | out, err := invoke.CommandWithContext(ctx, "swapctl", "-sk") 66 | if err != nil { 67 | return &SwapMemoryStat{}, nil 68 | } 69 | 70 | line := string(out) 71 | var total, used, free uint64 72 | 73 | _, err = fmt.Sscanf(line, 74 | "total: %d 1K-blocks allocated, %d used, %d available", 75 | &total, &used, &free) 76 | if err != nil { 77 | return nil, errors.New("failed to parse swapctl output") 78 | } 79 | 80 | percent := float64(used) / float64(total) * 100 81 | return &SwapMemoryStat{ 82 | Total: total * 1024, 83 | Used: used * 1024, 84 | Free: free * 1024, 85 | UsedPercent: percent, 86 | }, nil 87 | } 88 | -------------------------------------------------------------------------------- /mem/mem_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd 3 | 4 | package mem 5 | 6 | import ( 7 | "bytes" 8 | "context" 9 | "encoding/binary" 10 | "errors" 11 | "fmt" 12 | 13 | "golang.org/x/sys/unix" 14 | 15 | "github.com/shirou/gopsutil/v4/internal/common" 16 | ) 17 | 18 | func GetPageSize() (uint64, error) { 19 | return GetPageSizeWithContext(context.Background()) 20 | } 21 | 22 | func GetPageSizeWithContext(_ context.Context) (uint64, error) { 23 | uvmexp, err := unix.SysctlUvmexp("vm.uvmexp") 24 | if err != nil { 25 | return 0, err 26 | } 27 | return uint64(uvmexp.Pagesize), nil 28 | } 29 | 30 | func VirtualMemory() (*VirtualMemoryStat, error) { 31 | return VirtualMemoryWithContext(context.Background()) 32 | } 33 | 34 | func VirtualMemoryWithContext(_ context.Context) (*VirtualMemoryStat, error) { 35 | uvmexp, err := unix.SysctlUvmexp("vm.uvmexp") 36 | if err != nil { 37 | return nil, err 38 | } 39 | p := uint64(uvmexp.Pagesize) 40 | 41 | ret := &VirtualMemoryStat{ 42 | Total: uint64(uvmexp.Npages) * p, 43 | Free: uint64(uvmexp.Free) * p, 44 | Active: uint64(uvmexp.Active) * p, 45 | Inactive: uint64(uvmexp.Inactive) * p, 46 | Cached: 0, // not available 47 | Wired: uint64(uvmexp.Wired) * p, 48 | } 49 | 50 | ret.Available = ret.Inactive + ret.Cached + ret.Free 51 | ret.Used = ret.Total - ret.Available 52 | ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0 53 | 54 | mib := []int32{CTLVfs, VfsGeneric, VfsBcacheStat} 55 | buf, length, err := common.CallSyscall(mib) 56 | if err != nil { 57 | return nil, err 58 | } 59 | if length < sizeOfBcachestats { 60 | return nil, fmt.Errorf("short syscall ret %d bytes", length) 61 | } 62 | var bcs Bcachestats 63 | br := bytes.NewReader(buf) 64 | err = common.Read(br, binary.LittleEndian, &bcs) 65 | if err != nil { 66 | return nil, err 67 | } 68 | ret.Buffers = uint64(bcs.Numbufpages) * p 69 | 70 | return ret, nil 71 | } 72 | 73 | // Return swapctl summary info 74 | func SwapMemory() (*SwapMemoryStat, error) { 75 | return SwapMemoryWithContext(context.Background()) 76 | } 77 | 78 | func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { 79 | out, err := invoke.CommandWithContext(ctx, "swapctl", "-sk") 80 | if err != nil { 81 | return &SwapMemoryStat{}, nil 82 | } 83 | 84 | line := string(out) 85 | var total, used, free uint64 86 | 87 | _, err = fmt.Sscanf(line, 88 | "total: %d 1K-blocks allocated, %d used, %d available", 89 | &total, &used, &free) 90 | if err != nil { 91 | return nil, errors.New("failed to parse swapctl output") 92 | } 93 | 94 | percent := float64(used) / float64(total) * 100 95 | return &SwapMemoryStat{ 96 | Total: total * 1024, 97 | Used: used * 1024, 98 | Free: free * 1024, 99 | UsedPercent: percent, 100 | }, nil 101 | } 102 | -------------------------------------------------------------------------------- /mem/mem_openbsd_386.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && 386 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs mem/types_openbsd.go 6 | 7 | package mem 8 | 9 | const ( 10 | CTLVfs = 10 11 | VfsGeneric = 0 12 | VfsBcacheStat = 3 13 | ) 14 | 15 | const ( 16 | sizeOfBcachestats = 0x90 17 | ) 18 | 19 | type Bcachestats struct { 20 | Numbufs int64 21 | Numbufpages int64 22 | Numdirtypages int64 23 | Numcleanpages int64 24 | Pendingwrites int64 25 | Pendingreads int64 26 | Numwrites int64 27 | Numreads int64 28 | Cachehits int64 29 | Busymapped int64 30 | Dmapages int64 31 | Highpages int64 32 | Delwribufs int64 33 | Kvaslots int64 34 | Avail int64 35 | Highflips int64 36 | Highflops int64 37 | Dmaflips int64 38 | } 39 | -------------------------------------------------------------------------------- /mem/mem_openbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | // Created by cgo -godefs - DO NOT EDIT 3 | // cgo -godefs types_openbsd.go 4 | 5 | package mem 6 | 7 | const ( 8 | CTLVfs = 10 9 | VfsGeneric = 0 10 | VfsBcacheStat = 3 11 | ) 12 | 13 | const ( 14 | sizeOfBcachestats = 0x78 15 | ) 16 | 17 | type Bcachestats struct { 18 | Numbufs int64 19 | Numbufpages int64 20 | Numdirtypages int64 21 | Numcleanpages int64 22 | Pendingwrites int64 23 | Pendingreads int64 24 | Numwrites int64 25 | Numreads int64 26 | Cachehits int64 27 | Busymapped int64 28 | Dmapages int64 29 | Highpages int64 30 | Delwribufs int64 31 | Kvaslots int64 32 | Avail int64 33 | } 34 | -------------------------------------------------------------------------------- /mem/mem_openbsd_arm.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && arm 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs mem/types_openbsd.go 6 | 7 | package mem 8 | 9 | const ( 10 | CTLVfs = 10 11 | VfsGeneric = 0 12 | VfsBcacheStat = 3 13 | ) 14 | 15 | const ( 16 | sizeOfBcachestats = 0x90 17 | ) 18 | 19 | type Bcachestats struct { 20 | Numbufs int64 21 | Numbufpages int64 22 | Numdirtypages int64 23 | Numcleanpages int64 24 | Pendingwrites int64 25 | Pendingreads int64 26 | Numwrites int64 27 | Numreads int64 28 | Cachehits int64 29 | Busymapped int64 30 | Dmapages int64 31 | Highpages int64 32 | Delwribufs int64 33 | Kvaslots int64 34 | Avail int64 35 | Highflips int64 36 | Highflops int64 37 | Dmaflips int64 38 | } 39 | -------------------------------------------------------------------------------- /mem/mem_openbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && arm64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs mem/types_openbsd.go 6 | 7 | package mem 8 | 9 | const ( 10 | CTLVfs = 10 11 | VfsGeneric = 0 12 | VfsBcacheStat = 3 13 | ) 14 | 15 | const ( 16 | sizeOfBcachestats = 0x90 17 | ) 18 | 19 | type Bcachestats struct { 20 | Numbufs int64 21 | Numbufpages int64 22 | Numdirtypages int64 23 | Numcleanpages int64 24 | Pendingwrites int64 25 | Pendingreads int64 26 | Numwrites int64 27 | Numreads int64 28 | Cachehits int64 29 | Busymapped int64 30 | Dmapages int64 31 | Highpages int64 32 | Delwribufs int64 33 | Kvaslots int64 34 | Avail int64 35 | Highflips int64 36 | Highflops int64 37 | Dmaflips int64 38 | } 39 | -------------------------------------------------------------------------------- /mem/mem_openbsd_riscv64.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd && riscv64 3 | 4 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 5 | // cgo -godefs mem/types_openbsd.go 6 | 7 | package mem 8 | 9 | const ( 10 | CTLVfs = 10 11 | VfsGeneric = 0 12 | VfsBcacheStat = 3 13 | ) 14 | 15 | const ( 16 | sizeOfBcachestats = 0x90 17 | ) 18 | 19 | type Bcachestats struct { 20 | Numbufs int64 21 | Numbufpages int64 22 | Numdirtypages int64 23 | Numcleanpages int64 24 | Pendingwrites int64 25 | Pendingreads int64 26 | Numwrites int64 27 | Numreads int64 28 | Cachehits int64 29 | Busymapped int64 30 | Dmapages int64 31 | Highpages int64 32 | Delwribufs int64 33 | Kvaslots int64 34 | Avail int64 35 | Highflips int64 36 | Highflops int64 37 | Dmaflips int64 38 | } 39 | -------------------------------------------------------------------------------- /mem/mem_plan9.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build plan9 3 | 4 | package mem 5 | 6 | import ( 7 | "context" 8 | "os" 9 | 10 | stats "github.com/lufia/plan9stats" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | func SwapMemory() (*SwapMemoryStat, error) { 16 | return SwapMemoryWithContext(context.Background()) 17 | } 18 | 19 | func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { 20 | root := os.Getenv("HOST_ROOT") 21 | m, err := stats.ReadMemStats(ctx, stats.WithRootDir(root)) 22 | if err != nil { 23 | return nil, err 24 | } 25 | u := 0.0 26 | if m.SwapPages.Avail != 0 { 27 | u = float64(m.SwapPages.Used) / float64(m.SwapPages.Avail) * 100.0 28 | } 29 | return &SwapMemoryStat{ 30 | Total: uint64(m.SwapPages.Avail * m.PageSize), 31 | Used: uint64(m.SwapPages.Used * m.PageSize), 32 | Free: uint64(m.SwapPages.Free() * m.PageSize), 33 | UsedPercent: u, 34 | }, nil 35 | } 36 | 37 | func VirtualMemory() (*VirtualMemoryStat, error) { 38 | return VirtualMemoryWithContext(context.Background()) 39 | } 40 | 41 | func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { 42 | root := os.Getenv("HOST_ROOT") 43 | m, err := stats.ReadMemStats(ctx, stats.WithRootDir(root)) 44 | if err != nil { 45 | return nil, err 46 | } 47 | u := 0.0 48 | if m.UserPages.Avail != 0 { 49 | u = float64(m.UserPages.Used) / float64(m.UserPages.Avail) * 100.0 50 | } 51 | return &VirtualMemoryStat{ 52 | Total: uint64(m.Total), 53 | Available: uint64(m.UserPages.Free() * m.PageSize), 54 | Used: uint64(m.UserPages.Used * m.PageSize), 55 | UsedPercent: u, 56 | Free: uint64(m.UserPages.Free() * m.PageSize), 57 | 58 | SwapTotal: uint64(m.SwapPages.Avail * m.PageSize), 59 | SwapFree: uint64(m.SwapPages.Free() * m.PageSize), 60 | }, nil 61 | } 62 | 63 | func SwapDevices() ([]*SwapDevice, error) { 64 | return SwapDevicesWithContext(context.Background()) 65 | } 66 | 67 | func SwapDevicesWithContext(_ context.Context) ([]*SwapDevice, error) { 68 | return nil, common.ErrNotImplementedError 69 | } 70 | -------------------------------------------------------------------------------- /mem/mem_plan9_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build plan9 3 | 4 | package mem 5 | 6 | import ( 7 | "reflect" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/shirou/gopsutil/v4/internal/common" 14 | ) 15 | 16 | var virtualMemoryTests = []struct { 17 | mockedRootFS string 18 | stat *VirtualMemoryStat 19 | }{ 20 | { 21 | "swap", &VirtualMemoryStat{ 22 | Total: 1071185920, 23 | Available: 808370176, 24 | Used: 11436032, 25 | UsedPercent: 1.3949677238843257, 26 | Free: 808370176, 27 | SwapTotal: 655360000, 28 | SwapFree: 655360000, 29 | }, 30 | }, 31 | } 32 | 33 | func TestVirtualMemoryPlan9(t *testing.T) { 34 | for _, tt := range virtualMemoryTests { 35 | t.Run(tt.mockedRootFS, func(t *testing.T) { 36 | t.Setenv("HOST_ROOT", "testdata/plan9/virtualmemory/") 37 | 38 | stat, err := VirtualMemory() 39 | common.SkipIfNotImplementedErr(t, err) 40 | require.NoError(t, err) 41 | assert.Truef(t, reflect.DeepEqual(stat, tt.stat), "got: %+v\nwant: %+v", stat, tt.stat) 42 | }) 43 | } 44 | } 45 | 46 | var swapMemoryTests = []struct { 47 | mockedRootFS string 48 | swap *SwapMemoryStat 49 | }{ 50 | { 51 | "swap", &SwapMemoryStat{ 52 | Total: 655360000, 53 | Used: 0, 54 | Free: 655360000, 55 | }, 56 | }, 57 | } 58 | 59 | func TestSwapMemoryPlan9(t *testing.T) { 60 | for _, tt := range swapMemoryTests { 61 | t.Run(tt.mockedRootFS, func(t *testing.T) { 62 | t.Setenv("HOST_ROOT", "testdata/plan9/virtualmemory/") 63 | 64 | swap, err := SwapMemory() 65 | common.SkipIfNotImplementedErr(t, err) 66 | require.NoError(t, err) 67 | assert.Truef(t, reflect.DeepEqual(swap, tt.swap), "got: %+v\nwant: %+v", swap, tt.swap) 68 | }) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /mem/mem_solaris_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build solaris 3 | 4 | package mem 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | const validFile = `swapfile dev swaplo blocks free 14 | /dev/zvol/dsk/rpool/swap 256,1 16 1058800 1058800 15 | /dev/dsk/c0t0d0s1 136,1 16 1638608 1600528` 16 | 17 | const invalidFile = `swapfile dev swaplo INVALID free 18 | /dev/zvol/dsk/rpool/swap 256,1 16 1058800 1058800 19 | /dev/dsk/c0t0d0s1 136,1 16 1638608 1600528` 20 | 21 | func TestParseSwapsCommandOutput_Valid(t *testing.T) { 22 | stats, err := parseSwapsCommandOutput(validFile) 23 | require.NoError(t, err) 24 | 25 | assert.Equal(t, SwapDevice{ 26 | Name: "/dev/zvol/dsk/rpool/swap", 27 | UsedBytes: 0, 28 | FreeBytes: 1058800 * 512, 29 | }, *stats[0]) 30 | 31 | assert.Equal(t, SwapDevice{ 32 | Name: "/dev/dsk/c0t0d0s1", 33 | UsedBytes: 38080 * 512, 34 | FreeBytes: 1600528 * 512, 35 | }, *stats[1]) 36 | } 37 | 38 | func TestParseSwapsCommandOutput_Invalid(t *testing.T) { 39 | _, err := parseSwapsCommandOutput(invalidFile) 40 | assert.Error(t, err) 41 | } 42 | 43 | func TestParseSwapsCommandOutput_Empty(t *testing.T) { 44 | _, err := parseSwapsCommandOutput("") 45 | assert.Error(t, err) 46 | } 47 | -------------------------------------------------------------------------------- /mem/testdata/linux/virtualmemory/anonhugepages/proc/meminfo: -------------------------------------------------------------------------------- 1 | MemTotal: 260799420 kB 2 | MemFree: 119443248 kB 3 | MemAvailable: 127880216 kB 4 | AnonHugePages: 50409472 kB -------------------------------------------------------------------------------- /mem/testdata/linux/virtualmemory/intelcorei5/proc/meminfo: -------------------------------------------------------------------------------- 1 | MemTotal: 16115528 kB 2 | MemFree: 8577628 kB 3 | MemAvailable: 11225936 kB 4 | Buffers: 207516 kB 5 | Cached: 3791568 kB 6 | SwapCached: 0 kB 7 | Active: 4245500 kB 8 | Inactive: 2869956 kB 9 | Active(anon): 3123508 kB 10 | Inactive(anon): 1186612 kB 11 | Active(file): 1121992 kB 12 | Inactive(file): 1683344 kB 13 | Unevictable: 32 kB 14 | Mlocked: 32 kB 15 | SwapTotal: 8065020 kB 16 | SwapFree: 8065020 kB 17 | Dirty: 172 kB 18 | Writeback: 0 kB 19 | AnonPages: 3116472 kB 20 | Mapped: 1145144 kB 21 | Shmem: 1193752 kB 22 | Slab: 247824 kB 23 | SReclaimable: 182100 kB 24 | SUnreclaim: 65724 kB 25 | KernelStack: 14224 kB 26 | PageTables: 63712 kB 27 | NFS_Unstable: 0 kB 28 | Bounce: 0 kB 29 | WritebackTmp: 0 kB 30 | CommitLimit: 16122784 kB 31 | Committed_AS: 12071112 kB 32 | VmallocTotal: 34359738367 kB 33 | VmallocUsed: 0 kB 34 | VmallocChunk: 0 kB 35 | HardwareCorrupted: 0 kB 36 | AnonHugePages: 0 kB 37 | ShmemHugePages: 0 kB 38 | ShmemPmdMapped: 0 kB 39 | HugePages_Total: 0 40 | HugePages_Free: 0 41 | HugePages_Rsvd: 0 42 | HugePages_Surp: 0 43 | Hugepagesize: 2048 kB 44 | DirectMap4k: 143564 kB 45 | DirectMap2M: 6871040 kB 46 | DirectMap1G: 10485760 kB 47 | -------------------------------------------------------------------------------- /mem/testdata/linux/virtualmemory/issue1002/proc/meminfo: -------------------------------------------------------------------------------- 1 | total: used: free: shared: buffers: cached: 2 | Mem: 260579328 136073216 124506112 0 4915200 94064640 3 | Swap: 0 0 0 4 | MemTotal: 254472 kB 5 | MemFree: 121588 kB 6 | MemShared: 0 kB 7 | Buffers: 4800 kB 8 | Cached: 91860 kB 9 | SwapCached: 0 kB 10 | Active: 106236 kB 11 | Inactive: 8380 kB 12 | MemAvailable: 210156 kB 13 | Active(anon): 17956 kB 14 | Inactive(anon): 0 kB 15 | Active(file): 88280 kB 16 | Inactive(file): 8380 kB 17 | Unevictable: 0 kB 18 | Mlocked: 0 kB 19 | HighTotal: 131072 kB 20 | HighFree: 66196 kB 21 | LowTotal: 123400 kB 22 | LowFree: 55392 kB 23 | SwapTotal: 0 kB 24 | SwapFree: 0 kB 25 | Dirty: 0 kB 26 | Writeback: 0 kB 27 | AnonPages: 17992 kB 28 | Mapped: 37884 kB 29 | Shmem: 0 kB 30 | Slab: 9076 kB 31 | SReclaimable: 2700 kB 32 | SUnreclaim: 6376 kB 33 | KernelStack: 624 kB 34 | PageTables: 396 kB 35 | NFS_Unstable: 0 kB 36 | Bounce: 0 kB 37 | WritebackTmp: 0 kB 38 | CommitLimit: 127236 kB 39 | Committed_AS: 24968 kB 40 | VmallocTotal: 1949696 kB 41 | VmallocUsed: 0 kB 42 | VmallocChunk: 0 kB 43 | -------------------------------------------------------------------------------- /mem/testdata/plan9/virtualmemory/dev/swap: -------------------------------------------------------------------------------- 1 | 1071185920 memory 2 | 4096 pagesize 3 | 61372 kernel 4 | 2792/200148 user 5 | 0/160000 swap 6 | 9046176/219352384 kernel malloc 7 | 0/16777216 kernel draw 8 | -------------------------------------------------------------------------------- /mem/types_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | /* 5 | Input to cgo -godefs. 6 | */ 7 | 8 | package mem 9 | 10 | /* 11 | #include 12 | #include 13 | #include 14 | */ 15 | import "C" 16 | 17 | // Machine characteristics; for internal use. 18 | 19 | const ( 20 | CTLVfs = 10 21 | VfsGeneric = 0 22 | VfsBcacheStat = 3 23 | ) 24 | 25 | const ( 26 | sizeOfBcachestats = C.sizeof_struct_bcachestats 27 | ) 28 | 29 | type Bcachestats C.struct_bcachestats 30 | -------------------------------------------------------------------------------- /mktypes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PKGS="cpu disk docker host load mem net process sensors winservices" 4 | 5 | GOOS=$(go env GOOS) 6 | GOARCH=$(go env GOARCH) 7 | 8 | for PKG in $PKGS 9 | do 10 | if [ -e "${PKG}/types_${GOOS}.go" ]; then 11 | (echo "// +build $GOOS" 12 | echo "// +build $GOARCH" 13 | go tool cgo -godefs "${PKG}/types_${GOOS}.go") | gofmt > "${PKG}/${PKG}_${GOOS}_${GOARCH}.go" 14 | fi 15 | done 16 | -------------------------------------------------------------------------------- /net/net_aix_cgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && cgo 3 | 4 | package net 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/power-devops/perfstat" 10 | ) 11 | 12 | func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { 13 | ifs, err := perfstat.NetIfaceStat() 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | iocounters := make([]IOCountersStat, 0, len(ifs)) 19 | for _, netif := range ifs { 20 | n := IOCountersStat{ 21 | Name: netif.Name, 22 | BytesSent: uint64(netif.OBytes), 23 | BytesRecv: uint64(netif.IBytes), 24 | PacketsSent: uint64(netif.OPackets), 25 | PacketsRecv: uint64(netif.IPackets), 26 | Errin: uint64(netif.OErrors), 27 | Errout: uint64(netif.IErrors), 28 | Dropout: uint64(netif.XmitDrops), 29 | } 30 | iocounters = append(iocounters, n) 31 | } 32 | if !pernic { 33 | return getIOCountersAll(iocounters), nil 34 | } 35 | return iocounters, nil 36 | } 37 | -------------------------------------------------------------------------------- /net/net_aix_nocgo.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix && !cgo 3 | 4 | package net 5 | 6 | import ( 7 | "context" 8 | "errors" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | func parseNetstatI(output string) ([]IOCountersStat, error) { 16 | lines := strings.Split(string(output), "\n") 17 | ret := make([]IOCountersStat, 0, len(lines)-1) 18 | exists := make([]string, 0, len(ret)) 19 | 20 | // Check first line is header 21 | if len(lines) > 0 && strings.Fields(lines[0])[0] != "Name" { 22 | return nil, errors.New("not a 'netstat -i' output") 23 | } 24 | 25 | for _, line := range lines[1:] { 26 | values := strings.Fields(line) 27 | if len(values) < 1 || values[0] == "Name" { 28 | continue 29 | } 30 | if common.StringsHas(exists, values[0]) { 31 | // skip if already get 32 | continue 33 | } 34 | exists = append(exists, values[0]) 35 | 36 | if len(values) < 9 { 37 | continue 38 | } 39 | 40 | base := 1 41 | // sometimes Address is omitted 42 | if len(values) < 10 { 43 | base = 0 44 | } 45 | 46 | parsed := make([]uint64, 0, 5) 47 | vv := []string{ 48 | values[base+3], // Ipkts == PacketsRecv 49 | values[base+4], // Ierrs == Errin 50 | values[base+5], // Opkts == PacketsSent 51 | values[base+6], // Oerrs == Errout 52 | values[base+8], // Drops == Dropout 53 | } 54 | 55 | for _, target := range vv { 56 | if target == "-" { 57 | parsed = append(parsed, 0) 58 | continue 59 | } 60 | 61 | t, err := strconv.ParseUint(target, 10, 64) 62 | if err != nil { 63 | return nil, err 64 | } 65 | parsed = append(parsed, t) 66 | } 67 | 68 | n := IOCountersStat{ 69 | Name: values[0], 70 | PacketsRecv: parsed[0], 71 | Errin: parsed[1], 72 | PacketsSent: parsed[2], 73 | Errout: parsed[3], 74 | Dropout: parsed[4], 75 | } 76 | ret = append(ret, n) 77 | } 78 | return ret, nil 79 | } 80 | 81 | func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { 82 | out, err := invoke.CommandWithContext(ctx, "netstat", "-idn") 83 | if err != nil { 84 | return nil, err 85 | } 86 | 87 | iocounters, err := parseNetstatI(string(out)) 88 | if err != nil { 89 | return nil, err 90 | } 91 | if !pernic { 92 | return getIOCountersAll(iocounters), nil 93 | } 94 | return iocounters, nil 95 | } 96 | -------------------------------------------------------------------------------- /net/net_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !aix && !darwin && !linux && !freebsd && !openbsd && !windows && !solaris 3 | 4 | package net 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func IOCountersWithContext(_ context.Context, _ bool) ([]IOCountersStat, error) { 13 | return []IOCountersStat{}, common.ErrNotImplementedError 14 | } 15 | 16 | func IOCountersByFileWithContext(ctx context.Context, pernic bool, _ string) ([]IOCountersStat, error) { 17 | return IOCountersWithContext(ctx, pernic) 18 | } 19 | 20 | func FilterCountersWithContext(_ context.Context) ([]FilterStat, error) { 21 | return nil, common.ErrNotImplementedError 22 | } 23 | 24 | func ConntrackStatsWithContext(_ context.Context, _ bool) ([]ConntrackStat, error) { 25 | return nil, common.ErrNotImplementedError 26 | } 27 | 28 | func ProtoCountersWithContext(_ context.Context, _ []string) ([]ProtoCountersStat, error) { 29 | return nil, common.ErrNotImplementedError 30 | } 31 | 32 | // Deprecated: use process.PidsWithContext instead 33 | func PidsWithContext(_ context.Context) ([]int32, error) { 34 | return nil, common.ErrNotImplementedError 35 | } 36 | 37 | func ConnectionsWithContext(_ context.Context, _ string) ([]ConnectionStat, error) { 38 | return []ConnectionStat{}, common.ErrNotImplementedError 39 | } 40 | 41 | func ConnectionsMaxWithContext(ctx context.Context, kind string, maxConn int) ([]ConnectionStat, error) { 42 | return ConnectionsPidMaxWithContext(ctx, kind, 0, maxConn) 43 | } 44 | 45 | func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { 46 | return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0) 47 | } 48 | 49 | func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, maxConn int) ([]ConnectionStat, error) { 50 | return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, maxConn) 51 | } 52 | 53 | func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { 54 | return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0) 55 | } 56 | 57 | func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { 58 | return ConnectionsPidMaxWithContext(ctx, kind, pid, 0) 59 | } 60 | 61 | func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, maxConn int) ([]ConnectionStat, error) { 62 | return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, maxConn, false) 63 | } 64 | 65 | func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, maxConn int) ([]ConnectionStat, error) { 66 | return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, maxConn, true) 67 | } 68 | 69 | func connectionsPidMaxWithoutUidsWithContext(_ context.Context, _ string, _ int32, _ int, _ bool) ([]ConnectionStat, error) { 70 | return []ConnectionStat{}, common.ErrNotImplementedError 71 | } 72 | -------------------------------------------------------------------------------- /net/net_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd 3 | 4 | package net 5 | 6 | import ( 7 | "context" 8 | "strconv" 9 | "strings" 10 | 11 | "github.com/shirou/gopsutil/v4/internal/common" 12 | ) 13 | 14 | // Deprecated: use process.PidsWithContext instead 15 | func PidsWithContext(_ context.Context) ([]int32, error) { 16 | return nil, common.ErrNotImplementedError 17 | } 18 | 19 | func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { 20 | out, err := invoke.CommandWithContext(ctx, "netstat", "-ibdnW") 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | lines := strings.Split(string(out), "\n") 26 | ret := make([]IOCountersStat, 0, len(lines)-1) 27 | exists := make([]string, 0, len(ret)) 28 | 29 | for _, line := range lines { 30 | values := strings.Fields(line) 31 | if len(values) < 1 || values[0] == "Name" { 32 | continue 33 | } 34 | if common.StringsHas(exists, values[0]) { 35 | // skip if already get 36 | continue 37 | } 38 | exists = append(exists, values[0]) 39 | 40 | if len(values) < 12 { 41 | continue 42 | } 43 | base := 1 44 | // sometimes Address is omitted 45 | if len(values) < 13 { 46 | base = 0 47 | } 48 | 49 | parsed := make([]uint64, 0, 8) 50 | vv := []string{ 51 | values[base+3], // PacketsRecv 52 | values[base+4], // Errin 53 | values[base+5], // Dropin 54 | values[base+6], // BytesRecvn 55 | values[base+7], // PacketSent 56 | values[base+8], // Errout 57 | values[base+9], // BytesSent 58 | values[base+11], // Dropout 59 | } 60 | for _, target := range vv { 61 | if target == "-" { 62 | parsed = append(parsed, 0) 63 | continue 64 | } 65 | 66 | t, err := strconv.ParseUint(target, 10, 64) 67 | if err != nil { 68 | return nil, err 69 | } 70 | parsed = append(parsed, t) 71 | } 72 | 73 | n := IOCountersStat{ 74 | Name: values[0], 75 | PacketsRecv: parsed[0], 76 | Errin: parsed[1], 77 | Dropin: parsed[2], 78 | BytesRecv: parsed[3], 79 | PacketsSent: parsed[4], 80 | Errout: parsed[5], 81 | BytesSent: parsed[6], 82 | Dropout: parsed[7], 83 | } 84 | ret = append(ret, n) 85 | } 86 | 87 | if !pernic { 88 | return getIOCountersAll(ret), nil 89 | } 90 | 91 | return ret, nil 92 | } 93 | 94 | func IOCountersByFileWithContext(ctx context.Context, pernic bool, _ string) ([]IOCountersStat, error) { 95 | return IOCountersWithContext(ctx, pernic) 96 | } 97 | 98 | func FilterCountersWithContext(_ context.Context) ([]FilterStat, error) { 99 | return nil, common.ErrNotImplementedError 100 | } 101 | 102 | func ConntrackStatsWithContext(_ context.Context, _ bool) ([]ConntrackStat, error) { 103 | return nil, common.ErrNotImplementedError 104 | } 105 | 106 | func ProtoCountersWithContext(_ context.Context, _ []string) ([]ProtoCountersStat, error) { 107 | return nil, common.ErrNotImplementedError 108 | } 109 | -------------------------------------------------------------------------------- /net/types_darwin.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // Hand writing: _Ctype_struct___3, 4 5 | 6 | /* 7 | Input to cgo -godefs. 8 | 9 | */ 10 | 11 | package net 12 | 13 | /* 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | enum { 20 | sizeofPtr = sizeof(void*), 21 | }; 22 | 23 | */ 24 | import "C" 25 | 26 | // Machine characteristics; for internal use. 27 | 28 | const ( 29 | sizeofPtr = C.sizeofPtr 30 | sizeofShort = C.sizeof_short 31 | sizeofInt = C.sizeof_int 32 | sizeofLong = C.sizeof_long 33 | sizeofLongLong = C.sizeof_longlong 34 | sizeofLongDouble = C.sizeof_longlong 35 | ) 36 | 37 | // Basic types 38 | 39 | type ( 40 | _C_short C.short 41 | _C_int C.int 42 | _C_long C.long 43 | _C_long_long C.longlong 44 | _C_long_double C.longlong 45 | ) 46 | 47 | type ( 48 | Xinpgen C.struct_xinpgen 49 | Inpcb C.struct_inpcb 50 | in_addr C.struct_in_addr 51 | Inpcb_list_entry C.struct__inpcb_list_entry 52 | Xsocket C.struct_xsocket 53 | Xsockbuf C.struct_xsockbuf 54 | Xinpcb C.struct_xinpcb 55 | ) 56 | 57 | // type u_quad_t C.struct_u_quad_t 58 | -------------------------------------------------------------------------------- /process/process_bsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build darwin || freebsd || openbsd 3 | 4 | package process 5 | 6 | import ( 7 | "bytes" 8 | "context" 9 | "encoding/binary" 10 | 11 | "github.com/shirou/gopsutil/v4/cpu" 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | type MemoryInfoExStat struct{} 16 | 17 | type MemoryMapsStat struct{} 18 | 19 | func (p *Process) TgidWithContext(_ context.Context) (int32, error) { 20 | return 0, common.ErrNotImplementedError 21 | } 22 | 23 | func (p *Process) IOniceWithContext(_ context.Context) (int32, error) { 24 | return 0, common.ErrNotImplementedError 25 | } 26 | 27 | func (p *Process) RlimitWithContext(_ context.Context) ([]RlimitStat, error) { 28 | return nil, common.ErrNotImplementedError 29 | } 30 | 31 | func (p *Process) RlimitUsageWithContext(_ context.Context, _ bool) ([]RlimitStat, error) { 32 | return nil, common.ErrNotImplementedError 33 | } 34 | 35 | func (p *Process) NumCtxSwitchesWithContext(_ context.Context) (*NumCtxSwitchesStat, error) { 36 | return nil, common.ErrNotImplementedError 37 | } 38 | 39 | func (p *Process) NumFDsWithContext(_ context.Context) (int32, error) { 40 | return 0, common.ErrNotImplementedError 41 | } 42 | 43 | func (p *Process) CPUAffinityWithContext(_ context.Context) ([]int32, error) { 44 | return nil, common.ErrNotImplementedError 45 | } 46 | 47 | func (p *Process) MemoryInfoExWithContext(_ context.Context) (*MemoryInfoExStat, error) { 48 | return nil, common.ErrNotImplementedError 49 | } 50 | 51 | func (p *Process) PageFaultsWithContext(_ context.Context) (*PageFaultsStat, error) { 52 | return nil, common.ErrNotImplementedError 53 | } 54 | 55 | func (p *Process) OpenFilesWithContext(_ context.Context) ([]OpenFilesStat, error) { 56 | return nil, common.ErrNotImplementedError 57 | } 58 | 59 | func (p *Process) MemoryMapsWithContext(_ context.Context, _ bool) (*[]MemoryMapsStat, error) { 60 | return nil, common.ErrNotImplementedError 61 | } 62 | 63 | func (p *Process) ThreadsWithContext(_ context.Context) (map[int32]*cpu.TimesStat, error) { 64 | return nil, common.ErrNotImplementedError 65 | } 66 | 67 | func (p *Process) EnvironWithContext(_ context.Context) ([]string, error) { 68 | return nil, common.ErrNotImplementedError 69 | } 70 | 71 | func parseKinfoProc(buf []byte) (KinfoProc, error) { 72 | var k KinfoProc 73 | br := bytes.NewReader(buf) 74 | err := common.Read(br, binary.LittleEndian, &k) 75 | return k, err 76 | } 77 | -------------------------------------------------------------------------------- /process/process_posix_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux || freebsd 3 | 4 | package process 5 | 6 | import ( 7 | "os" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "golang.org/x/sys/unix" 12 | ) 13 | 14 | func Test_SendSignal(t *testing.T) { 15 | checkPid := os.Getpid() 16 | 17 | p, _ := NewProcess(int32(checkPid)) 18 | assert.NoErrorf(t, p.SendSignal(unix.SIGCONT), "send signal") 19 | } 20 | -------------------------------------------------------------------------------- /process/process_race_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build race 3 | 4 | package process 5 | 6 | import ( 7 | "sync" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | func TestPpid_Race(t *testing.T) { 16 | wg := sync.WaitGroup{} 17 | testCount := 10 18 | p := testGetProcess() 19 | wg.Add(testCount) 20 | for i := 0; i < testCount; i++ { 21 | go func(j int) { 22 | ppid, err := p.Ppid() 23 | wg.Done() 24 | common.SkipIfNotImplementedErr(t, err) 25 | require.NoError(t, err, "Ppid() failed, %v", err) 26 | 27 | if j == 9 { 28 | t.Logf("Ppid(): %d", ppid) 29 | } 30 | }(i) 31 | } 32 | wg.Wait() 33 | } 34 | -------------------------------------------------------------------------------- /process/process_windows_64bit.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build (windows && amd64) || (windows && arm64) 3 | 4 | package process 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | 10 | "golang.org/x/sys/windows" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | type PROCESS_MEMORY_COUNTERS struct { //nolint:revive //FIXME 16 | CB uint32 17 | PageFaultCount uint32 18 | PeakWorkingSetSize uint64 19 | WorkingSetSize uint64 20 | QuotaPeakPagedPoolUsage uint64 21 | QuotaPagedPoolUsage uint64 22 | QuotaPeakNonPagedPoolUsage uint64 23 | QuotaNonPagedPoolUsage uint64 24 | PagefileUsage uint64 25 | PeakPagefileUsage uint64 26 | } 27 | 28 | func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) { 29 | if is32BitProcess { 30 | // we are on a 64-bit process reading an external 32-bit process 31 | var wow64 uint 32 | 33 | ret, _, _ := common.ProcNtQueryInformationProcess.Call( 34 | uintptr(procHandle), 35 | uintptr(common.ProcessWow64Information), 36 | uintptr(unsafe.Pointer(&wow64)), 37 | uintptr(unsafe.Sizeof(wow64)), 38 | uintptr(0), 39 | ) 40 | if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { 41 | return uint64(wow64), nil 42 | } 43 | return 0, windows.NTStatus(ret) 44 | } 45 | // we are on a 64-bit process reading an external 64-bit process 46 | var info processBasicInformation64 47 | 48 | ret, _, _ := common.ProcNtQueryInformationProcess.Call( 49 | uintptr(procHandle), 50 | uintptr(common.ProcessBasicInformation), 51 | uintptr(unsafe.Pointer(&info)), 52 | uintptr(unsafe.Sizeof(info)), 53 | uintptr(0), 54 | ) 55 | if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { 56 | return info.PebBaseAddress, nil 57 | } 58 | return 0, windows.NTStatus(ret) 59 | } 60 | 61 | func readProcessMemory(procHandle syscall.Handle, _ bool, address uint64, size uint) []byte { 62 | var read uint 63 | 64 | buffer := make([]byte, size) 65 | 66 | ret, _, _ := common.ProcNtReadVirtualMemory.Call( 67 | uintptr(procHandle), 68 | uintptr(address), 69 | uintptr(unsafe.Pointer(&buffer[0])), 70 | uintptr(size), 71 | uintptr(unsafe.Pointer(&read)), 72 | ) 73 | if int(ret) >= 0 && read > 0 { 74 | return buffer[:read] 75 | } 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /process/testdata/linux/1/comm: -------------------------------------------------------------------------------- 1 | ksoftirqd/0 2 | -------------------------------------------------------------------------------- /process/testdata/linux/1/smaps: -------------------------------------------------------------------------------- 1 | ffffb5ecc000-ffffb5ece000 r--p 00000000 00:00 0 [vvar] 2 | Rss: 0 kB 3 | KernelPageSize: 4 kB 4 | Size: 1 kB 5 | Shared_Clean: 3 kB 6 | Shared_Dirty: 4 kB 7 | Private_Clean: 5 kB 8 | Private_Dirty: 6 kB 9 | Referenced: 7 kB 10 | Anonymous: 8 kB 11 | Swap: 9 kB 12 | ffffb5eca000-ffffb5ecc000 rw-p 00000000 00:00 0 13 | Rss: 0 kB 14 | Size: 1 kB 15 | Pss: 2 kB 16 | Shared_Clean: 3 kB 17 | Shared_Dirty: 4 kB 18 | Private_Dirty: 6 kB 19 | LazyFree: 0 kB 20 | Referenced: 7 kB 21 | Anonymous: 8 kB 22 | Swap: 9 kB 23 | ffffb5ece000-ffffb5ecf000 r-xp 00000000 00:00 0 [vdso] 24 | Rss: 0 kB 25 | Size: 1 kB 26 | Pss: 2 kB 27 | Shared_Clean: 3 kB 28 | Shared_Dirty: 4 kB 29 | Private_Clean: 5 kB 30 | Private_Hugetlb: 0 kB 31 | Referenced: 7 kB 32 | Anonymous: 8 kB 33 | Swap: 9 kB 34 | ffffb5ecf000-ffffb5ed1000 r--p 0002a000 00:3d 2238525 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 35 | Rss: 0 kB 36 | Size: 1 kB 37 | Pss: 2 kB 38 | Shared_Clean: 3 kB 39 | Shared_Dirty: 4 kB 40 | Private_Clean: 5 kB 41 | Private_Dirty: 6 kB 42 | Referenced: 7 kB 43 | THPeligible: 0 44 | Swap: 9 kB 45 | -------------------------------------------------------------------------------- /process/testdata/linux/1/status: -------------------------------------------------------------------------------- 1 | Name: ksoftirqd/0 2 | Umask: 0000 3 | State: S (sleeping) 4 | Tgid: 10 5 | Ngid: 0 6 | Pid: 10 7 | PPid: 2 8 | TracerPid: 0 9 | Uid: 0 0 0 0 10 | Gid: 0 0 0 0 11 | FDSize: 64 12 | Groups: 13 | NStgid: 10 14 | NSpid: 10 15 | NSpgid: 0 16 | NSsid: 0 17 | Threads: 1 18 | SigQ: 0/27700 19 | SigPnd: 0000000000000000 20 | ShdPnd: 0000000000000000 21 | SigBlk: 0000000000000000 22 | SigIgn: ffffffffffffffff 23 | SigCgt: 0000000000000000 24 | CapInh: 0000000000000000 25 | CapPrm: 0000003fffffffff 26 | CapEff: 0000003fffffffff 27 | CapBnd: 0000003fffffffff 28 | CapAmb: 0000000000000000 29 | NoNewPrivs: 0 30 | Seccomp: 0 31 | Speculation_Store_Bypass: vulnerable 32 | Cpus_allowed: 1 33 | Cpus_allowed_list: 0 34 | Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 35 | Mems_allowed_list: 0 36 | voluntary_ctxt_switches: 76887 37 | nonvoluntary_ctxt_switches: 1771 38 | -------------------------------------------------------------------------------- /process/testdata/linux/1060/comm: -------------------------------------------------------------------------------- 1 | server 2 | -------------------------------------------------------------------------------- /process/testdata/linux/1060/status: -------------------------------------------------------------------------------- 1 | Name: server 2 | Umask: 0022 3 | State: S (sleeping) 4 | Tgid: 2549 5 | Ngid: 0 6 | Pid: 2549 7 | PPid: 1 8 | TracerPid: 0 9 | Uid: 107 107 107 107 10 | Gid: 113 113 113 113 11 | FDSize: 64 12 | Groups: 113 13 | VmPeak: 664744 kB 14 | VmSize: 664744 kB 15 | VmLck: 0 kB 16 | VmPin: 0 kB 17 | VmHWM: 2892 kB 18 | VmRSS: 2892 kB 19 | RssAnon: 524 kB 20 | RssFile: 2368 kB 21 | RssShmem: 0 kB 22 | VmData: 5932 kB 23 | VmStk: 132 kB 24 | VmExe: 1304 kB 25 | VmLib: 1180 kB 26 | VmPTE: 44 kB 27 | VmSwap: 0 kB 28 | CoreDumping: 0 29 | THP_enabled: 1 30 | Threads: 5 31 | SigQ: 0/1823 32 | SigPnd: 00000000000000000000000000000000 33 | ShdPnd: 00000000000000000000000000000000 34 | SigBlk: 00000000000000000000000000000000 35 | SigIgn: 00000000000000000000000000000000 36 | SigCgt: fffffffffffffffffffffffe783ffeff 37 | CapInh: 0000000000000000 38 | CapPrm: 0000000000000000 39 | CapEff: 0000000000000000 40 | CapBnd: 0000003fffffffff 41 | CapAmb: 0000000000000000 42 | NoNewPrivs: 0 43 | Speculation_Store_Bypass: unknown 44 | Cpus_allowed: 3 45 | Cpus_allowed_list: 0-1 46 | voluntary_ctxt_switches: 3 47 | nonvoluntary_ctxt_switches: 146 -------------------------------------------------------------------------------- /process/testdata/linux/68927/comm: -------------------------------------------------------------------------------- 1 | test(cmd).sh 2 | -------------------------------------------------------------------------------- /process/testdata/linux/68927/stat: -------------------------------------------------------------------------------- 1 | 68927 (test(cmd).sh) S 68044 68927 68044 34818 68927 4194304 165 0 0 0 0 0 0 0 20 0 1 0 114413973 9961472 868 18446744073709551615 94388826710016 94388827626021 140725039102800 0 0 0 2 4 65536 1 0 0 17 1 0 0 0 0 0 94388827875984 94388827924080 94388835627008 140725039105503 140725039105528 140725039105528 140725039108073 0 2 | -------------------------------------------------------------------------------- /process/testdata/lx_brandz/1/stat: -------------------------------------------------------------------------------- 1 | 1 (systemd) S 0 0 0 0 -1 0 0 0 0 0 8 15 48 52 1 0 0 0 25 31883264 1413 18446744073709551615 0 0 140737487261696 0 0 0 0 0 0 18446741901776689794 0 0 17 0 2 | -------------------------------------------------------------------------------- /process/types_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // We still need editing by hands. 5 | // go tool cgo -godefs types_freebsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_freebsd_amd64.go 6 | 7 | /* 8 | Input to cgo -godefs. 9 | */ 10 | 11 | // +godefs map struct_pargs int64 /* pargs */ 12 | // +godefs map struct_proc int64 /* proc */ 13 | // +godefs map struct_user int64 /* user */ 14 | // +godefs map struct_vnode int64 /* vnode */ 15 | // +godefs map struct_filedesc int64 /* filedesc */ 16 | // +godefs map struct_vmspace int64 /* vmspace */ 17 | // +godefs map struct_pcb int64 /* pcb */ 18 | // +godefs map struct_thread int64 /* thread */ 19 | // +godefs map struct_pwddesc int64 /* pwddesc, not accurate */ 20 | // +godefs map struct___sigset [16]byte /* sigset */ 21 | 22 | package process 23 | 24 | /* 25 | #include 26 | #include 27 | 28 | enum { 29 | sizeofPtr = sizeof(void*), 30 | }; 31 | 32 | 33 | */ 34 | import "C" 35 | 36 | // Machine characteristics; for internal use. 37 | 38 | const ( 39 | CTLKern = 1 // "high kernel": proc, limits 40 | KernProc = 14 // struct: process entries 41 | KernProcPID = 1 // by process id 42 | KernProcProc = 8 // only return procs 43 | KernProcPathname = 12 // path to executable 44 | KernProcArgs = 7 // get/set arguments/proctitle 45 | KernProcCwd = 42 /* process current working directory */ 46 | ) 47 | 48 | const ( 49 | sizeofPtr = C.sizeofPtr 50 | sizeofShort = C.sizeof_short 51 | sizeofInt = C.sizeof_int 52 | sizeofLong = C.sizeof_long 53 | sizeofLongLong = C.sizeof_longlong 54 | ) 55 | 56 | const ( 57 | sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry 58 | sizeOfKinfoProc = C.sizeof_struct_kinfo_proc 59 | sizeOfKinfoFile = C.sizeof_struct_kinfo_file 60 | ) 61 | 62 | // from sys/proc.h 63 | const ( 64 | SIDL = 1 /* Process being created by fork. */ 65 | SRUN = 2 /* Currently runnable. */ 66 | SSLEEP = 3 /* Sleeping on an address. */ 67 | SSTOP = 4 /* Process debugging or suspension. */ 68 | SZOMB = 5 /* Awaiting collection by parent. */ 69 | SWAIT = 6 /* Waiting for interrupt. */ 70 | SLOCK = 7 /* Blocked on a lock. */ 71 | ) 72 | 73 | // Basic types 74 | 75 | type ( 76 | _C_short C.short 77 | _C_int C.int 78 | _C_long C.long 79 | _C_long_long C.longlong 80 | ) 81 | 82 | // Time 83 | 84 | type Timespec C.struct_timespec 85 | 86 | type Timeval C.struct_timeval 87 | 88 | // Processes 89 | 90 | type Rusage C.struct_rusage 91 | 92 | type Rlimit C.struct_rlimit 93 | 94 | type KinfoProc C.struct_kinfo_proc 95 | 96 | type Priority C.struct_priority 97 | 98 | type KinfoVmentry C.struct_kinfo_vmentry 99 | 100 | type kinfoFile C.struct_kinfo_file 101 | 102 | type capRights C.struct_cap_rights 103 | -------------------------------------------------------------------------------- /process/types_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build ignore 3 | 4 | // We still need editing by hands. 5 | // go tool cgo -godefs types_openbsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_openbsd_amd64.go 6 | 7 | /* 8 | Input to cgo -godefs. 9 | */ 10 | 11 | // +godefs map struct_pargs int64 /* pargs */ 12 | // +godefs map struct_proc int64 /* proc */ 13 | // +godefs map struct_user int64 /* user */ 14 | // +godefs map struct_vnode int64 /* vnode */ 15 | // +godefs map struct_vnode int64 /* vnode */ 16 | // +godefs map struct_filedesc int64 /* filedesc */ 17 | // +godefs map struct_vmspace int64 /* vmspace */ 18 | // +godefs map struct_pcb int64 /* pcb */ 19 | // +godefs map struct_thread int64 /* thread */ 20 | // +godefs map struct___sigset [16]byte /* sigset */ 21 | 22 | package process 23 | 24 | /* 25 | #include 26 | #include 27 | #include 28 | 29 | enum { 30 | sizeofPtr = sizeof(void*), 31 | }; 32 | 33 | 34 | */ 35 | import "C" 36 | 37 | // Machine characteristics; for internal use. 38 | 39 | const ( 40 | CTLKern = 1 // "high kernel": proc, limits 41 | KernProc = 66 // struct: process entries 42 | KernProcAll = 0 43 | KernProcPID = 1 // by process id 44 | KernProcProc = 8 // only return procs 45 | KernProcPathname = 12 // path to executable 46 | KernProcArgs = 55 // get/set arguments/proctitle 47 | KernProcCwd = 78 // get current working directory 48 | KernProcArgv = 1 49 | KernProcEnv = 3 50 | ) 51 | 52 | const ( 53 | ArgMax = 256 * 1024 // sys/syslimits.h:#define ARG_MAX 54 | ) 55 | 56 | const ( 57 | sizeofPtr = C.sizeofPtr 58 | sizeofShort = C.sizeof_short 59 | sizeofInt = C.sizeof_int 60 | sizeofLong = C.sizeof_long 61 | sizeofLongLong = C.sizeof_longlong 62 | ) 63 | 64 | const ( 65 | sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry 66 | sizeOfKinfoProc = C.sizeof_struct_kinfo_proc 67 | ) 68 | 69 | // from sys/proc.h 70 | const ( 71 | SIDL = 1 /* Process being created by fork. */ 72 | SRUN = 2 /* Currently runnable. */ 73 | SSLEEP = 3 /* Sleeping on an address. */ 74 | SSTOP = 4 /* Process debugging or suspension. */ 75 | SZOMB = 5 /* Awaiting collection by parent. */ 76 | SDEAD = 6 /* Thread is almost gone */ 77 | SONPROC = 7 /* Thread is currently on a CPU. */ 78 | ) 79 | 80 | // Basic types 81 | 82 | type ( 83 | _C_short C.short 84 | _C_int C.int 85 | _C_long C.long 86 | _C_long_long C.longlong 87 | ) 88 | 89 | // Time 90 | 91 | type Timespec C.struct_timespec 92 | 93 | type Timeval C.struct_timeval 94 | 95 | // Processes 96 | 97 | type Rusage C.struct_rusage 98 | 99 | type Rlimit C.struct_rlimit 100 | 101 | type KinfoProc C.struct_kinfo_proc 102 | 103 | type Priority C.struct_priority 104 | 105 | type KinfoVmentry C.struct_kinfo_vmentry 106 | -------------------------------------------------------------------------------- /sensors/ex_linux.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build linux 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "os" 10 | "path/filepath" 11 | "strings" 12 | ) 13 | 14 | // ExTemperature represents Linux dependent temperature sensor data 15 | type ExTemperature struct { 16 | SensorKey string `json:"key"` 17 | Min float64 `json:"min"` // Temperature min value. 18 | Lowest float64 `json:"lowest"` // Historical minimum temperature 19 | Highest float64 `json:"highest"` // Historical maximum temperature 20 | } 21 | 22 | type ExLinux struct{} 23 | 24 | func NewExLinux() *ExLinux { 25 | return &ExLinux{} 26 | } 27 | 28 | func (ex *ExLinux) TemperatureWithContext(ctx context.Context) ([]ExTemperature, error) { 29 | var warns Warnings 30 | 31 | files, err := getTemperatureFiles(ctx) 32 | if err != nil { 33 | return nil, fmt.Errorf("failed to get temperature files, %w", err) 34 | } 35 | 36 | temperatures := make([]ExTemperature, 0, len(files)) 37 | for _, file := range files { 38 | var raw []byte 39 | 40 | // Get the base directory location 41 | directory := filepath.Dir(file) 42 | 43 | // Get the base filename prefix like temp1 44 | basename := strings.Split(filepath.Base(file), "_")[0] 45 | 46 | // Get the base path like /temp1 47 | basepath := filepath.Join(directory, basename) 48 | 49 | // Get the label of the temperature you are reading 50 | label := "" 51 | 52 | if raw, _ = os.ReadFile(basepath + "_label"); len(raw) != 0 { 53 | // Format the label from "Core 0" to "core_0" 54 | label = strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(raw))), " "), "_") 55 | } 56 | 57 | // Get the name of the temperature you are reading 58 | if raw, err = os.ReadFile(filepath.Join(directory, "name")); err != nil { 59 | warns.Add(err) 60 | continue 61 | } 62 | 63 | name := strings.TrimSpace(string(raw)) 64 | 65 | if label != "" { 66 | name = name + "_" + label 67 | } 68 | 69 | // Add discovered temperature sensor to the list 70 | temperatures = append(temperatures, ExTemperature{ 71 | SensorKey: name, 72 | Min: optionalValueReadFromFile(basepath+"_min") / hostTemperatureScale, 73 | Lowest: optionalValueReadFromFile(basepath+"_lowest") / hostTemperatureScale, 74 | Highest: optionalValueReadFromFile(basepath+"_highest") / hostTemperatureScale, 75 | }) 76 | } 77 | 78 | return temperatures, warns.Reference() 79 | } 80 | -------------------------------------------------------------------------------- /sensors/sensors.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | 3 | package sensors 4 | 5 | import ( 6 | "context" 7 | "encoding/json" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | type Warnings = common.Warnings 13 | 14 | var invoke common.Invoker = common.Invoke{} 15 | 16 | type TemperatureStat struct { 17 | SensorKey string `json:"sensorKey"` 18 | Temperature float64 `json:"temperature"` 19 | High float64 `json:"sensorHigh"` 20 | Critical float64 `json:"sensorCritical"` 21 | } 22 | 23 | func (t TemperatureStat) String() string { 24 | s, _ := json.Marshal(t) 25 | return string(s) 26 | } 27 | 28 | func SensorsTemperatures() ([]TemperatureStat, error) { 29 | return TemperaturesWithContext(context.Background()) 30 | } 31 | -------------------------------------------------------------------------------- /sensors/sensors_aix.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build aix 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | const ( 13 | hostTemperatureScale = 1000.0 // Not part of the linked file, but kept just in case it becomes relevant 14 | ) 15 | 16 | func VirtualizationWithContext(_ context.Context) (string, string, error) { 17 | return "", "", common.ErrNotImplementedError 18 | } 19 | 20 | func TemperaturesWithContext(_ context.Context) ([]TemperatureStat, error) { 21 | return []TemperatureStat{}, common.ErrNotImplementedError 22 | } 23 | -------------------------------------------------------------------------------- /sensors/sensors_fallback.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !aix 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func TemperaturesWithContext(_ context.Context) ([]TemperatureStat, error) { 13 | return []TemperatureStat{}, common.ErrNotImplementedError 14 | } 15 | -------------------------------------------------------------------------------- /sensors/sensors_freebsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build freebsd 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func TemperaturesWithContext(_ context.Context) ([]TemperatureStat, error) { 13 | return []TemperatureStat{}, common.ErrNotImplementedError 14 | } 15 | -------------------------------------------------------------------------------- /sensors/sensors_netbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build netbsd 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func TemperaturesWithContext(_ context.Context) ([]TemperatureStat, error) { 13 | return []TemperatureStat{}, common.ErrNotImplementedError 14 | } 15 | -------------------------------------------------------------------------------- /sensors/sensors_openbsd.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build openbsd 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/shirou/gopsutil/v4/internal/common" 10 | ) 11 | 12 | func TemperaturesWithContext(_ context.Context) ([]TemperatureStat, error) { 13 | return []TemperatureStat{}, common.ErrNotImplementedError 14 | } 15 | -------------------------------------------------------------------------------- /sensors/sensors_solaris.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build solaris 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | "encoding/csv" 9 | "errors" 10 | "io" 11 | "strconv" 12 | "strings" 13 | ) 14 | 15 | func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { 16 | var ret []TemperatureStat 17 | 18 | out, err := invoke.CommandWithContext(ctx, "ipmitool", "-c", "sdr", "list") 19 | if err != nil { 20 | return ret, err 21 | } 22 | 23 | r := csv.NewReader(strings.NewReader(string(out))) 24 | // Output may contain errors, e.g. "bmc_send_cmd: Permission denied", don't expect a consistent number of records 25 | r.FieldsPerRecord = -1 26 | for { 27 | record, err := r.Read() 28 | if errors.Is(err, io.EOF) { 29 | break 30 | } 31 | if err != nil { 32 | return ret, err 33 | } 34 | // CPU1 Temp,40,degrees C,ok 35 | if len(record) < 3 || record[1] == "" || record[2] != "degrees C" { 36 | continue 37 | } 38 | v, err := strconv.ParseFloat(record[1], 64) 39 | if err != nil { 40 | return ret, err 41 | } 42 | ts := TemperatureStat{ 43 | SensorKey: strings.TrimSuffix(record[0], " Temp"), 44 | Temperature: v, 45 | } 46 | ret = append(ret, ts) 47 | } 48 | 49 | return ret, nil 50 | } 51 | -------------------------------------------------------------------------------- /sensors/sensors_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | 3 | package sensors 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/shirou/gopsutil/v4/internal/common" 14 | ) 15 | 16 | func TestTemperatureStat_String(t *testing.T) { 17 | v := TemperatureStat{ 18 | SensorKey: "CPU", 19 | Temperature: 1.1, 20 | High: 30.1, 21 | Critical: 0.1, 22 | } 23 | s := `{"sensorKey":"CPU","temperature":1.1,"sensorHigh":30.1,"sensorCritical":0.1}` 24 | assert.Equalf(t, s, fmt.Sprintf("%v", v), "TemperatureStat string is invalid, %v", fmt.Sprintf("%v", v)) 25 | } 26 | 27 | func TestTemperatures(t *testing.T) { 28 | if os.Getenv("CI") != "" { 29 | t.Skip("Skip CI") 30 | } 31 | v, err := SensorsTemperatures() 32 | common.SkipIfNotImplementedErr(t, err) 33 | require.NoError(t, err) 34 | assert.NotEmptyf(t, v, "Could not get temperature %v", v) 35 | t.Log(v) 36 | } 37 | -------------------------------------------------------------------------------- /sensors/sensors_windows.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build windows 3 | 4 | package sensors 5 | 6 | import ( 7 | "context" 8 | "math" 9 | 10 | "github.com/yusufpapurcu/wmi" 11 | 12 | "github.com/shirou/gopsutil/v4/internal/common" 13 | ) 14 | 15 | type msAcpi_ThermalZoneTemperature struct { //nolint:revive //FIXME 16 | Active bool 17 | CriticalTripPoint uint32 18 | CurrentTemperature uint32 19 | InstanceName string 20 | } 21 | 22 | func TemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { 23 | var ret []TemperatureStat 24 | var dst []msAcpi_ThermalZoneTemperature 25 | q := wmi.CreateQuery(&dst, "") 26 | if err := common.WMIQueryWithContext(ctx, q, &dst, nil, "root/wmi"); err != nil { 27 | return ret, err 28 | } 29 | 30 | for _, v := range dst { 31 | ts := TemperatureStat{ 32 | SensorKey: v.InstanceName, 33 | Temperature: kelvinToCelsius(v.CurrentTemperature, 2), 34 | } 35 | ret = append(ret, ts) 36 | } 37 | 38 | return ret, nil 39 | } 40 | 41 | func kelvinToCelsius(temp uint32, n int) float64 { 42 | // wmi return temperature Kelvin * 10, so need to divide the result by 10, 43 | // and then minus 273.15 to get °Celsius. 44 | t := float64(temp/10) - 273.15 45 | n10 := math.Pow10(n) 46 | return math.Trunc((t+0.5/n10)*n10) / n10 47 | } 48 | -------------------------------------------------------------------------------- /windows_memo.rst: -------------------------------------------------------------------------------- 1 | Windows memo 2 | ===================== 3 | 4 | Size 5 | ---------- 6 | 7 | DWORD 8 | 32-bit unsigned integer 9 | DWORDLONG 10 | 64-bit unsigned integer 11 | DWORD_PTR 12 | unsigned long type for pointer precision 13 | DWORD32 14 | 32-bit unsigned integer 15 | DWORD64 16 | 64-bit unsigned integer 17 | HALF_PTR 18 | _WIN64 = int, else short 19 | INT 20 | 32-bit signed integer 21 | INT_PTR 22 | _WIN64 = __int64 else int 23 | LONG 24 | 32-bit signed integer 25 | LONGLONG 26 | 64-bit signed integer 27 | LONG_PTR 28 | _WIN64 = __int64 else long 29 | SHORT 30 | 16-bit integer 31 | SIZE_T 32 | maximum number of bytes to which a pointer can point. typedef ULONG_PTR SIZE_T; 33 | SSIZE_T 34 | signed version of SIZE_T. typedef LONG_PTR SSIZE_T; 35 | WORD 36 | 16-bit unsigned integer -------------------------------------------------------------------------------- /winservices/manager.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-3-Clause 2 | //go:build windows 3 | 4 | package winservices 5 | 6 | import ( 7 | "golang.org/x/sys/windows/svc/mgr" 8 | ) 9 | 10 | type scmanager struct { 11 | mgr *mgr.Mgr 12 | } 13 | 14 | func openSCManager() (*scmanager, error) { 15 | m, err := mgr.Connect() 16 | if err != nil { 17 | return nil, err 18 | } 19 | return &scmanager{m}, nil 20 | } 21 | 22 | func (sc *scmanager) close() error { 23 | return sc.mgr.Disconnect() 24 | } 25 | 26 | func getService(serviceName string) (*mgr.Service, error) { 27 | m, err := openSCManager() 28 | if err != nil { 29 | return nil, err 30 | } 31 | defer m.close() 32 | return m.mgr.OpenService(serviceName) 33 | } 34 | --------------------------------------------------------------------------------