Repository: elastic/go-sysinfo
Pull request #96 (2021-04-20 16:19:31)

Add per-process NetworkCounters
This is a fairly simple PR that adds the ability to query per-process network stats, found under `/proc/[PID]/net/`.

This basically reuses the existing code that grabs these stats at a global level, since the only difference is the path. I've never tinkered with the process stats before, so hopefully I'm not forgetting anything.

I also took the liberty of running `make format` on everything, so there's a handful of added changes.

elasticmachine: 
## :broken_heart: Build Failed


<!-- BUILD BADGES-->
> _the below badges are clickable and redirect to their specific view in the CI or DOCS_
[![Pipeline View](https://img.shields.io/badge/pipeline-pipeline%20-green)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-sysinfo-mbp%2FPR-96/detail/PR-96/1//pipeline) [![Test View](https://img.shields.io/badge/test-test-green)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-sysinfo-mbp%2FPR-96/detail/PR-96/1//tests) [![Changes](https://img.shields.io/badge/changes-changes-green)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-sysinfo-mbp%2FPR-96/detail/PR-96/1//changes) [![Artifacts](https://img.shields.io/badge/artifacts-artifacts-yellow)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-sysinfo-mbp%2FPR-96/detail/PR-96/1//artifacts) [![preview](https://img.shields.io/badge/docs-preview-yellowgreen)](http://go-sysinfo_96.docs-preview.app.elstc.co/diff)

<!-- BUILD SUMMARY-->
<details><summary>Expand to view the summary</summary>
<p>

#### Build stats


* Build Cause: `Pull request #96 opened`



* Start Time: 2021-04-20T16:19:46.881+0000


* Duration: 6 min 18 sec


* Commit: b77e3b1a2d63526709f48e75a54b9b72b17c0a21



#### Test stats :test_tube:

| Test         | Results                         |
| ------------ | :-----------------------------: |
| Failed       | 0  |
| Passed       | 9  |
| Skipped      | 0 |
| Total        | 9   |


#### Trends :test_tube:


![Image of Build Times](https://beats-ci.elastic.co/job/Library/job/go-sysinfo-mbp/job/PR-96/buildTimeGraph/png)


![Image of Tests](https://beats-ci.elastic.co/job/Library/job/go-sysinfo-mbp/job/PR-96/1/testReport/history/countGraph/png?start=0&amp;end=25)


</p>
</details>

<!-- TEST RESULTS IF ANY-->


<!-- STEPS ERRORS IF ANY -->









### Steps errors [![3](https://img.shields.io/badge/3%20-red)](https://beats-ci.elastic.co/blue/organizations/jenkins/Library%2Fgo-sysinfo-mbp%2FPR-96/detail/PR-96/1//pipeline)
  <details><summary>Expand to view the steps failures</summary>
  <p>


  
  
  
  
##### `go test for 1.12.17 in ubuntu-18 && immutable`
<ul>
<li>Took 0 min 14 sec . View more details on <a href="https://beats-ci.elastic.co//blue/rest/organizations/jenkins/pipelines/Library/pipelines/go-sysinfo-mbp/pipelines/PR-96/runs/1/steps/240/log/?start=0">here</a></li>
<li>Description: <code>.ci/scripts/test.sh</code></l1>
</ul>
  
  
  
  
##### `go test for 1.12.17 in macosx&&x86_64`
<ul>
<li>Took 0 min 20 sec . View more details on <a href="https://beats-ci.elastic.co//blue/rest/organizations/jenkins/pipelines/Library/pipelines/go-sysinfo-mbp/pipelines/PR-96/runs/1/steps/174/log/?start=0">here</a></li>
<li>Description: <code>.ci/scripts/test.sh</code></l1>
</ul>
  
  
  
  
##### `go test for 1.16 in macosx&&arm64`
<ul>
<li>Took 0 min 16 sec . View more details on <a href="https://beats-ci.elastic.co//blue/rest/organizations/jenkins/pipelines/Library/pipelines/go-sysinfo-mbp/pipelines/PR-96/runs/1/steps/163/log/?start=0">here</a></li>
<li>Description: <code>.ci/scripts/test.sh</code></l1>
</ul>
  
  </p>
  </details>



<!-- LOG OUTPUT-->
### Log output

<details><summary>Expand to view the last 100 lines of log output</summary>
<p>

```
[2021-04-20T16:25:08.519Z] ) 
[2021-04-20T16:25:08.519Z] 
[2021-04-20T16:25:08.519Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96>where /q gcc 
[2021-04-20T16:25:08.519Z] 
[2021-04-20T16:25:08.519Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96>IF ERRORLEVEL 1 (
[2021-04-20T16:25:08.519Z] REM Install mingw 5.3.0  
[2021-04-20T16:25:08.519Z]  choco install mingw -y -r --no-progress --version 5.3.0  
[2021-04-20T16:25:08.519Z]  IF NOT ERRORLEVEL 0 (exit /b 1 ) 
[2021-04-20T16:25:08.519Z] ) 
[2021-04-20T16:25:08.519Z] 
[2021-04-20T16:25:08.519Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96>gcc --version 
[2021-04-20T16:25:08.519Z] gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 5.3.0
[2021-04-20T16:25:08.519Z] Copyright (C) 2015 Free Software Foundation, Inc.
[2021-04-20T16:25:08.519Z] This is free software; see the source for copying conditions.  There is NO
[2021-04-20T16:25:08.519Z] warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[2021-04-20T16:25:08.519Z] 
[2021-04-20T16:25:08.519Z] 
[2021-04-20T16:25:08.519Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96>where gcc 
[2021-04-20T16:25:08.519Z] C:\tools\mingw64\bin\gcc.exe
[2021-04-20T16:25:08.648Z] Running in C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo
[2021-04-20T16:25:09.058Z] 
[2021-04-20T16:25:09.058Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>.ci/scripts/test.bat
[2021-04-20T16:25:09.058Z] 
[2021-04-20T16:25:09.058Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>SET GO111MODULE=off 
[2021-04-20T16:25:09.058Z] 
[2021-04-20T16:25:09.058Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go get -u github.com/elastic/go-licenser 
[2021-04-20T16:25:14.327Z] 
[2021-04-20T16:25:14.327Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>SET GO111MODULE=on 
[2021-04-20T16:25:14.327Z] 
[2021-04-20T16:25:14.327Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go mod verify 
[2021-04-20T16:25:14.327Z] go: finding github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
[2021-04-20T16:25:14.327Z] go: finding github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0
[2021-04-20T16:25:14.327Z] go: finding github.com/stretchr/testify v1.3.0
[2021-04-20T16:25:14.327Z] go: finding github.com/elastic/go-windows v1.0.0
[2021-04-20T16:25:14.327Z] go: finding github.com/pkg/errors v0.8.1
[2021-04-20T16:25:14.327Z] go: finding golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae
[2021-04-20T16:25:14.588Z] go: finding howett.net/plist v0.0.0-20181124034731-591f970eefbb
[2021-04-20T16:25:15.967Z] go: finding github.com/kr/pretty v0.1.0
[2021-04-20T16:25:15.967Z] go: finding github.com/jessevdk/go-flags v1.4.0
[2021-04-20T16:25:15.967Z] go: finding golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4
[2021-04-20T16:25:16.227Z] go: finding github.com/stretchr/objx v0.1.0
[2021-04-20T16:25:16.227Z] go: finding github.com/pmezard/go-difflib v1.0.0
[2021-04-20T16:25:16.227Z] go: finding github.com/davecgh/go-spew v1.1.0
[2021-04-20T16:25:16.795Z] go: finding gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127
[2021-04-20T16:25:16.795Z] go: finding gopkg.in/yaml.v2 v2.2.1
[2021-04-20T16:25:17.370Z] go: finding github.com/kr/text v0.1.0
[2021-04-20T16:25:18.749Z] go: finding github.com/kr/pty v1.1.1
[2021-04-20T16:25:19.688Z] go: finding gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
[2021-04-20T16:25:21.590Z] all modules verified
[2021-04-20T16:25:21.590Z] 
[2021-04-20T16:25:21.590Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go-licenser -d 
[2021-04-20T16:25:21.590Z] 
[2021-04-20T16:25:21.590Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go run .ci/scripts/check_format.go 
[2021-04-20T16:25:43.678Z] Run goimports on the code.
[2021-04-20T16:25:43.678Z] providers\linux\process_linux_test.go
[2021-04-20T16:25:43.678Z] exit status 1
[2021-04-20T16:25:43.678Z] 
[2021-04-20T16:25:43.678Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go run .ci/scripts/check_lint.go 
[2021-04-20T16:25:50.236Z] 
[2021-04-20T16:25:50.236Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>mkdir -p build 
[2021-04-20T16:25:50.236Z] 
[2021-04-20T16:25:50.236Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>SET OUT_FILE=build\output-report.out 
[2021-04-20T16:25:50.236Z] 
[2021-04-20T16:25:50.236Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go test "./..." -v   1>build\output-report.out  | type build\output-report.out 
[2021-04-20T16:25:50.236Z] go: downloading github.com/pkg/errors v0.8.1
[2021-04-20T16:25:50.236Z] go: downloading howett.net/plist v0.0.0-20181124034731-591f970eefbb
[2021-04-20T16:25:50.236Z] go: downloading github.com/stretchr/testify v1.3.0
[2021-04-20T16:25:50.236Z] go: downloading golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae
[2021-04-20T16:25:50.236Z] go: downloading github.com/elastic/go-windows v1.0.0
[2021-04-20T16:25:50.236Z] go: downloading github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
[2021-04-20T16:25:50.236Z] go: extracting github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
[2021-04-20T16:25:50.236Z] go: extracting github.com/pkg/errors v0.8.1
[2021-04-20T16:25:50.236Z] go: extracting github.com/elastic/go-windows v1.0.0
[2021-04-20T16:25:50.236Z] go: extracting github.com/stretchr/testify v1.3.0
[2021-04-20T16:25:50.236Z] go: downloading github.com/pmezard/go-difflib v1.0.0
[2021-04-20T16:25:50.236Z] go: downloading github.com/davecgh/go-spew v1.1.0
[2021-04-20T16:25:50.236Z] go: extracting howett.net/plist v0.0.0-20181124034731-591f970eefbb
[2021-04-20T16:25:50.236Z] go: extracting github.com/pmezard/go-difflib v1.0.0
[2021-04-20T16:25:50.236Z] go: extracting github.com/davecgh/go-spew v1.1.0
[2021-04-20T16:25:50.236Z] go: extracting golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae
[2021-04-20T16:25:58.342Z] 
[2021-04-20T16:25:58.342Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go get -v -u github.com/jstemmer/go-junit-report 
[2021-04-20T16:25:58.601Z] go: finding github.com/jstemmer/go-junit-report v0.9.1
[2021-04-20T16:25:59.534Z] go: downloading github.com/jstemmer/go-junit-report v0.9.1
[2021-04-20T16:25:59.534Z] go: extracting github.com/jstemmer/go-junit-report v0.9.1
[2021-04-20T16:25:59.793Z] github.com/jstemmer/go-junit-report/parser
[2021-04-20T16:26:00.052Z] github.com/jstemmer/go-junit-report/formatter
[2021-04-20T16:26:00.052Z] github.com/jstemmer/go-junit-report
[2021-04-20T16:26:01.424Z] 
[2021-04-20T16:26:01.424Z] C:\Users\jenkins\workspace\Library_go-sysinfo-mbp_PR-96\src\github.com\elastic\go-sysinfo>go-junit-report  1>build\junit-1.12.17.xml 0<build\output-report.out 
[2021-04-20T16:26:02.923Z] Post stage
[2021-04-20T16:26:02.950Z] Recording test results
[2021-04-20T16:26:03.576Z] [Checks API] No suitable checks publisher found.
[2021-04-20T16:26:04.163Z] Running on Jenkins in /var/lib/jenkins/workspace/Library_go-sysinfo-mbp_PR-96
[2021-04-20T16:26:04.290Z] [INFO] getVaultSecret: Getting secrets
[2021-04-20T16:26:04.419Z] Masking supported pattern matches of $VAULT_ADDR or $VAULT_ROLE_ID or $VAULT_SECRET_ID
[2021-04-20T16:26:05.367Z] + chmod 755 generate-build-data.sh
[2021-04-20T16:26:05.367Z] + ./generate-build-data.sh https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Library/go-sysinfo-mbp/PR-96/ https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Library/go-sysinfo-mbp/PR-96/runs/1 FAILURE 378208
[2021-04-20T16:26:05.617Z] INFO: curl https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Library/go-sysinfo-mbp/PR-96/runs/1/steps/?limit=10000 -o steps-info.json
[2021-04-20T16:26:06.960Z] INFO: curl https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Library/go-sysinfo-mbp/PR-96/runs/1/tests/?status=FAILED -o tests-errors.json

```

</p>
</details>



<!--COMMENT_GENERATED_WITH_ID_comment.id-->

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1bcf5b8..0ef8c29 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+- Add per-process network stats [#96](https://github.com/elastic/go-sysinfo/pull/96)
+
 ### Changed
 
 ### Deprecated
diff --git a/README.md b/README.md
index daaa573..408431e 100644
--- a/README.md
+++ b/README.md
@@ -51,3 +51,4 @@ that are implemented.
 | `OpenHandleCounter`    |        | x     |         |           |
 | `Seccomp`              |        | x     |         |           |
 | `Capabilities`         |        | x     |         |           |
+| `NetworkCounters`      |        | x     |         |           |
diff --git a/providers/aix/boottime_aix.go b/providers/aix/boottime_aix.go
index e867960..fee3428 100644
--- a/providers/aix/boottime_aix.go
+++ b/providers/aix/boottime_aix.go
@@ -74,5 +74,4 @@ func bootTime(filename string) (time.Time, error) {
 	}
 
 	return time.Time{}, errors.Wrap(err, "failed to get host uptime: no utmp record")
-
 }
diff --git a/providers/aix/defs_aix.go b/providers/aix/defs_aix.go
index 3537137..2178ae4 100644
--- a/providers/aix/defs_aix.go
+++ b/providers/aix/defs_aix.go
@@ -28,14 +28,16 @@ import "C"
 
 type prcred C.prcred_t
 
-type pstatus C.pstatus_t
-type prTimestruc64 C.pr_timestruc64_t
-type prSigset C.pr_sigset_t
-type fltset C.fltset_t
-type lwpstatus C.lwpstatus_t
-type prSiginfo64 C.pr_siginfo64_t
-type prStack64 C.pr_stack64_t
-type prSigaction64 C.struct_pr_sigaction64
-type prgregset C.prgregset_t
-type prfpregset C.prfpregset_t
-type pfamily C.pfamily_t
+type (
+	pstatus       C.pstatus_t
+	prTimestruc64 C.pr_timestruc64_t
+	prSigset      C.pr_sigset_t
+	fltset        C.fltset_t
+	lwpstatus     C.lwpstatus_t
+	prSiginfo64   C.pr_siginfo64_t
+	prStack64     C.pr_stack64_t
+	prSigaction64 C.struct_pr_sigaction64
+	prgregset     C.prgregset_t
+	prfpregset    C.prfpregset_t
+	pfamily       C.pfamily_t
+)
diff --git a/providers/aix/kernel_aix.go b/providers/aix/kernel_aix.go
index 8ba3252..3c05ea4 100644
--- a/providers/aix/kernel_aix.go
+++ b/providers/aix/kernel_aix.go
@@ -46,7 +46,6 @@ func getKernelVersion() (int, int, error) {
 		return 0, 0, errors.Wrap(err, "parsing kernel release")
 	}
 	return version, release, nil
-
 }
 
 // KernelVersion returns the version of AIX kernel
diff --git a/providers/aix/machineid_aix.go b/providers/aix/machineid_aix.go
index e96b4a4..3d02ddd 100644
--- a/providers/aix/machineid_aix.go
+++ b/providers/aix/machineid_aix.go
@@ -21,6 +21,7 @@ package aix
 #include <sys/utsname.h>
 */
 import "C"
+
 import (
 	"github.com/pkg/errors"
 )
diff --git a/providers/aix/process_aix.go b/providers/aix/process_aix.go
index 58d385a..cccb4bd 100644
--- a/providers/aix/process_aix.go
+++ b/providers/aix/process_aix.go
@@ -187,7 +187,6 @@ func (p *process) Info() (types.ProcessInfo, error) {
 	p.info.CWD = strings.TrimSuffix(cwd, "/")
 
 	return *p.info, nil
-
 }
 
 // Environment returns the environment of a process.
@@ -243,7 +242,6 @@ func (p *process) User() (types.UserInfo, error) {
 		EGID: strconv.Itoa(int(prcred.Egid)),
 		SGID: strconv.Itoa(int(prcred.Sgid)),
 	}, nil
-
 }
 
 // Memory returns the current memory usage of a process.
diff --git a/providers/aix/ztypes_aix_ppc64.go b/providers/aix/ztypes_aix_ppc64.go
index 118f2b9..20c6b24 100644
--- a/providers/aix/ztypes_aix_ppc64.go
+++ b/providers/aix/ztypes_aix_ppc64.go
@@ -61,17 +61,21 @@ type pstatus struct {
 	X_pad           [8]uint64
 	Lwp             lwpstatus
 }
+
 type prTimestruc64 struct {
 	Sec    int64
 	Nsec   int32
 	X__pad uint32
 }
+
 type prSigset struct {
 	Set [4]uint64
 }
+
 type fltset struct {
 	Set [4]uint64
 }
+
 type lwpstatus struct {
 	Lwpid    uint64
 	Flags    uint32
@@ -98,6 +102,7 @@ type lwpstatus struct {
 	Fpreg    prfpregset
 	Family   pfamily
 }
+
 type prSiginfo64 struct {
 	Signo   int32
 	Errno   int32
@@ -112,18 +117,21 @@ type prSiginfo64 struct {
 	Value   [8]byte
 	X__pad  [4]uint32
 }
+
 type prStack64 struct {
 	Sp     uint64
 	Size   uint64
 	Flags  int32
 	X__pad [5]int32
 }
+
 type prSigaction64 struct {
 	Union  [8]byte
 	Mask   prSigset
 	Flags  int32
 	X__pad [5]int32
 }
+
 type prgregset struct {
 	X__iar    uint64
 	X__msr    uint64
@@ -136,9 +144,11 @@ type prgregset struct {
 	X__gpr    [32]uint64
 	X__pad1   [8]uint64
 }
+
 type prfpregset struct {
 	X__fpr [32]float64
 }
+
 type pfamily struct {
 	Extoff  uint64
 	Extsize uint64
diff --git a/providers/linux/process_linux.go b/providers/linux/process_linux.go
index 3ea7fd8..10cb947 100644
--- a/providers/linux/process_linux.go
+++ b/providers/linux/process_linux.go
@@ -253,6 +253,29 @@ func (p *process) User() (types.UserInfo, error) {
 	return user, nil
 }
 
+// NetworkStats reports network stats for an individual PID.
+func (p *process) NetworkCounters() (*types.NetworkCountersInfo, error) {
+	snmpRaw, err := ioutil.ReadFile(p.path("net/snmp"))
+	if err != nil {
+		return nil, err
+	}
+	snmp, err := getNetSnmpStats(snmpRaw)
+	if err != nil {
+		return nil, err
+	}
+
+	netstatRaw, err := ioutil.ReadFile(p.path("net/netstat"))
+	if err != nil {
+		return nil, err
+	}
+	netstat, err := getNetstatStats(netstatRaw)
+	if err != nil {
+		return nil, err
+	}
+
+	return &types.NetworkCountersInfo{SNMP: snmp, Netstat: netstat}, nil
+}
+
 func ticksToDuration(ticks uint64) time.Duration {
 	seconds := float64(ticks) / float64(userHz) * float64(time.Second)
 	return time.Duration(int64(seconds))


Test patch:
diff --git a/providers/darwin/process_darwin_test.go b/providers/darwin/process_darwin_test.go
index 67fdf62..b23b251 100644
--- a/providers/darwin/process_darwin_test.go
+++ b/providers/darwin/process_darwin_test.go
@@ -28,8 +28,10 @@ import (
 	"github.com/elastic/go-sysinfo/internal/registry"
 )
 
-var _ registry.HostProvider = darwinSystem{}
-var _ registry.ProcessProvider = darwinSystem{}
+var (
+	_ registry.HostProvider    = darwinSystem{}
+	_ registry.ProcessProvider = darwinSystem{}
+)
 
 func TestKernProcInfo(t *testing.T) {
 	var p process
diff --git a/providers/linux/process_linux_test.go b/providers/linux/process_linux_test.go
index a6e5ed8..f545101 100644
--- a/providers/linux/process_linux_test.go
+++ b/providers/linux/process_linux_test.go
@@ -18,8 +18,35 @@
 package linux
 
 import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
 	"github.com/elastic/go-sysinfo/internal/registry"
+	"github.com/elastic/go-sysinfo/types"
 )
 
-var _ registry.HostProvider = linuxSystem{}
-var _ registry.ProcessProvider = linuxSystem{}
+var (
+	_ registry.HostProvider    = linuxSystem{}
+	_ registry.ProcessProvider = linuxSystem{}
+)
+
+func TestProcessNetstat(t *testing.T) {
+	proc, err := newLinuxSystem("").Self()
+	if err != nil {
+		t.Fatal(err)
+	}
+	procNetwork, ok := proc.(types.NetworkCounters)
+	if !ok {
+		t.Fatalf("error, cannot cast to types.NetworkCounters")
+	}
+	stats, err := procNetwork.NetworkCounters()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	assert.NotEmpty(t, stats.SNMP.ICMP, "ICMP")
+	assert.NotEmpty(t, stats.SNMP.IP, "IP")
+	assert.NotEmpty(t, stats.SNMP.TCP, "TCP")
+	assert.NotEmpty(t, stats.SNMP.UDP, "UDP")
+}
diff --git a/providers/windows/process_windows_test.go b/providers/windows/process_windows_test.go
index 5514a87..6808501 100644
--- a/providers/windows/process_windows_test.go
+++ b/providers/windows/process_windows_test.go
@@ -21,5 +21,7 @@ import (
 	"github.com/elastic/go-sysinfo/internal/registry"
 )
 
-var _ registry.HostProvider = windowsSystem{}
-var _ registry.ProcessProvider = windowsSystem{}
+var (
+	_ registry.HostProvider    = windowsSystem{}
+	_ registry.ProcessProvider = windowsSystem{}
+)
diff --git a/system_test.go b/system_test.go
index b0a3550..0630a61 100644
--- a/system_test.go
+++ b/system_test.go
@@ -45,13 +45,13 @@ type ProcessFeatures struct {
 }
 
 var expectedProcessFeatures = map[string]*ProcessFeatures{
-	"darwin": &ProcessFeatures{
+	"darwin": {
 		ProcessInfo:          true,
 		Environment:          true,
 		OpenHandleEnumerator: false,
 		OpenHandleCounter:    false,
 	},
-	"linux": &ProcessFeatures{
+	"linux": {
 		ProcessInfo:          true,
 		Environment:          true,
 		OpenHandleEnumerator: true,
@@ -59,12 +59,12 @@ var expectedProcessFeatures = map[string]*ProcessFeatures{
 		Seccomp:              true,
 		Capabilities:         true,
 	},
-	"windows": &ProcessFeatures{
+	"windows": {
 		ProcessInfo:          true,
 		OpenHandleEnumerator: false,
 		OpenHandleCounter:    true,
 	},
-	"aix": &ProcessFeatures{
+	"aix": {
 		ProcessInfo:          true,
 		Environment:          true,
 		OpenHandleEnumerator: false,