17
17
package collector
18
18
19
19
import (
20
- "errors"
21
20
"fmt"
22
21
"log/slog"
23
22
"unsafe"
@@ -33,21 +32,68 @@ import (
33
32
#include <netinet/tcp.h>
34
33
#include <netinet/tcp_var.h>
35
34
#include <netinet/udp.h>
35
+ #include <netinet/udp_var.h>
36
36
*/
37
37
import "C"
38
38
39
39
var (
40
+ // TCP metrics
40
41
bsdNetstatTcpSendPacketsTotal = prometheus .NewDesc (
41
42
prometheus .BuildFQName (namespace , "netstat" , "tcp_transmit_packets_total" ),
42
43
"TCP packets sent" ,
43
44
nil , nil ,
44
45
)
45
-
46
46
bsdNetstatTcpRecvPacketsTotal = prometheus .NewDesc (
47
47
prometheus .BuildFQName (namespace , "netstat" , "tcp_receive_packets_total" ),
48
48
"TCP packets received" ,
49
49
nil , nil ,
50
50
)
51
+ bsdNetstatTcpConnectionAttempts = prometheus .NewDesc (
52
+ prometheus .BuildFQName (namespace , "netstat" , "tcp_connection_attempts_total" ),
53
+ "Number of times TCP connections have been initiated" ,
54
+ nil , nil ,
55
+ )
56
+ bsdNetstatTcpConnectionAccepts = prometheus .NewDesc (
57
+ prometheus .BuildFQName (namespace , "netstat" , "tcp_connection_accepts_total" ),
58
+ "Number of times TCP connections have made it to established state" ,
59
+ nil , nil ,
60
+ )
61
+ bsdNetstatTcpConnectionDrops = prometheus .NewDesc (
62
+ prometheus .BuildFQName (namespace , "netstat" , "tcp_connection_drops_total" ),
63
+ "Number of dropped TCP connections" ,
64
+ nil , nil ,
65
+ )
66
+ bsdNetstatTcpRetransmitPackets = prometheus .NewDesc (
67
+ prometheus .BuildFQName (namespace , "netstat" , "tcp_retransmit_packets_total" ),
68
+ "Number of TCP data packets retransmitted" ,
69
+ nil , nil ,
70
+ )
71
+ // UDP metrics
72
+ bsdNetstatUdpSendPacketsTotal = prometheus .NewDesc (
73
+ prometheus .BuildFQName (namespace , "netstat" , "udp_transmit_packets_total" ),
74
+ "UDP packets sent" ,
75
+ nil , nil ,
76
+ )
77
+ bsdNetstatUdpRecvPacketsTotal = prometheus .NewDesc (
78
+ prometheus .BuildFQName (namespace , "netstat" , "udp_receive_packets_total" ),
79
+ "UDP packets received" ,
80
+ nil , nil ,
81
+ )
82
+ bsdNetstatUdpHeaderDrops = prometheus .NewDesc (
83
+ prometheus .BuildFQName (namespace , "netstat" , "udp_header_drops_total" ),
84
+ "Number of UDP packets dropped due to invalid header" ,
85
+ nil , nil ,
86
+ )
87
+ bsdNetstatUdpBadChecksum = prometheus .NewDesc (
88
+ prometheus .BuildFQName (namespace , "netstat" , "udp_bad_checksum_total" ),
89
+ "Number of UDP packets dropped due to bad checksum" ,
90
+ nil , nil ,
91
+ )
92
+ bsdNetstatUdpNoPort = prometheus .NewDesc (
93
+ prometheus .BuildFQName (namespace , "netstat" , "udp_no_port_total" ),
94
+ "Number of UDP packets to port with no listener" ,
95
+ nil , nil ,
96
+ )
51
97
)
52
98
53
99
type netStatCollector struct {
@@ -76,18 +122,16 @@ func getData(queryString string) ([]byte, error) {
76
122
fmt .Println ("Error:" , err )
77
123
return nil , err
78
124
}
79
-
80
- if len (data ) < int (unsafe .Sizeof (C.struct_tcpstat {})) {
81
- return nil , errors .New ("Data Size mismatch" )
82
- }
83
125
return data , nil
84
126
}
85
127
86
128
func (c * netStatCollector ) Update (ch chan <- prometheus.Metric ) error {
87
-
88
129
tcpData , err := getData ("net.inet.tcp.stats" )
89
130
if err != nil {
90
- return err
131
+ return fmt .Errorf ("failed to get TCP stats: %w" , err )
132
+ }
133
+ if len (tcpData ) < int (unsafe .Sizeof (C.struct_tcpstat {})) {
134
+ return fmt .Errorf ("TCP data size mismatch: got %d, want >= %d" , len (tcpData ), unsafe .Sizeof (C.struct_tcpstat {}))
91
135
}
92
136
93
137
tcpStats := * (* C .struct_tcpstat )(unsafe .Pointer (& tcpData [0 ]))
@@ -97,12 +141,67 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
97
141
prometheus .CounterValue ,
98
142
float64 (tcpStats .tcps_sndtotal ),
99
143
)
100
-
101
144
ch <- prometheus .MustNewConstMetric (
102
145
bsdNetstatTcpRecvPacketsTotal ,
103
146
prometheus .CounterValue ,
104
147
float64 (tcpStats .tcps_rcvtotal ),
105
148
)
149
+ ch <- prometheus .MustNewConstMetric (
150
+ bsdNetstatTcpConnectionAttempts ,
151
+ prometheus .CounterValue ,
152
+ float64 (tcpStats .tcps_connattempt ),
153
+ )
154
+ ch <- prometheus .MustNewConstMetric (
155
+ bsdNetstatTcpConnectionAccepts ,
156
+ prometheus .CounterValue ,
157
+ float64 (tcpStats .tcps_accepts ),
158
+ )
159
+ ch <- prometheus .MustNewConstMetric (
160
+ bsdNetstatTcpConnectionDrops ,
161
+ prometheus .CounterValue ,
162
+ float64 (tcpStats .tcps_drops ),
163
+ )
164
+ ch <- prometheus .MustNewConstMetric (
165
+ bsdNetstatTcpRetransmitPackets ,
166
+ prometheus .CounterValue ,
167
+ float64 (tcpStats .tcps_sndrexmitpack ),
168
+ )
169
+
170
+ udpData , err := getData ("net.inet.udp.stats" )
171
+ if err != nil {
172
+ return fmt .Errorf ("failed to get UDP stats: %w" , err )
173
+ }
174
+ if len (udpData ) < int (unsafe .Sizeof (C.struct_udpstat {})) {
175
+ return fmt .Errorf ("UDP data size mismatch: got %d, want >= %d" , len (udpData ), unsafe .Sizeof (C.struct_udpstat {}))
176
+ }
177
+
178
+ udpStats := * (* C .struct_udpstat )(unsafe .Pointer (& udpData [0 ]))
179
+
180
+ ch <- prometheus .MustNewConstMetric (
181
+ bsdNetstatUdpSendPacketsTotal ,
182
+ prometheus .CounterValue ,
183
+ float64 (udpStats .udps_opackets ),
184
+ )
185
+ ch <- prometheus .MustNewConstMetric (
186
+ bsdNetstatUdpRecvPacketsTotal ,
187
+ prometheus .CounterValue ,
188
+ float64 (udpStats .udps_ipackets ),
189
+ )
190
+ ch <- prometheus .MustNewConstMetric (
191
+ bsdNetstatUdpHeaderDrops ,
192
+ prometheus .CounterValue ,
193
+ float64 (udpStats .udps_hdrops ),
194
+ )
195
+ ch <- prometheus .MustNewConstMetric (
196
+ bsdNetstatUdpBadChecksum ,
197
+ prometheus .CounterValue ,
198
+ float64 (udpStats .udps_badsum ),
199
+ )
200
+ ch <- prometheus .MustNewConstMetric (
201
+ bsdNetstatUdpNoPort ,
202
+ prometheus .CounterValue ,
203
+ float64 (udpStats .udps_noport ),
204
+ )
106
205
107
206
return nil
108
207
}
0 commit comments