initial commit
This commit is contained in:
111
internal/collector/iface.go
Normal file
111
internal/collector/iface.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/device"
|
||||
"gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/keenetic"
|
||||
"gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/utils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type InterfaceCollector struct {
|
||||
linkDesc *prometheus.Desc
|
||||
stateDesc *prometheus.Desc
|
||||
mtuDesc *prometheus.Desc
|
||||
txQueueLengthDesc *prometheus.Desc
|
||||
uptimeDesc *prometheus.Desc
|
||||
temperatureDesc *prometheus.Desc
|
||||
channelDesc *prometheus.Desc
|
||||
}
|
||||
|
||||
func NewInterfaceCollector() *InterfaceCollector {
|
||||
labels := []string{"device", "id", "name", "type", "description", "mac", "connected"}
|
||||
|
||||
return &InterfaceCollector{
|
||||
linkDesc: prometheus.NewDesc("keenetic_interface_link_up", "Link status (1=up, 0=down)", labels, nil),
|
||||
stateDesc: prometheus.NewDesc("keenetic_interface_state_up", "Interface state (1=up, 0=down)", labels, nil),
|
||||
mtuDesc: prometheus.NewDesc("keenetic_interface_mtu", "MTU size", labels, nil),
|
||||
txQueueLengthDesc: prometheus.NewDesc("keenetic_interface_tx_queue_length", "TX queue length", labels, nil),
|
||||
uptimeDesc: prometheus.NewDesc("keenetic_interface_uptime_seconds", "Interface uptime in seconds", labels, nil),
|
||||
temperatureDesc: prometheus.NewDesc("keenetic_interface_temperature", "Interface temperature in celsius", labels, nil),
|
||||
channelDesc: prometheus.NewDesc("keenetic_interface_channel", "Interface wifi channel", labels, nil),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *InterfaceCollector) Name() string {
|
||||
return "interface"
|
||||
}
|
||||
|
||||
func (c *InterfaceCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- c.linkDesc
|
||||
ch <- c.stateDesc
|
||||
ch <- c.mtuDesc
|
||||
ch <- c.txQueueLengthDesc
|
||||
ch <- c.uptimeDesc
|
||||
ch <- c.temperatureDesc
|
||||
ch <- c.channelDesc
|
||||
}
|
||||
|
||||
func (c *InterfaceCollector) Collect(dev *device.Device, ch chan<- prometheus.Metric) error {
|
||||
var ifaceData any
|
||||
var ok bool
|
||||
|
||||
hostname := dev.Name
|
||||
client := dev.Client
|
||||
|
||||
// Check cache first
|
||||
dev.CacheMutex.RLock()
|
||||
ifaceData, ok = dev.Cache["interface"]
|
||||
valid := time.Since(dev.LastUpdate) < dev.CacheTTL
|
||||
dev.CacheMutex.RUnlock()
|
||||
|
||||
// Fetch fresh data if cache miss or expired
|
||||
if !ok || !valid {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
fresh, err := client.GetInterfaceInfo(ctx)
|
||||
cancel()
|
||||
if err != nil {
|
||||
log.Printf("failed to get interface info from %s: %v", hostname, err)
|
||||
return err
|
||||
}
|
||||
ifaceData = fresh
|
||||
dev.CacheMutex.Lock()
|
||||
dev.Cache["interface"] = fresh
|
||||
dev.LastUpdate = time.Now()
|
||||
dev.CacheMutex.Unlock()
|
||||
}
|
||||
|
||||
// Type assertion
|
||||
data, ok := ifaceData.(map[string]*keenetic.InterfaceInfo)
|
||||
if !ok || data == nil {
|
||||
log.Printf("invalid cache data type for interface info on %s", hostname)
|
||||
return fmt.Errorf("invalid cache data type for interface info")
|
||||
}
|
||||
|
||||
// Emit metrics for each interface
|
||||
for _, iface := range data {
|
||||
labels := []string{
|
||||
hostname,
|
||||
iface.ID,
|
||||
iface.InterfaceName,
|
||||
iface.Type,
|
||||
iface.Description,
|
||||
iface.MAC,
|
||||
iface.Connected,
|
||||
}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(c.linkDesc, prometheus.GaugeValue, utils.BoolToFloat(iface.Link == "up"), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.stateDesc, prometheus.GaugeValue, utils.BoolToFloat(iface.State == "up"), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.mtuDesc, prometheus.GaugeValue, float64(iface.MTU), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.txQueueLengthDesc, prometheus.GaugeValue, float64(iface.TxQueueLength), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.uptimeDesc, prometheus.CounterValue, float64(iface.Uptime), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.temperatureDesc, prometheus.GaugeValue, float64(iface.Temperature), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.channelDesc, prometheus.GaugeValue, float64(iface.Channel), labels...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user