yanic/database/influxdb2/node.go

196 lines
6.0 KiB
Go

package influxdb
import (
"strconv"
"time"
"github.com/FreifunkBremen/yanic/runtime"
influxdb "github.com/influxdata/influxdb-client-go/v2"
)
// PruneNodes prunes historical per-node data - not nessasary, juse configurate your influxdb2
func (conn *Connection) PruneNodes(deleteAfter time.Duration) {
}
// InsertNode stores statistics and neighbours in the database
func (conn *Connection) InsertNode(node *runtime.Node) {
stats := node.Statistics
time := node.Lastseen.GetTime()
if stats == nil || stats.NodeID == "" {
return
}
p := influxdb.NewPoint(MeasurementNode,
conn.config.Tags(),
map[string]interface{}{
"load": stats.LoadAverage,
"time.up": int64(stats.Uptime),
"time.idle": int64(stats.Idletime),
"proc.running": stats.Processes.Running,
"clients.wifi": stats.Clients.Wifi,
"clients.wifi24": stats.Clients.Wifi24,
"clients.wifi5": stats.Clients.Wifi5,
"clients.owe": stats.Clients.OWE,
"clients.owe24": stats.Clients.OWE24,
"clients.owe5": stats.Clients.OWE5,
"clients.total": stats.Clients.Total,
"memory.buffers": stats.Memory.Buffers,
"memory.cached": stats.Memory.Cached,
"memory.free": stats.Memory.Free,
"memory.total": stats.Memory.Total,
"memory.available": stats.Memory.Available,
},
time).
AddTag("nodeid", stats.NodeID)
vpnInterfaces := make(map[string]bool)
if nodeinfo := node.Nodeinfo; nodeinfo != nil {
for _, mIface := range nodeinfo.Network.Mesh {
for _, tunnel := range mIface.Interfaces.Tunnel {
vpnInterfaces[tunnel] = true
}
}
p.AddTag("hostname", nodeinfo.Hostname)
if nodeinfo.System.SiteCode != "" {
p.AddTag("site", nodeinfo.System.SiteCode)
}
if nodeinfo.System.DomainCode != "" {
p.AddTag("domain", nodeinfo.System.DomainCode)
}
if owner := nodeinfo.Owner; owner != nil {
p.AddTag("owner", owner.Contact)
}
if wireless := nodeinfo.Wireless; wireless != nil {
p.AddField("wireless.txpower24", wireless.TxPower24)
p.AddField("wireless.txpower5", wireless.TxPower5)
}
// Hardware
p.AddTag("model", nodeinfo.Hardware.Model)
p.AddField("nproc", nodeinfo.Hardware.Nproc)
if nodeinfo.Software.Firmware != nil {
p.AddTag("firmware_base", nodeinfo.Software.Firmware.Base)
p.AddTag("firmware_release", nodeinfo.Software.Firmware.Release)
}
if nodeinfo.Software.Autoupdater != nil && nodeinfo.Software.Autoupdater.Enabled {
p.AddTag("autoupdater", nodeinfo.Software.Autoupdater.Branch)
} else {
p.AddTag("autoupdater", runtime.DISABLED_AUTOUPDATER)
}
}
if neighbours := node.Neighbours; neighbours != nil {
// VPN Neighbours are Neighbours but includet in one protocol
vpn := 0
// protocol: Batman Advance
batadv := 0
for mac, batadvNeighbours := range neighbours.Batadv {
batadv += len(batadvNeighbours.Neighbours)
if _, ok := vpnInterfaces[mac]; ok {
vpn += len(batadvNeighbours.Neighbours)
}
}
p.AddField("neighbours.batadv", batadv)
// protocol: Babel
babel := 0
for _, babelNeighbours := range neighbours.Babel {
babel += len(babelNeighbours.Neighbours)
if _, ok := vpnInterfaces[babelNeighbours.LinkLocalAddress]; ok {
vpn += len(babelNeighbours.Neighbours)
}
}
p.AddField("neighbours.babel", babel)
// protocol: LLDP
lldp := 0
for _, lldpNeighbours := range neighbours.LLDP {
lldp += len(lldpNeighbours)
}
p.AddField("neighbours.lldp", lldp)
// vpn wait for babel
p.AddField("neighbours.vpn", vpn)
// total is the sum of all protocols
p.AddField("neighbours.total", batadv+babel+lldp)
}
if procstat := stats.ProcStats; procstat != nil {
p.AddField("stat.cpu.user", procstat.CPU.User)
p.AddField("stat.cpu.nice", procstat.CPU.Nice)
p.AddField("stat.cpu.system", procstat.CPU.System)
p.AddField("stat.cpu.idle", procstat.CPU.Idle)
p.AddField("stat.cpu.iowait", procstat.CPU.IOWait)
p.AddField("stat.cpu.irq", procstat.CPU.IRQ)
p.AddField("stat.cpu.softirq", procstat.CPU.SoftIRQ)
p.AddField("stat.intr", procstat.Intr)
p.AddField("stat.ctxt", procstat.ContextSwitches)
p.AddField("stat.softirq", procstat.SoftIRQ)
p.AddField("stat.processes", procstat.Processes)
}
if t := stats.Traffic.Rx; t != nil {
p.AddField("traffic.rx.bytes", int64(t.Bytes))
p.AddField("traffic.rx.packets", t.Packets)
}
if t := stats.Traffic.Tx; t != nil {
p.AddField("traffic.tx.bytes", int64(t.Bytes))
p.AddField("traffic.tx.packets", t.Packets)
p.AddField("traffic.tx.dropped", t.Dropped)
}
if t := stats.Traffic.Forward; t != nil {
p.AddField("traffic.forward.bytes", int64(t.Bytes))
p.AddField("traffic.forward.packets", t.Packets)
}
if t := stats.Traffic.MgmtRx; t != nil {
p.AddField("traffic.mgmt_rx.bytes", int64(t.Bytes))
p.AddField("traffic.mgmt_rx.packets", t.Packets)
}
if t := stats.Traffic.MgmtTx; t != nil {
p.AddField("traffic.mgmt_tx.bytes", int64(t.Bytes))
p.AddField("traffic.mgmt_tx.packets", t.Packets)
}
for _, airtime := range stats.Wireless {
suffix := airtime.FrequencyName()
p.AddField("airtime"+suffix+".chan_util", airtime.ChanUtil)
p.AddField("airtime"+suffix+".rx_util", airtime.RxUtil)
p.AddField("airtime"+suffix+".tx_util", airtime.TxUtil)
p.AddField("airtime"+suffix+".noise", airtime.Noise)
p.AddField("airtime"+suffix+".frequency", airtime.Frequency)
p.AddTag("frequency"+suffix, strconv.Itoa(int(airtime.Frequency)))
}
conn.writeAPI[MeasurementNode].WritePoint(p)
// Add DHCP statistics
if dhcp := stats.DHCP; dhcp != nil {
p := influxdb.NewPoint(MeasurementDHCP,
conn.config.Tags(),
map[string]interface{}{
"decline": dhcp.Decline,
"offer": dhcp.Offer,
"ack": dhcp.Ack,
"nak": dhcp.Nak,
"request": dhcp.Request,
"discover": dhcp.Discover,
"inform": dhcp.Inform,
"release": dhcp.Release,
"leases.allocated": dhcp.LeasesAllocated,
"leases.pruned": dhcp.LeasesPruned,
}, time).
AddTag("nodeid", stats.NodeID)
if nodeinfo := node.Nodeinfo; nodeinfo != nil {
p.AddTag("hostname", nodeinfo.Hostname)
}
conn.writeAPI[MeasurementDHCP].WritePoint(p)
}
}