Git Product home page Git Product logo

go-sysinfo's Introduction

go-sysinfo

go Go Documentation

go-sysinfo is a library for collecting system information. This includes information about the host machine and processes running on the host.

The available features vary based on what has been implemented by the "provider" for the operating system. At runtime you check to see if additional interfaces are implemented by the returned Host or Process. For example:

process, err := sysinfo.Self()
if err != nil {
	return err
}

if handleCounter, ok := process.(types.OpenHandleCounter); ok {
	count, err := handleCounter.OpenHandleCount()
	if err != nil {
		return err
	}
	log.Printf("%d open handles", count)
}

These tables show what methods are implemented as well as the extra interfaces that are implemented.

Host Features Darwin Linux Windows AIX
Info() x x x x
Memory() x x x x
CPUTimer x x x x
LoadAverage x x
VMStat x
NetworkCounters x
Process Features Darwin Linux Windows AIX
Info() x x x x
Memory() x x x x
User() x x x x
Parent() x x x x
CPUTimer x x x x
Environment x x x
OpenHandleEnumerator x
OpenHandleCounter x
Seccomp x
Capabilities x
NetworkCounters x

GOOS / GOARCH Pairs

This table lists the OS and architectures for which a "provider" is implemented.

GOOS / GOARCH Requires CGO Tested
aix/ppc64 x
darwin/amd64 optional * x
darwin/arm64 optional * x
linux/386
linux/amd64 x
linux/arm
linux/arm64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/riscv64
linux/s390x
windows/amd64 x
windows/arm64
windows/arm
  • On darwin (macOS) host information like machineid and process information like memory, cpu, user and starttime require cgo.

Supported Go versions

go-sysinfo supports the two most recent Go releases.

go-sysinfo's People

Contributors

adriansr avatar andrewkroh avatar ariasmn avatar asalih avatar axw avatar bjmcnic avatar danmx avatar dependabot[bot] avatar dliappis avatar fearful-symmetry avatar helflym avatar intxgo avatar kruskall avatar kvch avatar marclop avatar michel-laterman avatar mikemadden42 avatar mmta avatar ph avatar reakaleek avatar ruflin avatar shimmerglass avatar strawgate avatar topazus avatar tsg avatar v1v avatar vjsamuel avatar wardn avatar xmichelo avatar ycombinator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-sysinfo's Issues

Update linux capability names

The list of capability names needs updated for new Linux kernels.

// Generated with:
//
// curl -s https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/capability.h | \
// grep -P '^#define CAP_\w+\s+\d+' | perl -pe 's/#define (\w+)\s+(\d+)/\2: "\1",/g'
var capabilityNames = map[int]string{

I observed some unknown names being reported:

          "block_suspend",
          "audit_read",
          "38",
          "39",
          "40"
        ],

Unresolved dependency howett.net (site down)

I caught a problem with downloading dependency with dep:

(36)  ? attempt github.com/elastic/go-sysinfo with 2 pkgs; at least 1 versions to try
(37)      try github.com/elastic/[email protected]
^CSignal received: waiting for 1 ops to complete...
(37)  ✗   unable to deduce repository and source type for "howett.net/plist": unable to read metadata: unable to fetch raw metadata: failed HTTP request to URL "http://howett.net/plist?go-get=1": Get http://howett.net/plist?go-get=1: context canceled
(37)    ← no more versions of github.com/elastic/go-sysinfo to try; begin backtrack
  ✗ solving failed

Solving failure: No versions of github.com/elastic/go-sysinfo met constraints:
	v1.1.0: unable to deduce repository and source type for "howett.net/plist": unable to read metadata: unable to fetch raw metadata: failed HTTP request to URL "http://howett.net/plist?go-get=1": Get http://howett.net/plist?go-get=1: dial tcp 13.77.158.121:80: i/o timeout

And go get too:

go get howett.net/plist
package howett.net/plist: unrecognized import path "howett.net/plist" (https fetch: Get https://howett.net/plist?go-get=1: dial tcp 13.77.158.121:443: i/o timeout)

What workaround do we have?

LoadAverage() Where is this used?

I'm looking at using your library to provide cross-platform (Linux, BSD and Darwin) System Information, but going through the docs and codebase I don't see where .LoadAverage() is ever used or the interface.

Is this just missing?

Checksum mismatch

verifying github.com/elastic/[email protected]: checksum mismatch
	downloaded: h1:6DBn+WmxLz+IJ9MY+MzX2rWQNd04vSRB3TSuXu/2JjU=
	go.sum:     h1:gRU50CKgoFceePdExPgt6jAK4ZogTqZa4FCQ86shpXQ=

Process starttime non-cgo implementation

From #127 (comment)

I am using the startup time for the Java agent attacher
However, it is not the most crucial piece of info I rely on. Even if I don't do anything, processes will be only identified only based on their PID. That should be good enough as the cache I am maintaining gets updated every second, including the removal of stale process entries, which means there will be a problem only if a process is terminated and another starts with the same PID within one second, which is unlikely enough for the macOS use case (non-production).

APM Server is built without CGO but we need the process starttime for the java attacher and that requires CGO.

Solution: implement process starttime without CGO

TestProcesses failing on CI for darwin

The TestProcesses is constantly failing on CI at least for #144, but it seems to be happening on other PRs as well, even though it passes locally.

I don´t have a mac to investigate it further, I just got someone else to try it and as I said, itś working locally.

[2023-01-23T13:49:10.877Z] === RUN   TestProcesses

[2023-01-23T13:49:10.877Z]     process_darwin_test.go:115: empty exec

[2023-01-23T13:49:10.877Z] --- FAIL: TestProcesses (0.00s)

[2023-01-23T13:49:10.877Z] FAIL

[2023-01-23T13:49:10.877Z] FAIL	github.com/elastic/go-sysinfo/providers/darwin	0.671s

process_windows.go 1 variable returns 2 values

.got this error message:

.....\github.com\elastic\[email protected]\providers\windows\process_windows.go:283:6: assignment mismatch: 1 variable but tokenUser.User.Sid.String returns 2 values
......\github.com\elastic\[email protected]\providers\windows\process_windows.go:292:7: assignment mismatch: 1 variable but tokenGroup.PrimaryGroup.String returns 2 values

sid, err:= tokenUser.User.Sid.String()
if err != nil {
return types.UserInfo{}, errors.Wrap(err, "failed to look up user SID")
}
Sid.String seems to not return error, same for PrimaryGroup.String

AIX unimplemented error

{"log.level":"info","@timestamp":"2023-04-06T16:23:44.996+0300","log.origin":{"file.name":"instance/beat.go","file.line":785},"message":"Home path: [/FBE/filebeat-aix] Config path: [/FBE/filebeat-aix] Data path: [/FBE/filebeat-aix/data] Logs path: [/FBE/filebeat-aix/logs]","service.name":"filebeat","ecs.version":"1.6.0"}
{"log.level":"debug","@timestamp":"2023-04-06T16:23:44.996+0300","log.logger":"beat","log.origin":{"file.name":"instance/beat.go","file.line":859},"message":"Beat metadata path: /FBE/filebeat-aix/data/meta.json","service.name":"filebeat","ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2023-04-06T16:23:44.996+0300","log.origin":{"file.name":"instance/beat.go","file.line":793},"message":"Beat ID: 33bf430e-c802-48f3-8800-a199572b6741","service.name":"filebeat","ecs.version":"1.6.0"}
{"log.level":"error","@timestamp":"2023-04-06T16:23:44.996+0300","log.origin":{"file.name":"instance/beat.go","file.line":1263},"message":"Exiting: failed to get host information: unimplemented","service.name":"filebeat","ecs.version":"1.6.0"}
Exiting: failed to get host information: unimplemented

How do i know which part is unimplemented ,FYI i am new to golang, but can scramble the internet to contribute to working code, my assumption is its this code, but could not correlated with other os like linux to find what is missing in aix


func Host() (types.Host, error) {
	provider := registry.GetHostProvider()
	if provider == nil {
		return nil, types.ErrNotImplemented
	}
	return provider.Host()
}

Can't Install on MacOs Cataline

Installing github.com/elastic/go-sysinfo on MacOs Catalone has this issue ,

github.com/elastic/go-sysinfo/providers/darwin
# github.com/elastic/go-sysinfo/providers/darwin
ld: unsupported tapi file type '!tapi-tbd' in YAML file '/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/lib/libproc.tbd' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Darwin: non-cgo implementation

Description

We've started relying on this library for apm-server to be able to list processes in the context of automatically running the java-attacher within the APM integration. apm-server is compiled and shipped with CGO_DISABLED=1, which is not a problem for any of the platforms except for Darwin.

We wanted to explore improving this library to use a non-cgo implementation for darwin where we could (elastic/apm-server#8718). From my limited exploration, it seems like it's not possible to implement all the functionality provided by C calls and powered by CGO with a non-cgo implementation, however, we can still provide a new non-cgo implementation which implements most of the API and leave a few unsupported API calls that cannot be implemented returning an "unimplemented error: please use the CGO implementation" or shell out where necessary to be able to populate all the types that are fed by CGO.

go-sysinfo repo cleanup meta-issue

I'd like to track a few quality-of-life and codebase maintenance issues here, since I ran into a few things while trying to contribute to the code for the first time.

  • We need some makefiles to run basic Go things: #61

    • go-license
    • formatting
    • goimports
  • A lot of files are missing godocs #62

  • The tests are pretty neglected. After talking with @andrewkroh , it appears the solution is to pull out the ansible, replace it with vagrant setup scripts, and go from there.

Cannot get OS version on Alpine v3.17

Environement

# go mod
github.com/elastic/go-sysinfo v1.9.0
# cat /etc/os-release 
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.17.3
PRETTY_NAME="Alpine Linux v3.17"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

# cat /etc/alpine-release
3.17.3

To Reproduce

Compile code to gosysinfo :

package main

import (
	"fmt"

	sysinfo "github.com/elastic/go-sysinfo"
)

func main() {
	h, err := sysinfo.Host()
	if err == nil {
		fmt.Printf("%+v\n", h.Info())
	} else {
		fmt.Printf("%s\n", err.Error())
	}

}
docker pull  alpine:3.17.3

docker run -it --rm --privileged --mount type=bind,source=/home/root/gosysinfo,target=/usr/share/gosysinfo/gosysinfo --mount   alpine:latest

/usr/share/gosysinfo/gosysinfo 

As you can see the version reported is not the right one (expected 3.17, here major=0) :

{
    "Architecture": "x86_64",
    "BootTime": "2023-04-03T10:19:36Z",
    "Containerized": false,
    "Hostname": "XXXXXXXX",
    "IPs": [
        "127.0.0.1/8",
        "172.17.55.2/16"
    ],
    "KernelVersion": "5.15.0-67-generic",
    "MACs": [
        "02XXXXXXXXX:02"
    ],
    "OS": {
        "type": "linux",
        "family": "",
        "platform": "alpine",
        "name": "Alpine Linux",
        "version": "",
        "major": 0,
        "minor": 0,
        "patch": 0
    },
    "Timezone": "UTC",
    "TimezoneOffsetSec": 0,
    "UniqueID": ""
}

Make the "host FS" location configurable

There needs to be a way to pass in the host filesystem location as an option to allow collection from the host machine when operating inside of Docker. This is equivalent to how Metricbeat allows the -system.hostfs CLI option.

This must not be set as a global variable as it is in both gosigar and gopsutil.

I'm thinking to have an API like sysinfo.New(opts types.Option) and have an option that can be used like types.HostFS("/hostfs"). sysinfo.New would return an interface that has methods like Host(), Processes(), Process(), and Self().

And I think only the Linux provider would actually honor this option.

Return FQDN in hostname

Getting the FQDN of the local host has always been a pain point in Go. It would be nice if this library could provide that functionality and return the FQDN in the types.HostInfo.Hostname field.

macOS ARM - Incorrect process CPU times

Based on similar code in other projects it looks like the process CPU times may not be scaled correctly on Apple M1 / M2 hardware. This code needs to apply a scaling factor from https://developer.apple.com/documentation/driverkit/mach_timebase_info_t to the ticks. Under intel macs these were simple 1 tick = 1 nanosecond so it just worked.

User: time.Duration(task.Ptinfo.Total_user),
System: time.Duration(task.Ptinfo.Total_system),

Related

Download module failed on MacOS 11.4

download module failed with undefined struct C.uuid_string_t under MacOS 11.4

go get github.com/elastic/go-sysinfo@latest
go: downloading github.com/elastic/go-sysinfo v1.7.0
go: downloading golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae
go: downloading github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0
# github.com/elastic/go-sysinfo/providers/darwin
../../../go/pkg/mod/github.com/elastic/[email protected]/providers/darwin/machineid_darwin.go:53:18: could not determine kind of name for C.uuid_string_t

machine kernel:

uname -v
Darwin Kernel Version 20.5.0

uuid_string_t not appear in /usr/local/include/uuid/uuid.h, it seems has to def it with (typedef __darwin_uuid_string_t uuid_string_t;)[https://developer.apple.com/documentation/kernel/uuid_string_t]

Cannot get OS version on Manjaro 22.1.0 Talos

Reason

Version is only in /etc/lsb-release, neither in /etc/os-release nor in /etc/manjaro-release.

Environment

# go mod
github.com/elastic/go-sysinfo v1.10.1
# cat /etc/os-release 
NAME="Manjaro Linux"
PRETTY_NAME="Manjaro Linux"
ID=manjaro
ID_LIKE=arch
BUILD_ID=rolling
ANSI_COLOR="32;1;24;144;200"
HOME_URL="https://manjaro.org/"
DOCUMENTATION_URL="https://wiki.manjaro.org/"
SUPPORT_URL="https://forum.manjaro.org/"
BUG_REPORT_URL="https://docs.manjaro.org/reporting-bugs/"
PRIVACY_POLICY_URL="https://manjaro.org/privacy-policy/"

# cat /etc/manjaro-release 
Manjaro Linux

# cat /etc/lsb-release
DISTRIB_ID=ManjaroLinux
DISTRIB_RELEASE=22.1.0
DISTRIB_CODENAME=Talos
DISTRIB_DESCRIPTION="Manjaro Linux"

To Reproduce

Compile code to gosysinfo :

package main

import (
	"fmt"

	sysinfo "github.com/elastic/go-sysinfo"
)

func main() {
	h, err := sysinfo.Host()
	if err == nil {
		fmt.Printf("%+v\n", h.Info())
	} else {
		fmt.Printf("%s\n", err.Error())
	}

}
docker pull manjarolinux/base:20230101

docker run -it --rm --privileged --mount type=bind,source=/home/root/gosysinfo,target=/usr/share/gosysinfo/gosysinfo --mount   manjarolinux/base:20230101

/usr/share/gosysinfo/gosysinfo 

As you can see the version reported is not the right one (expected 22.1, here major=0) :

And by the way manjaro belong to the arch family.

{
    "Architecture": "x86_64",
    "BootTime": "2023-04-03T16:22:16Z",
    "Containerized": false,
    "Hostname": "225666ab961a",
    "IPs": [
        "127.0.0.1/8",
        "1xxxxx.2/16"
    ],
    "KernelVersion": "5.15.0-67-generic",
    "MACs": [
        "02:aa:ac:aa:00:02"
    ],
    "OS": {
        "type": "linux",
        "family": "",
        "platform": "manjaro",
        "name": "Manjaro Linux",
        "version": "",
        "major": 0,
        "minor": 0,
        "patch": 0,
        "build": "rolling",
        "codename": "Talos"
    },
    "Timezone": "UTC",
    "TimezoneOffsetSec": 0,
    "UniqueID": "cdddcdddddddddddd"
}

Add go-sysinfo cmd

Hi,

As a new user of this package, I had to spend a little more time to understand what kind of information go-sysinfo was able to provide, say compared to other packages, e.g., https://github.com/zcalusic/sysinfo.

A simple utility command line program would help new users to check quickly all the available information. For example, something like below.

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/elastic/go-sysinfo"
	"github.com/elastic/go-sysinfo/types"
)

type SysInfo struct {
	ProcessInfo    types.ProcessInfo     `json:"process_info"`
	CPUTimes       types.CPUTimes        `json:"cpu_times"`
	MemoryInfo     types.MemoryInfo      `json:"memory_info"`
	UserInfo       types.UserInfo        `json:"user_info"`
	HostInfo       types.HostInfo        `json:"host_info"`
	HostMemoryInfo *types.HostMemoryInfo `json:"host_memory_info"`
}

func GetSysInfo() SysInfo {
	process, _ := sysinfo.Self()
	processInfo, _ := process.Info()
	cpuTime, _ := process.CPUTime()
	memoryInfo, _ := process.Memory()
	userInfo, _ := process.User()

	host, _ := sysinfo.Host()
	hostInfo := host.Info()
	hostMemoryInfo, _ := host.Memory()

	return SysInfo{
		ProcessInfo:    processInfo,
		CPUTimes:       cpuTime,
		MemoryInfo:     memoryInfo,
		UserInfo:       userInfo,
		HostInfo:       hostInfo,
		HostMemoryInfo: hostMemoryInfo,
	}
}

func main() {
	sysinf := GetSysInfo()

	data, err := json.MarshalIndent(&sysinf, "", "  ")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(data))
}

Output:

{
  "process_info": {
    "name": "sysinfo",
    "pid": 10142,
    "ppid": 25771,
    "cwd": "/workspace/go-sysinfo/cmd/sysinfo",
    "exe": "/workspace/go-sysinfo/cmd/sysinfo/sysinfo",
    "args": [
      "./sysinfo"
    ],
    "start_time": "2021-10-24T16:23:14.47Z"
  },
  "cpu_times": {
    "user": 0,
    "system": 0
  },
  "memory_info": {
    "resident_bytes": 5734400,
    "virtual_bytes": 720535552
  },
  "user_info": {
    "uid": "0",
    "euid": "0",
    "suid": "0",
    "gid": "0",
    "egid": "0",
    "sgid": "0"
  },
  "host_info": {
    "architecture": "x86_64",
    "boot_time": "2021-10-24T10:28:56Z",
    "containerized": true,
    "name": "58755aabff76",
    "ip": [
      "127.0.0.1/8",
      "172.18.0.2/16"
    ],
    "kernel_version": "5.4.72-microsoft-standard-WSL2",
    "mac": [
      "02:42:ac:12:00:02"
    ],
    "os": {
      "type": "linux",
      "family": "",
      "platform": "alpine",
      "name": "Alpine Linux",
      "version": "",
      "major": 0,
      "minor": 0,
      "patch": 0
    },
    "timezone": "UTC",
    "timezone_offset_sec": 0,
    "id": "8203ec2a7d4a85be1975970061753e5c"
  },
  "host_memory_info": {
    "total_bytes": 13293199360,
    "used_bytes": 4198158336,
    "available_bytes": 11434057728,
    "free_bytes": 9095041024,
    "virtual_total_bytes": 4294967296,
    "virtual_used_bytes": 0,
    "virtual_free_bytes": 4294967296,
    "raw": {
      "Active": 1741504512,
      "Active(anon)": 1001545728,
      "Active(file)": 739958784,
      "AnonHugePages": 262144000,
      "AnonPages": 878346240,
      "Bounce": 0,
      "Buffers": 310341632,
      "Cached": 2418610176,
      "CommitLimit": 10941566976,
      "Committed_AS": 4803932160,
      "DirectMap1G": 7516192768,
      "DirectMap2M": 6067060736,
      "DirectMap4k": 47185920,
      "Dirty": 0,
      "FileHugePages": 0,
      "FilePmdMapped": 0,
      "HugePages_Free": 0,
      "HugePages_Rsvd": 0,
      "HugePages_Surp": 0,
      "HugePages_Total": 0,
      "Hugepagesize": 2097152,
      "Hugetlb": 0,
      "Inactive": 2007437312,
      "Inactive(anon)": 297070592,
      "Inactive(file)": 1710366720,
      "KReclaimable": 216645632,
      "KernelStack": 15048704,
      "Mapped": 273330176,
      "Mlocked": 0,
      "NFS_Unstable": 0,
      "PageTables": 9781248,
      "Percpu": 6750208,
      "SReclaimable": 216645632,
      "SUnreclaim": 104050688,
      "Shmem": 386269184,
      "ShmemHugePages": 0,
      "ShmemPmdMapped": 0,
      "Slab": 320696320,
      "SwapCached": 0,
      "Unevictable": 0,
      "VmallocChunk": 0,
      "VmallocTotal": 35184372087808,
      "VmallocUsed": 35704832,
      "Writeback": 0,
      "WritebackTmp": 0
    }
  }
}

cross compile on aix fails

env
GOOS=aix
GOARCH=ppc64

`# github.com/elastic/go-sysinfo/providers/aix
........\go\pkg\mod\github.com\elastic\[email protected]\providers\aix\os_aix.go:36:23: undefined: getKernelVersion
........\go\pkg\mod\github.com\elastic\[email protected]\providers\aix\os_aix.go:42:19: cannot assign error to err in multiple assignment

Swallowing errors

Neither types.CPUTimer.CPUTime() nor types.Memory.Memory() return an error, so the implementations swallow errors. This means the caller must check the value if they want to be sure they're operating on valid information. Can we surface the error, and let the caller decide what to do with it?

openEuler: osFamily value is null

when i use the code to get the value of os information.

h, err := sysinfo.Host()
info := h.Info()
fmt.Println(info.OS.Family)

osName show the value is "openEuler",but the info.OS.Family show the null value.

AIX build issue

Hello

Trying to build AIX binaries using golang 1.16.5, I am seeing the following error:

 # github.com/elastic/go-sysinfo/providers/aix
../../../../pkg/mod/github.com/elastic/[email protected]/providers/aix/os_aix.go:36:23: undefined: getKernelVersion

I see this was previously marked as resolved by upgrading go compiler in elastic/apm-integration-testing#891

Upgrading does not seem to help. I can reproduce the issue in both a Linux container (github actions) and locally on macOS.

image

Failed to get OS info on Fedora 30

On Fedora 30 you get no /etc/<distrib>-release file found because all the files are symlinks and only regular files are read at

if err != nil || !info.Mode().IsRegular() || info.Size() == 0 {

ls -la /etc/*-release
lrwxrwxrwx. 1 root root 25 May 16 13:03 /etc/fedora-release -> ../usr/lib/fedora-release
lrwxrwxrwx. 1 root root 21 May 16 13:03 /etc/os-release -> ../usr/lib/os-release
lrwxrwxrwx. 1 root root 14 May 16 13:03 /etc/redhat-release -> fedora-release
lrwxrwxrwx. 1 root root 14 May 16 13:03 /etc/system-release -> fedora-release

package broken/ won't build

I use Go agent for elastic apm but and go-sysinfo is one of the dependency there but since this morning I am getting this error while trying to build my packages

github.com/elastic/go-sysinfo/providers/linux
src/github.com/elastic/go-sysinfo/providers/linux/host_linux.go:45:20: cannot convert filepath.Join(hostFS, procfs.DefaultMountPoint) (type string) to type procfs.FS
src/github.com/elastic/go-sysinfo/providers/linux/host_linux.go:64:42: h.procFS.Path undefined (type procfs.FS has no field or method Path)
src/github.com/elastic/go-sysinfo/providers/linux/process_linux.go:91:13: p.fs.Path undefined (type procfs.FS has no field or method Path)

help?

Containerized value showing false positive

I'm seeing some false positives from the containerized value. This was captured while running the beat as a service.

{
  "level": "info",
  "timestamp": "2018-04-06T21:33:35.738Z",
  "logger": "beat",
  "caller": "instance/beat.go:722",
  "message": "Host info",
  "system_info": {
    "host": {
      "architecture": "x86_64",
      "boot_time": "2018-04-06T21:31:48Z",
      "containerized": true,
      "hostname": "localhost.localdomain",
      "ips": [
        "127.0.0.1/8",
        "::1/128",
        "10.0.2.15/24",
        "fe80::a00:27ff:feaf:8570/64",
        "192.168.33.78/24",
        "fe80::a00:27ff:fe8c:2fcb/64"
      ],
      "kernel_version": "4.9.17-8.31.amzn1.x86_64",
      "mac_addresses": [
        "08:00:27:af:85:70",
        "08:00:27:8c:2f:cb"
      ],
      "os": {
        "family": "",
        "platform": "amzn",
        "name": "Amazon Linux AMI",
        "version": "2017.03",
        "major": 2017,
        "minor": 3,
        "patch": 0
      },
      "timezone": "UTC",
      "timezone_offset_sec": 0
    }
  }
}
{"level":"info","timestamp":"2018-04-06T23:33:32.708+0200","logger":"beat","caller":"instance/beat.go:751","message":"Process info","system_info":{"process":{"capabilities":{"inheritable":null,"permitted":["chown","dac_override","dac_read_search","fowner","fsetid","kill","setgid","setuid","setpcap","linux_immutable","net_bind_service","net_broadcast","net_admin","net_raw","ipc_lock","ipc_owner","sys_module","sys_rawio","sys_chroot","sys_ptrace","sys_pacct","sys_admin","sys_boot","sys_nice","sys_resource","sys_time","sys_tty_config","mknod","lease","audit_write","audit_control","setfcap","mac_override","mac_admin","syslog","wake_alarm","block_suspend"],"effective":["chown","dac_override","dac_read_search","fowner","fsetid","kill","setgid","setuid","setpcap","linux_immutable","net_bind_service","net_broadcast","net_admin","net_raw","ipc_lock","ipc_owner","sys_module","sys_rawio","sys_chroot","sys_ptrace","sys_pacct","sys_admin","sys_boot","sys_nice","sys_resource","sys_time","sys_tty_config","mknod","lease","audit_write","audit_control","setfcap","mac_override","mac_admin","syslog","wake_alarm","block_suspend"],"bounding":["chown","dac_override","dac_read_search","fowner","fsetid","kill","setgid","setuid","setpcap","linux_immutable","net_bind_service","net_broadcast","net_admin","net_raw","ipc_lock","ipc_owner","sys_module","sys_rawio","sys_chroot","sys_ptrace","sys_pacct","sys_admin","sys_boot","sys_nice","sys_resource","sys_time","sys_tty_config","mknod","lease","audit_write","audit_control","setfcap","mac_override","mac_admin","syslog","wake_alarm","block_suspend"],"ambient":null},"cwd":"/","exe":"/usr/share/packetbeat/bin/packetbeat","name":"packetbeat","pid":4946,"ppid":1,"seccomp":{"mode":"disabled"},"start_time":"2018-04-06T23:33:32.260+0200"}}}

Linux kernel ticks assumption is error prone

Problem

The value of clock ticks (_SC_CLK_TCK) is hard coded and might varies across kernel versions and hardware platforms, it would probably be best if you could read this value dynamically.

There is an assumption here for certain conditions that might not be respected between different deployments and versions.
please read the wiki article about Kernel Timer Systems:

The original kernel timer system (called the "timer wheel) was based on incrementing a kernel-internal value (jiffies) every timer interrupt. The timer interrupt becomes the default scheduling quantum, and all other timers are based on jiffies. The timer interrupt rate (and jiffy increment rate) is defined by a compile-time constant called HZ. Different platforms use different values for HZ. Historically, the kernel used 100 as the value for HZ, yielding a jiffy interval of 10 ms. With 2.4, the HZ value for i386 was changed to 1000, yielding a jiffy interval of 1 ms. Recently (2.6.13) the kernel changed HZ for i386 to 250. (1000 was deemed too high).

Proposed solution

Make a sys call to retrieve the actual _SC_CLK_TCK and use it for process time calculations, the same has been done for Darwin:

// getClockTicks returns the number of click ticks in one jiffie.
func getClockTicks() int {
return int(C.sysconf(C._SC_CLK_TCK))
}

assignment mismatch in process_windows.go (#65 wasn't really fixed)

I left a comment in #65, but since it's already closed, here's a repost with a quick test result on Windows.

The related upstream change hasn't been reverted, func (sid *SID) String() is still returning only 1 value: https://github.com/golang/sys/blob/master/windows/security_windows.go#L231

PS C:\Users\mmta\proj\sysinfowin> go get -u -v github.com/elastic/go-sysinfo
go: finding github.com/elastic/go-sysinfo v1.1.0
go: downloading github.com/elastic/go-sysinfo v1.1.0
go: extracting github.com/elastic/go-sysinfo v1.1.0
go: downloading github.com/pkg/errors v0.8.1
go: downloading golang.org/x/sys v0.0.0-20191023151326-f89234f9a2c2
go: downloading github.com/elastic/go-windows v1.0.1
go: downloading howett.net/plist v0.0.0-20181124034731-591f970eefbb
go: downloading github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
go: downloading github.com/prometheus/procfs v0.0.5
go: extracting github.com/pkg/errors v0.8.1
go: extracting github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
go: extracting github.com/elastic/go-windows v1.0.1
go: extracting howett.net/plist v0.0.0-20181124034731-591f970eefbb
go: extracting github.com/prometheus/procfs v0.0.5
go: extracting golang.org/x/sys v0.0.0-20191023151326-f89234f9a2c2
go: finding golang.org/x/sys latest
go: finding howett.net/plist latest
go: finding github.com/joeshaw/multierror latest
go: finding github.com/pkg/errors v0.8.1
go: finding github.com/elastic/go-windows v1.0.1
go: finding github.com/prometheus/procfs v0.0.5
github.com/elastic/go-sysinfo/providers/windows
# github.com/elastic/go-sysinfo/providers/windows
..\..\go\pkg\mod\github.com\elastic\go-sysinfo@v1.1.0\providers\windows\process_windows.go:307:11: assignment mismatch: 2 variables but tokenUser.User.Sid.String returns 1 values
..\..\go\pkg\mod\github.com\elastic\go-sysinfo@v1.1.0\providers\windows\process_windows.go:316:12: assignment mismatch: 2 variables but tokenGroup.PrimaryGroup.String returns 1 values

Import cycle not allowed

Hello, I tried to copy-paste the function in the readme in a main function, but the Go compiler says imports sysinfo: import cycle not allowed.

That's the full code:

package main

import (
	"log"
	"sysinfo"
)

func main() {
	process, err := sysinfo.Self()
	if err != nil {
		log.Fatal(err)
	}

	if handleCounter, ok := process.(types.OpenHandleCounter); ok {
		count, err := handleCounter.OpenHandleCount()
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("%d open handles", count)
	}
}

OS: Windows 10
Golang Version: 1.16.5

test.sh failed on MacOS and Linux (amd64)

The github actions for macos failed with the below error:

Run .ci/scripts/test.sh
+ GO111MODULE=off
+ go get -u github.com/elastic/go-licenser
+ go mod verify
all modules verified
+ go-licenser -d
+ go run .ci/scripts/check_format.go
Run goimports on the code.
providers/aix/boottime_test.go
providers/aix/defs_aix.go
providers/darwin/arch_darwin.go
providers/darwin/boottime_darwin.go
providers/darwin/defs_darwin.go
providers/darwin/host_darwin.go
providers/darwin/kernel_darwin.go
providers/darwin/machineid_darwin.go
providers/darwin/memory_darwin.go
providers/darwin/process_darwin.go
providers/darwin/process_darwin_test.go
providers/darwin/syscall_darwin.go
providers/linux/os_test.go
exit status 1

assignment mismatch in process_windows.go

I'm getting these errors (and upgrading to 1.1.0 didn't help):

/go/pkg/mod/github.com/elastic/[email protected]/providers/windows/process_windows.go:283:11: assignment mismatch: 2 variables but tokenUser.User.Sid.String returns 1 values
/go/pkg/mod/github.com/elastic/[email protected]/providers/windows/process_windows.go:292:12: assignment mismatch: 2 variables but tokenGroup.PrimaryGroup.String returns 1 values

Panic on macOS Catalina 10.15.7

In #135 we changed from a custom sysctl implementation to the Go stdlib version. There is a kernel bug1 in Catalina that causes the stdlib version to return bad data to go-sysinfo. There is issue open in Go to track a possible fix golang/go#60047.

#172 adds defensive measures to prevent bad data from causing a panic in go-sysinfo. We probably need another change to revert to the custom sysctl implementation for Catalina (darwin/amd64 version 10.15).

goroutine 1 [running]:
github.com/elastic/go-sysinfo/providers/darwin.kern_procargs(0xc0003df430?, 0xc0001168c0)
github.com/elastic/[email protected]/providers/darwin/process_darwin.go:207 +0x58f
github.com/elastic/go-sysinfo/providers/darwin.(*process).Info(0xc0001168c0)
github.com/elastic/[email protected]/providers/darwin/process_darwin.go:104 +0x1b4
go.elastic.co/apm/v2.currentProcessTitle()
go.elastic.co/apm/[email protected]/utils_other.go:34 +0x5f
go.elastic.co/apm/v2.getCurrentProcess()
go.elastic.co/apm/[email protected]/utils.go:83 +0x65
go.elastic.co/apm/v2.init.1()
go.elastic.co/apm/[email protected]/utils.go:77 +0x2b

https://discuss.elastic.co/t/macos-10-15-7-cannot-execute-filebeat-auditbeat-or-metricbeat/333471

Footnotes

  1. https://github.com/apple-oss-distributions/xnu/blob/xnu-7195.50.7.100.1/bsd/kern/kern_sysctl.c#L1552-#L1592

Timestamp fields superfluous

The Timestamp fields of types.CPUTimes and types.MemoryInfo are unnecessary for my purposes. It's wasteful to call time.Now() just to discard the value. I don't think they really belong here - can these be removed?

If it's here only for the JSON-encoding, then you can embed CPUTimes/MemoryInfo in another struct to get the same effect, e.g.

type TimestampedCPUTimes struct {
    Timestamp time.Time `json:"timestamp"`
    types.CPUTimes
}

Broken dependency on Prometheus package

There are new breaks derived from the Prometheus package in linux builds:

../github.com/elastic/go-sysinfo/providers/linux/boottime_linux.go:40:17: fs.NewStat undefined (type procfs.FS has no field or method NewStat)
../github.com/elastic/go-sysinfo/providers/linux/host_linux.go:75:23: h.procFS.NewStat undefined (type procFS has no field or method NewStat)
../github.com/elastic/go-sysinfo/providers/linux/host_linux.go:93:17: fs.NewStat undefined (type procFS has no field or method NewStat)
../github.com/elastic/go-sysinfo/providers/linux/process_linux.go:49:23: s.procFS.NewProc undefined (type procFS has no field or method NewProc)
../github.com/elastic/go-sysinfo/providers/linux/process_linux.go:82:19: p.fs.NewProc undefined (type procFS has no field or method NewProc)

I will issue a pull request which allows compilation (the NewStat() method was moved from the process.FS struct to a function on the root of the package) but I am uncertain of the implications it will have for the this package.

Use GOARCH for host architecture?

At the moment, each of the OS providers is using OS-specific code to determine the architecture. Is there a reason for doing this, rather than using the compiled-in GOARCH value?

Unified CPUTimer interface for Host and Process?

The Host and Process (by way of CPUTimer) interfaces currently have incompatible CPUTime methods:

type Host interface {
    CPUTime() (*types.CPUTimes, error)
}

type CPUTimer interface {
    CPUTime() types.CPUTimes
}

It would be nice if they were the same. That would make it straightforward to implement functions that operate on a CPUTimer and accept either a Host or Process. By taking Host's current signature, we would also address #17 for the CPUTimer case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.