Skip to content

Commit

Permalink
remove mapstructure
Browse files Browse the repository at this point in the history
  • Loading branch information
nikakis committed Mar 4, 2022
1 parent 3d753b0 commit dc5e963
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 82 deletions.
50 changes: 24 additions & 26 deletions proc_netstat.go
Expand Up @@ -18,10 +18,10 @@ import (
"bytes"
"fmt"
"io"
"reflect"
"strconv"
"strings"

"github.com/mitchellh/mapstructure"
"github.com/prometheus/procfs/internal/util"
)

Expand Down Expand Up @@ -171,32 +171,21 @@ type IpExt struct {

func (p Proc) Netstat() (ProcNetstat, error) {
filename := p.path("net/netstat")
procNetstat := ProcNetstat{PID: p.PID}

data, err := util.ReadFileNoStat(filename)
if err != nil {
return procNetstat, err
}

netStats, err := parseNetstat(bytes.NewReader(data), filename)
if err != nil {
return procNetstat, err
}

mapStructureErr := mapstructure.Decode(netStats, &procNetstat)
if mapStructureErr != nil {
return procNetstat, mapStructureErr
return ProcNetstat{PID: p.PID}, err
}

return procNetstat, nil
procNetstat, err := parseNetstat(bytes.NewReader(data), filename)
procNetstat.PID = p.PID
return procNetstat, err
}

// parseNetstat parses the metrics from proc/<pid>/net/netstat file
// and returns a map contains those metrics (e.g. {"TcpExt": {"SyncookiesSent": 0}}).
func parseNetstat(r io.Reader, fileName string) (map[string]map[string]float64, error) {
// and returns a ProcNetstat structure.
func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) {
var (
netStats = map[string]map[string]float64{}
scanner = bufio.NewScanner(r)
procNetstat = ProcNetstat{}
)

for scanner.Scan() {
Expand All @@ -205,19 +194,28 @@ func parseNetstat(r io.Reader, fileName string) (map[string]map[string]float64,
valueParts := strings.Split(scanner.Text(), " ")
// Remove trailing :.
protocol := nameParts[0][:len(nameParts[0])-1]
netStats[protocol] = map[string]float64{}
if len(nameParts) != len(valueParts) {
return nil, fmt.Errorf("mismatch field count mismatch in %s: %s",
return ProcNetstat{}, fmt.Errorf("mismatch field count mismatch in %s: %s",
fileName, protocol)
}
for i := 1; i < len(nameParts); i++ {
var err error
netStats[protocol][nameParts[i]], err = strconv.ParseFloat(valueParts[i], 64)
value, err := strconv.ParseFloat(valueParts[i], 64)
if err != nil {
return nil, err
return procNetstat, err
}
key := nameParts[i]

var s interface{}
if protocol == "TcpExt" {
s = &procNetstat.TcpExt
}
if protocol == "IpExt" {
s = &procNetstat.IpExt
}
structValue := reflect.ValueOf(s).Elem()
structFieldValue := structValue.FieldByName(key)
structFieldValue.Set(reflect.ValueOf(value))
}
}

return netStats, scanner.Err()
return procNetstat, scanner.Err()
}
60 changes: 35 additions & 25 deletions proc_snmp.go
Expand Up @@ -18,10 +18,10 @@ import (
"bytes"
"fmt"
"io"
"reflect"
"strconv"
"strings"

"github.com/mitchellh/mapstructure"
"github.com/prometheus/procfs/internal/util"
)

Expand Down Expand Up @@ -136,32 +136,21 @@ type UdpLite struct {

func (p Proc) Snmp() (ProcSnmp, error) {
filename := p.path("net/snmp")
procSnmp := ProcSnmp{PID: p.PID}

data, err := util.ReadFileNoStat(filename)
if err != nil {
return procSnmp, err
}

netStats, err := parseSnmp(bytes.NewReader(data), filename)
if err != nil {
return procSnmp, err
return ProcSnmp{PID: p.PID}, err
}

mapStructureErr := mapstructure.Decode(netStats, &procSnmp)
if mapStructureErr != nil {
return procSnmp, mapStructureErr
}

return procSnmp, nil
procSnmp, err := parseSnmp(bytes.NewReader(data), filename)
procSnmp.PID = p.PID
return procSnmp, err
}

// parseSnmp parses the metrics from proc/<pid>/net/snmp file
// and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}).
func parseSnmp(r io.Reader, fileName string) (map[string]map[string]float64, error) {
func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) {
var (
netStats = map[string]map[string]float64{}
scanner = bufio.NewScanner(r)
procSnmp = ProcSnmp{}
)

for scanner.Scan() {
Expand All @@ -170,19 +159,40 @@ func parseSnmp(r io.Reader, fileName string) (map[string]map[string]float64, err
valueParts := strings.Split(scanner.Text(), " ")
// Remove trailing :.
protocol := nameParts[0][:len(nameParts[0])-1]
netStats[protocol] = map[string]float64{}
if len(nameParts) != len(valueParts) {
return nil, fmt.Errorf("mismatch field count mismatch in %s: %s",
return ProcSnmp{}, fmt.Errorf("mismatch field count mismatch in %s: %s",
fileName, protocol)
}
for i := 1; i < len(nameParts); i++ {
var err error
netStats[protocol][nameParts[i]], err = strconv.ParseFloat(valueParts[i], 64)
value, err := strconv.ParseFloat(valueParts[i], 64)
if err != nil {
return nil, err
return procSnmp, err
}
key := nameParts[i]

var s interface{}
if protocol == "Ip" {
s = &procSnmp.Ip
}
if protocol == "Icmp" {
s = &procSnmp.Icmp
}
if protocol == "IcmpMsg" {
s = &procSnmp.IcmpMsg
}
if protocol == "Tcp" {
s = &procSnmp.Tcp
}
if protocol == "Udp" {
s = &procSnmp.Udp
}
if protocol == "UdpLite" {
s = &procSnmp.UdpLite
}
structValue := reflect.ValueOf(s).Elem()
structFieldValue := structValue.FieldByName(key)
structFieldValue.Set(reflect.ValueOf(value))
}
}

return netStats, scanner.Err()
return procSnmp, scanner.Err()
}
60 changes: 30 additions & 30 deletions proc_snmp6.go
Expand Up @@ -19,10 +19,10 @@ import (
"errors"
"io"
"os"
"reflect"
"strconv"
"strings"

"github.com/mitchellh/mapstructure"
"github.com/prometheus/procfs/internal/util"
)

Expand All @@ -33,7 +33,7 @@ type ProcSnmp6 struct {
Ip6
Icmp6
Udp6
Udp6Lite
UdpLite6
}

type Ip6 struct {
Expand Down Expand Up @@ -129,7 +129,7 @@ type Udp6 struct {
IgnoredMulti float64
}

type Udp6Lite struct {
type UdpLite6 struct {
InDatagrams float64
NoPorts float64
InErrors float64
Expand All @@ -141,39 +141,28 @@ type Udp6Lite struct {

func (p Proc) Snmp6() (ProcSnmp6, error) {
filename := p.path("net/snmp6")
procSnmp6 := ProcSnmp6{PID: p.PID}

data, err := util.ReadFileNoStat(filename)
if err != nil {
// On systems with IPv6 disabled, this file won't exist.
// Do nothing.
if errors.Is(err, os.ErrNotExist) {
return procSnmp6, nil
return ProcSnmp6{PID: p.PID}, nil
}

return procSnmp6, err
}

netStats, err := parseSNMP6Stats(bytes.NewReader(data))
if err != nil {
return procSnmp6, err
return ProcSnmp6{PID: p.PID}, err
}

mapStructureErr := mapstructure.Decode(netStats, &procSnmp6)
if mapStructureErr != nil {
return procSnmp6, mapStructureErr
}

return procSnmp6, nil

procSnmp6, err := parseSNMP6Stats(bytes.NewReader(data))
procSnmp6.PID = p.PID
return procSnmp6, err
}

// parseSnmp6 parses the metrics from proc/<pid>/net/snmp6 file
// and returns a map contains those metrics.
func parseSNMP6Stats(r io.Reader) (map[string]map[string]float64, error) {
func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) {
var (
netStats = map[string]map[string]float64{}
scanner = bufio.NewScanner(r)
procSnmp6 = ProcSnmp6{}
)

for scanner.Scan() {
Expand All @@ -184,17 +173,28 @@ func parseSNMP6Stats(r io.Reader) (map[string]map[string]float64, error) {
// Expect to have "6" in metric name, skip line otherwise
if sixIndex := strings.Index(stat[0], "6"); sixIndex != -1 {
protocol := stat[0][:sixIndex+1]
name := stat[0][sixIndex+1:]
if _, present := netStats[protocol]; !present {
netStats[protocol] = map[string]float64{}
}
var err error
netStats[protocol][name], err = strconv.ParseFloat(stat[1], 64)
key := stat[0][sixIndex+1:]
value, err := strconv.ParseFloat(stat[1], 64)
if err != nil {
return nil, err
return procSnmp6, err
}
var s interface{}
if protocol == "Ip6" {
s = &procSnmp6.Ip6
}
if protocol == "Icmp6" {
s = &procSnmp6.Icmp6
}
if protocol == "Udp6" {
s = &procSnmp6.Udp6
}
if protocol == "UdpLite6" {
s = &procSnmp6.UdpLite6
}
structValue := reflect.ValueOf(s).Elem()
structFieldValue := structValue.FieldByName(key)
structFieldValue.Set(reflect.ValueOf(value))
}
}

return netStats, scanner.Err()
return procSnmp6, scanner.Err()
}
2 changes: 1 addition & 1 deletion proc_snmp6_test.go
Expand Up @@ -25,7 +25,7 @@ func TestProcSnmp6(t *testing.T) {
{name: "Ip6InOctets", want: 113479132, have: procSnmp6.Ip6.InOctets},
{name: "Icmp6InMsgs", want: 142, have: procSnmp6.Icmp6.InMsgs},
{name: "Udp6InDatagrams", want: 2016, have: procSnmp6.Udp6.InDatagrams},
{name: "UdpLite6InDatagrams", want: 0, have: procSnmp6.Udp6Lite.InDatagrams},
{name: "UdpLite6InDatagrams", want: 0, have: procSnmp6.UdpLite6.InDatagrams},
} {
if test.want != test.have {
t.Errorf("want %s %f, have %f", test.name, test.want, test.have)
Expand Down

0 comments on commit dc5e963

Please sign in to comment.