pkg/exporter/probe/procnetdev/procnetdev.go (101 lines of code) (raw):
package procnetdev
import (
"context"
"github.com/alibaba/kubeskoop/pkg/exporter/nettop"
"github.com/alibaba/kubeskoop/pkg/exporter/probe"
"github.com/prometheus/procfs"
log "github.com/sirupsen/logrus"
)
const (
probeName = "netdev" // nolint
RxBytes = "rxbytes"
RxErrors = "rxerrors"
TxBytes = "txbytes"
TxErrors = "txerrors"
RxPackets = "rxpackets"
RxDropped = "rxdropped"
TxPackets = "txpackets"
TxDropped = "txdropped"
)
var (
NetdevMetrics = []probe.LegacyMetric{
{Name: RxBytes, Help: "The total number of bytes received on the network interface."},
{Name: RxErrors, Help: "The total number of errors encountered while receiving on the network interface."},
{Name: TxBytes, Help: "The total number of bytes transmitted on the network interface."},
{Name: TxErrors, Help: "The total number of errors encountered while transmitting on the network interface."},
{Name: RxPackets, Help: "The total number of packets received on the network interface."},
{Name: RxDropped, Help: "The total number of received packets that were dropped on the network interface."},
{Name: TxPackets, Help: "The total number of packets transmitted on the network interface."},
{Name: TxDropped, Help: "The total number of transmitted packets that were dropped on the network interface."},
}
)
func init() {
probe.MustRegisterMetricsProbe(probeName, netdevProbeCreator)
}
func netdevProbeCreator() (probe.MetricsProbe, error) {
p := &ProcNetdev{}
batchMetrics := probe.NewLegacyBatchMetrics(probeName, NetdevMetrics, p.CollectOnce)
return probe.NewMetricsProbe(probeName, p, batchMetrics), nil
}
type ProcNetdev struct {
}
func (s *ProcNetdev) Start(_ context.Context) error {
return nil
}
func (s *ProcNetdev) Stop(_ context.Context) error {
return nil
}
func (s *ProcNetdev) CollectOnce() (map[string]map[uint32]uint64, error) {
ets := nettop.GetAllUniqueNetnsEntity()
if len(ets) == 0 {
log.Errorf("%s error, no entity found", probeName)
}
return collect(ets)
}
func collect(nslist []*nettop.Entity) (map[string]map[uint32]uint64, error) {
resMap := make(map[string]map[uint32]uint64)
for _, m := range NetdevMetrics {
resMap[m.Name] = make(map[uint32]uint64)
}
netdev := getAllNetdev(nslist)
for nsid := range netdev {
if len(netdev[nsid]) == 0 {
continue
}
for devname, devstat := range netdev[nsid] {
if devname != "lo" {
resMap[RxBytes][nsid] += devstat.RxBytes
resMap[RxErrors][nsid] += devstat.RxErrors
resMap[TxBytes][nsid] += devstat.TxBytes
resMap[TxErrors][nsid] += devstat.TxErrors
resMap[RxPackets][nsid] += devstat.RxPackets
resMap[TxPackets][nsid] += devstat.TxPackets
resMap[RxDropped][nsid] += devstat.RxDropped
resMap[TxDropped][nsid] += devstat.TxDropped
}
}
}
return resMap, nil
}
func getAllNetdev(nslist []*nettop.Entity) map[uint32]procfs.NetDev {
allnetdevs := map[uint32]procfs.NetDev{}
for idx := range nslist {
netdev, err := getNetdevByPid(uint32(nslist[idx].GetPid()))
if err != nil {
continue
}
allnetdevs[uint32(nslist[idx].GetNetns())] = netdev
}
return allnetdevs
}
func getNetdevByPid(pid uint32) (procfs.NetDev, error) {
fs, err := procfs.NewProc(int(pid))
if err != nil {
return nil, err
}
netdev, err := fs.NetDev()
if err != nil {
return nil, err
}
return netdev, nil
}