1717package collector
1818
1919import (
20- "errors"
2120 "fmt"
2221 "log/slog"
2322 "unsafe"
@@ -33,21 +32,68 @@ import (
3332#include <netinet/tcp.h>
3433#include <netinet/tcp_var.h>
3534#include <netinet/udp.h>
35+ #include <netinet/udp_var.h>
3636*/
3737import "C"
3838
3939var (
40+ // TCP metrics
4041 bsdNetstatTcpSendPacketsTotal = prometheus .NewDesc (
4142 prometheus .BuildFQName (namespace , "netstat" , "tcp_transmit_packets_total" ),
4243 "TCP packets sent" ,
4344 nil , nil ,
4445 )
45-
4646 bsdNetstatTcpRecvPacketsTotal = prometheus .NewDesc (
4747 prometheus .BuildFQName (namespace , "netstat" , "tcp_receive_packets_total" ),
4848 "TCP packets received" ,
4949 nil , nil ,
5050 )
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+ )
5197)
5298
5399type netStatCollector struct {
@@ -76,18 +122,16 @@ func getData(queryString string) ([]byte, error) {
76122 fmt .Println ("Error:" , err )
77123 return nil , err
78124 }
79-
80- if len (data ) < int (unsafe .Sizeof (C.struct_tcpstat {})) {
81- return nil , errors .New ("Data Size mismatch" )
82- }
83125 return data , nil
84126}
85127
86128func (c * netStatCollector ) Update (ch chan <- prometheus.Metric ) error {
87-
88129 tcpData , err := getData ("net.inet.tcp.stats" )
89130 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 {}))
91135 }
92136
93137 tcpStats := * (* C .struct_tcpstat )(unsafe .Pointer (& tcpData [0 ]))
@@ -97,12 +141,67 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
97141 prometheus .CounterValue ,
98142 float64 (tcpStats .tcps_sndtotal ),
99143 )
100-
101144 ch <- prometheus .MustNewConstMetric (
102145 bsdNetstatTcpRecvPacketsTotal ,
103146 prometheus .CounterValue ,
104147 float64 (tcpStats .tcps_rcvtotal ),
105148 )
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+ )
106205
107206 return nil
108207}
0 commit comments