...
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package procfs
15
16 import (
17 "bufio"
18 "bytes"
19 "fmt"
20 "io"
21 "strings"
22
23 "github.com/prometheus/procfs/internal/util"
24 )
25
26
27
28 type NetSockstat struct {
29
30 Used *int
31 Protocols []NetSockstatProtocol
32 }
33
34
35
36
37 type NetSockstatProtocol struct {
38 Protocol string
39 InUse int
40 Orphan *int
41 TW *int
42 Alloc *int
43 Mem *int
44 Memory *int
45 }
46
47
48 func (fs FS) NetSockstat() (*NetSockstat, error) {
49 return readSockstat(fs.proc.Path("net", "sockstat"))
50 }
51
52
53
54
55
56 func (fs FS) NetSockstat6() (*NetSockstat, error) {
57 return readSockstat(fs.proc.Path("net", "sockstat6"))
58 }
59
60
61 func readSockstat(name string) (*NetSockstat, error) {
62
63 b, err := util.ReadFileNoStat(name)
64 if err != nil {
65
66
67 return nil, err
68 }
69
70 stat, err := parseSockstat(bytes.NewReader(b))
71 if err != nil {
72 return nil, fmt.Errorf("%s: sockstats from %q: %w", ErrFileRead, name, err)
73 }
74
75 return stat, nil
76 }
77
78
79 func parseSockstat(r io.Reader) (*NetSockstat, error) {
80 var stat NetSockstat
81 s := bufio.NewScanner(r)
82 for s.Scan() {
83
84 fields := strings.Split(s.Text(), " ")
85 if len(fields) < 3 {
86 return nil, fmt.Errorf("%w: Malformed sockstat line: %q", ErrFileParse, s.Text())
87 }
88
89
90 kvs, err := parseSockstatKVs(fields[1:])
91 if err != nil {
92 return nil, fmt.Errorf("%s: sockstat key/value pairs from %q: %w", ErrFileParse, s.Text(), err)
93 }
94
95
96 proto := strings.TrimSuffix(fields[0], ":")
97 switch proto {
98 case "sockets":
99
100
101 used := kvs["used"]
102 stat.Used = &used
103 default:
104
105 nsp := parseSockstatProtocol(kvs)
106 nsp.Protocol = proto
107 stat.Protocols = append(stat.Protocols, nsp)
108 }
109 }
110
111 if err := s.Err(); err != nil {
112 return nil, err
113 }
114
115 return &stat, nil
116 }
117
118
119 func parseSockstatKVs(kvs []string) (map[string]int, error) {
120 if len(kvs)%2 != 0 {
121 return nil, fmt.Errorf("%w:: Odd number of fields in key/value pairs %q", ErrFileParse, kvs)
122 }
123
124
125 out := make(map[string]int, len(kvs)/2)
126 for i := 0; i < len(kvs); i += 2 {
127 vp := util.NewValueParser(kvs[i+1])
128 out[kvs[i]] = vp.Int()
129
130 if err := vp.Err(); err != nil {
131 return nil, err
132 }
133 }
134
135 return out, nil
136 }
137
138
139 func parseSockstatProtocol(kvs map[string]int) NetSockstatProtocol {
140 var nsp NetSockstatProtocol
141 for k, v := range kvs {
142
143
144 v := v
145 switch k {
146 case "inuse":
147 nsp.InUse = v
148 case "orphan":
149 nsp.Orphan = &v
150 case "tw":
151 nsp.TW = &v
152 case "alloc":
153 nsp.Alloc = &v
154 case "mem":
155 nsp.Mem = &v
156 case "memory":
157 nsp.Memory = &v
158 }
159 }
160
161 return nsp
162 }
163
View as plain text