Skip to content

Commit

Permalink
Move to uint64 for procnet, deal with MaxConn (#75)
Browse files Browse the repository at this point in the history
* Move to uint64, deal with MaxConn

* changelog
  • Loading branch information
fearful-symmetry authored Jan 11, 2020
1 parent bd71698 commit 07a209a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

### Changed
- Convert NetworkCountersInfo maps to uint64 [#75](https://github.com/elastic/go-sysinfo/pull/75)

### Deprecated

Expand Down
32 changes: 24 additions & 8 deletions providers/linux/procnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
)

// fillStruct is some reflection work that can dynamically fill one of our tagged `netstat` structs with netstat data
func fillStruct(str interface{}, data map[string]map[string]int64) {
func fillStruct(str interface{}, data map[string]map[string]uint64) {
val := reflect.ValueOf(str).Elem()
typ := reflect.TypeOf(str).Elem()

Expand All @@ -44,28 +44,44 @@ func fillStruct(str interface{}, data map[string]map[string]int64) {
}

// parseEntry parses two lines from the net files, the first line being keys, the second being values
func parseEntry(line1, line2 string) (map[string]int64, error) {
func parseEntry(line1, line2 string) (map[string]uint64, error) {
keyArr := strings.Split(strings.TrimSpace(line1), " ")
valueArr := strings.Split(strings.TrimSpace(line2), " ")

if len(keyArr) != len(valueArr) {
return nil, errors.New("key and value lines are mismatched")
}

counters := make(map[string]int64, len(valueArr))
counters := make(map[string]uint64, len(valueArr))
for iter, value := range valueArr {
parsed, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "error parsing string to int in line: %#v", valueArr)

// This if-else block is to deal with the MaxConn value in SNMP,
// which is a signed value according to RFC2012.
// This library emulates the behavior of the kernel: store all values as a uint, then cast to a signed value for printing
// Users of this library need to be aware that this value should be printed as a signed int or hex value to make it useful.
var parsed uint64
var err error
if strings.Contains(value, "-") {
signedParsed, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "error parsing string to int in line: %#v", valueArr)
}
parsed = uint64(signedParsed)
} else {
parsed, err = strconv.ParseUint(value, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "error parsing string to int in line: %#v", valueArr)
}
}

counters[keyArr[iter]] = parsed
}
return counters, nil
}

// parseNetFile parses an entire file, and returns a 2D map, representing how files are sorted by protocol
func parseNetFile(body string) (map[string]map[string]int64, error) {
fileMetrics := make(map[string]map[string]int64)
func parseNetFile(body string) (map[string]map[string]uint64, error) {
fileMetrics := make(map[string]map[string]uint64)
bodySplit := strings.Split(strings.TrimSpace(body), "\n")
// There should be an even number of lines. If not, something is wrong.
if len(bodySplit)%2 != 0 {
Expand Down
3 changes: 2 additions & 1 deletion providers/linux/procnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ UdpLite: 0 0 0 0 0 0 0 0`
fillStruct(&testOut, mapStr)

assert.NotEmpty(t, testOut.IP)
assert.Equal(t, int64(16755), testOut.UDP["InDatagrams"])
assert.Equal(t, uint64(16755), testOut.UDP["InDatagrams"])
assert.Equal(t, uint64(0xffffffffffffffff), testOut.TCP["MaxConn"])
}
17 changes: 9 additions & 8 deletions types/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,20 @@ type NetworkCounters interface {
}

// SNMP represents the data from /proc/net/snmp
// Note that according to RFC 2012,TCP.MaxConn, if present, is a signed value and should be cast to int64
type SNMP struct {
IP map[string]int64 `json:"ip" netstat:"Ip"`
ICMP map[string]int64 `json:"icmp" netstat:"Icmp"`
ICMPMsg map[string]int64 `json:"icmp_msg" netstat:"IcmpMsg"`
TCP map[string]int64 `json:"tcp" netstat:"Tcp"`
UDP map[string]int64 `json:"udp" netstat:"Udp"`
UDPLite map[string]int64 `json:"udp_lite" netstat:"UdpLite"`
IP map[string]uint64 `json:"ip" netstat:"Ip"`
ICMP map[string]uint64 `json:"icmp" netstat:"Icmp"`
ICMPMsg map[string]uint64 `json:"icmp_msg" netstat:"IcmpMsg"`
TCP map[string]uint64 `json:"tcp" netstat:"Tcp"`
UDP map[string]uint64 `json:"udp" netstat:"Udp"`
UDPLite map[string]uint64 `json:"udp_lite" netstat:"UdpLite"`
}

// Netstat represents the data from /proc/net/netstat
type Netstat struct {
TCPExt map[string]int64 `json:"tcp_ext" netstat:"TcpExt"`
IPExt map[string]int64 `json:"ip_ext" netstat:"IpExt"`
TCPExt map[string]uint64 `json:"tcp_ext" netstat:"TcpExt"`
IPExt map[string]uint64 `json:"ip_ext" netstat:"IpExt"`
}

// NetworkCountersInfo represents available network counters from /proc/net
Expand Down

0 comments on commit 07a209a

Please sign in to comment.