196 lines
6.0 KiB
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)
|
||
|
}
|
||
|
}
|