@@ -50,10 +50,13 @@ type (
50
50
// UsedSockets shows the total number of parsed lines representing the
51
51
// number of used sockets.
52
52
UsedSockets uint64
53
+ // Drops shows the total number of dropped packets of all UPD sockets.
54
+ Drops * uint64
53
55
}
54
56
55
57
// netIPSocketLine represents the fields parsed from a single line
56
58
// in /proc/net/{t,u}dp{,6}. Fields which are not used by IPSocket are skipped.
59
+ // Drops is non-nil for udp{,6}, but nil for tcp{,6}.
57
60
// For the proc file format details, see https://linux.die.net/man/5/proc.
58
61
netIPSocketLine struct {
59
62
Sl uint64
66
69
RxQueue uint64
67
70
UID uint64
68
71
Inode uint64
72
+ Drops * uint64
69
73
}
70
74
)
71
75
@@ -77,13 +81,14 @@ func newNetIPSocket(file string) (NetIPSocket, error) {
77
81
defer f .Close ()
78
82
79
83
var netIPSocket NetIPSocket
84
+ isUDP := strings .Contains (file , "udp" )
80
85
81
86
lr := io .LimitReader (f , readLimit )
82
87
s := bufio .NewScanner (lr )
83
88
s .Scan () // skip first line with headers
84
89
for s .Scan () {
85
90
fields := strings .Fields (s .Text ())
86
- line , err := parseNetIPSocketLine (fields )
91
+ line , err := parseNetIPSocketLine (fields , isUDP )
87
92
if err != nil {
88
93
return nil , err
89
94
}
@@ -104,19 +109,25 @@ func newNetIPSocketSummary(file string) (*NetIPSocketSummary, error) {
104
109
defer f .Close ()
105
110
106
111
var netIPSocketSummary NetIPSocketSummary
112
+ var udpPacketDrops uint64
113
+ isUDP := strings .Contains (file , "udp" )
107
114
108
115
lr := io .LimitReader (f , readLimit )
109
116
s := bufio .NewScanner (lr )
110
117
s .Scan () // skip first line with headers
111
118
for s .Scan () {
112
119
fields := strings .Fields (s .Text ())
113
- line , err := parseNetIPSocketLine (fields )
120
+ line , err := parseNetIPSocketLine (fields , isUDP )
114
121
if err != nil {
115
122
return nil , err
116
123
}
117
124
netIPSocketSummary .TxQueueLength += line .TxQueue
118
125
netIPSocketSummary .RxQueueLength += line .RxQueue
119
126
netIPSocketSummary .UsedSockets ++
127
+ if isUDP {
128
+ udpPacketDrops += * line .Drops
129
+ netIPSocketSummary .Drops = & udpPacketDrops
130
+ }
120
131
}
121
132
if err := s .Err (); err != nil {
122
133
return nil , err
@@ -149,7 +160,7 @@ func parseIP(hexIP string) (net.IP, error) {
149
160
}
150
161
151
162
// parseNetIPSocketLine parses a single line, represented by a list of fields.
152
- func parseNetIPSocketLine (fields []string ) (* netIPSocketLine , error ) {
163
+ func parseNetIPSocketLine (fields []string , isUDP bool ) (* netIPSocketLine , error ) {
153
164
line := & netIPSocketLine {}
154
165
if len (fields ) < 10 {
155
166
return nil , fmt .Errorf (
@@ -224,5 +235,14 @@ func parseNetIPSocketLine(fields []string) (*netIPSocketLine, error) {
224
235
return nil , fmt .Errorf ("%s: Cannot parse inode value in %q: %w" , ErrFileParse , line .Inode , err )
225
236
}
226
237
238
+ // drops
239
+ if isUDP {
240
+ drops , err := strconv .ParseUint (fields [12 ], 0 , 64 )
241
+ if err != nil {
242
+ return nil , fmt .Errorf ("%s: Cannot parse drops value in %q: %w" , ErrFileParse , drops , err )
243
+ }
244
+ line .Drops = & drops
245
+ }
246
+
227
247
return line , nil
228
248
}
0 commit comments