|
|
|
|
@ -16,7 +16,6 @@ |
|
|
|
|
package collector |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"log/slog" |
|
|
|
|
"unsafe" |
|
|
|
|
@ -32,21 +31,68 @@ import ( |
|
|
|
|
#include <netinet/tcp.h> |
|
|
|
|
#include <netinet/tcp_var.h> |
|
|
|
|
#include <netinet/udp.h> |
|
|
|
|
#include <netinet/udp_var.h> |
|
|
|
|
*/ |
|
|
|
|
import "C" |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
// TCP metrics
|
|
|
|
|
bsdNetstatTcpSendPacketsTotal = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "tcp_transmit_packets_total"), |
|
|
|
|
"TCP packets sent", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
bsdNetstatTcpRecvPacketsTotal = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "tcp_receive_packets_total"), |
|
|
|
|
"TCP packets received", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatTcpConnectionAttempts = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "tcp_connection_attempts_total"), |
|
|
|
|
"Number of times TCP connections have been initiated", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatTcpConnectionAccepts = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "tcp_connection_accepts_total"), |
|
|
|
|
"Number of times TCP connections have made it to established state", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatTcpConnectionDrops = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "tcp_connection_drops_total"), |
|
|
|
|
"Number of dropped TCP connections", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatTcpRetransmitPackets = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "tcp_retransmit_packets_total"), |
|
|
|
|
"Number of TCP data packets retransmitted", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
// UDP metrics
|
|
|
|
|
bsdNetstatUdpSendPacketsTotal = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "udp_transmit_packets_total"), |
|
|
|
|
"UDP packets sent", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatUdpRecvPacketsTotal = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "udp_receive_packets_total"), |
|
|
|
|
"UDP packets received", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatUdpHeaderDrops = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "udp_header_drops_total"), |
|
|
|
|
"Number of UDP packets dropped due to invalid header", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatUdpBadChecksum = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "udp_bad_checksum_total"), |
|
|
|
|
"Number of UDP packets dropped due to bad checksum", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
bsdNetstatUdpNoPort = prometheus.NewDesc( |
|
|
|
|
prometheus.BuildFQName(namespace, "netstat", "udp_no_port_total"), |
|
|
|
|
"Number of UDP packets to port with no listener", |
|
|
|
|
nil, nil, |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type netStatCollector struct { |
|
|
|
|
@ -75,18 +121,16 @@ func getData(queryString string) ([]byte, error) { |
|
|
|
|
fmt.Println("Error:", err) |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if len(data) < int(unsafe.Sizeof(C.struct_tcpstat{})) { |
|
|
|
|
return nil, errors.New("Data Size mismatch") |
|
|
|
|
} |
|
|
|
|
return data, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error { |
|
|
|
|
|
|
|
|
|
tcpData, err := getData("net.inet.tcp.stats") |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
return fmt.Errorf("failed to get TCP stats: %w", err) |
|
|
|
|
} |
|
|
|
|
if len(tcpData) < int(unsafe.Sizeof(C.struct_tcpstat{})) { |
|
|
|
|
return fmt.Errorf("TCP data size mismatch: got %d, want >= %d", len(tcpData), unsafe.Sizeof(C.struct_tcpstat{})) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tcpStats := *(*C.struct_tcpstat)(unsafe.Pointer(&tcpData[0])) |
|
|
|
|
@ -96,12 +140,67 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error { |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(tcpStats.tcps_sndtotal), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatTcpRecvPacketsTotal, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(tcpStats.tcps_rcvtotal), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatTcpConnectionAttempts, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(tcpStats.tcps_connattempt), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatTcpConnectionAccepts, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(tcpStats.tcps_accepts), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatTcpConnectionDrops, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(tcpStats.tcps_drops), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatTcpRetransmitPackets, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(tcpStats.tcps_sndrexmitpack), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
udpData, err := getData("net.inet.udp.stats") |
|
|
|
|
if err != nil { |
|
|
|
|
return fmt.Errorf("failed to get UDP stats: %w", err) |
|
|
|
|
} |
|
|
|
|
if len(udpData) < int(unsafe.Sizeof(C.struct_udpstat{})) { |
|
|
|
|
return fmt.Errorf("UDP data size mismatch: got %d, want >= %d", len(udpData), unsafe.Sizeof(C.struct_udpstat{})) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
udpStats := *(*C.struct_udpstat)(unsafe.Pointer(&udpData[0])) |
|
|
|
|
|
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatUdpSendPacketsTotal, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(udpStats.udps_opackets), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatUdpRecvPacketsTotal, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(udpStats.udps_ipackets), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatUdpHeaderDrops, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(udpStats.udps_hdrops), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatUdpBadChecksum, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(udpStats.udps_badsum), |
|
|
|
|
) |
|
|
|
|
ch <- prometheus.MustNewConstMetric( |
|
|
|
|
bsdNetstatUdpNoPort, |
|
|
|
|
prometheus.CounterValue, |
|
|
|
|
float64(udpStats.udps_noport), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|