2017-04-10 16:54:12 +00:00
|
|
|
package influxdb
|
2016-10-03 17:55:37 +00:00
|
|
|
|
|
|
|
import (
|
2017-04-17 23:48:38 +00:00
|
|
|
"fmt"
|
2017-01-29 21:14:40 +00:00
|
|
|
"strconv"
|
2017-04-17 23:48:38 +00:00
|
|
|
"time"
|
2017-01-29 21:14:40 +00:00
|
|
|
|
2017-04-17 23:48:38 +00:00
|
|
|
client "github.com/influxdata/influxdb/client/v2"
|
2017-04-10 16:54:12 +00:00
|
|
|
models "github.com/influxdata/influxdb/models"
|
2017-03-03 15:19:35 +00:00
|
|
|
|
2017-04-10 16:54:12 +00:00
|
|
|
"github.com/FreifunkBremen/yanic/runtime"
|
2016-10-03 17:55:37 +00:00
|
|
|
)
|
|
|
|
|
2017-09-27 11:55:02 +00:00
|
|
|
// PruneNodes prunes historical per-node data
|
2017-04-17 23:48:38 +00:00
|
|
|
func (conn *Connection) PruneNodes(deleteAfter time.Duration) {
|
2017-09-27 11:55:02 +00:00
|
|
|
for _, measurement := range []string{MeasurementNode, MeasurementLink} {
|
|
|
|
query := fmt.Sprintf("delete from %s where time < now() - %ds", measurement, deleteAfter/time.Second)
|
|
|
|
conn.client.Query(client.NewQuery(query, conn.config.Database(), "m"))
|
|
|
|
}
|
|
|
|
|
2017-04-17 23:48:38 +00:00
|
|
|
}
|
|
|
|
|
2017-09-27 11:55:02 +00:00
|
|
|
// InsertNode stores statistics and neighbours in the database
|
|
|
|
func (conn *Connection) InsertNode(node *runtime.Node) {
|
2016-10-03 17:55:37 +00:00
|
|
|
stats := node.Statistics
|
2017-09-27 11:55:02 +00:00
|
|
|
time := node.Lastseen.GetTime()
|
|
|
|
|
|
|
|
if stats == nil || stats.NodeID == "" {
|
|
|
|
return
|
|
|
|
}
|
2016-10-03 17:55:37 +00:00
|
|
|
|
2017-09-27 11:55:02 +00:00
|
|
|
tags := models.Tags{}
|
2017-01-20 21:27:44 +00:00
|
|
|
tags.SetString("nodeid", stats.NodeID)
|
2016-10-03 17:55:37 +00:00
|
|
|
|
2017-09-27 11:55:02 +00:00
|
|
|
fields := models.Fields{
|
2018-08-24 23:17:52 +00:00
|
|
|
"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.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,
|
2016-10-03 17:55:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if nodeinfo := node.Nodeinfo; nodeinfo != nil {
|
2017-03-15 22:26:34 +00:00
|
|
|
tags.SetString("hostname", nodeinfo.Hostname)
|
2017-11-20 11:22:52 +00:00
|
|
|
if nodeinfo.System.SiteCode != "" {
|
|
|
|
tags.SetString("site", nodeinfo.System.SiteCode)
|
|
|
|
}
|
2018-01-17 19:20:35 +00:00
|
|
|
if nodeinfo.System.DomainCode != "" {
|
|
|
|
tags.SetString("domain", nodeinfo.System.DomainCode)
|
|
|
|
}
|
2016-10-03 17:55:37 +00:00
|
|
|
if owner := nodeinfo.Owner; owner != nil {
|
|
|
|
tags.SetString("owner", owner.Contact)
|
|
|
|
}
|
|
|
|
if wireless := nodeinfo.Wireless; wireless != nil {
|
|
|
|
fields["wireless.txpower24"] = wireless.TxPower24
|
|
|
|
fields["wireless.txpower5"] = wireless.TxPower5
|
|
|
|
}
|
2017-03-15 22:26:34 +00:00
|
|
|
// Hardware
|
|
|
|
tags.SetString("model", nodeinfo.Hardware.Model)
|
2018-02-25 16:59:28 +00:00
|
|
|
fields["nproc"] = nodeinfo.Hardware.Nproc
|
2017-03-15 22:26:34 +00:00
|
|
|
tags.SetString("firmware_base", nodeinfo.Software.Firmware.Base)
|
|
|
|
tags.SetString("firmware_release", nodeinfo.Software.Firmware.Release)
|
2017-11-14 18:33:50 +00:00
|
|
|
if nodeinfo.Software.Autoupdater.Enabled {
|
|
|
|
tags.SetString("autoupdater", nodeinfo.Software.Autoupdater.Branch)
|
|
|
|
} else {
|
|
|
|
tags.SetString("autoupdater", runtime.DISABLED_AUTOUPDATER)
|
|
|
|
}
|
2017-03-15 22:26:34 +00:00
|
|
|
|
2016-10-03 17:55:37 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 22:23:31 +00:00
|
|
|
if neighbours := node.Neighbours; neighbours != nil {
|
|
|
|
// VPN Neighbours are Neighbours but includet in one protocol
|
|
|
|
vpn := 0
|
|
|
|
if meshvpn := stats.MeshVPN; meshvpn != nil {
|
|
|
|
for _, group := range meshvpn.Groups {
|
|
|
|
for _, link := range group.Peers {
|
2017-01-21 03:24:04 +00:00
|
|
|
if link != nil && link.Established > 1 {
|
2017-01-20 22:23:31 +00:00
|
|
|
vpn++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fields["neighbours.vpn"] = vpn
|
|
|
|
|
|
|
|
// protocol: Batman Advance
|
|
|
|
batadv := 0
|
|
|
|
for _, batadvNeighbours := range neighbours.Batadv {
|
|
|
|
batadv += len(batadvNeighbours.Neighbours)
|
|
|
|
}
|
|
|
|
fields["neighbours.batadv"] = batadv
|
|
|
|
|
|
|
|
// protocol: LLDP
|
2017-01-21 03:24:04 +00:00
|
|
|
lldp := 0
|
|
|
|
for _, lldpNeighbours := range neighbours.LLDP {
|
|
|
|
lldp += len(lldpNeighbours)
|
|
|
|
}
|
2017-01-20 22:23:31 +00:00
|
|
|
fields["neighbours.lldp"] = lldp
|
|
|
|
|
|
|
|
// total is the sum of all protocols
|
|
|
|
fields["neighbours.total"] = batadv + lldp
|
|
|
|
}
|
2018-05-05 22:11:01 +00:00
|
|
|
if procstat := stats.ProcStats; procstat != nil {
|
|
|
|
fields["stat.cpu.user"] = procstat.CPU.User
|
|
|
|
fields["stat.cpu.nice"] = procstat.CPU.Nice
|
|
|
|
fields["stat.cpu.system"] = procstat.CPU.System
|
|
|
|
fields["stat.cpu.idle"] = procstat.CPU.Idle
|
|
|
|
fields["stat.cpu.iowait"] = procstat.CPU.IOWait
|
|
|
|
fields["stat.cpu.irq"] = procstat.CPU.IRQ
|
|
|
|
fields["stat.cpu.softirq"] = procstat.CPU.SoftIRQ
|
|
|
|
fields["stat.intr"] = procstat.Intr
|
|
|
|
fields["stat.ctxt"] = procstat.ContextSwitches
|
|
|
|
fields["stat.softirq"] = procstat.SoftIRQ
|
|
|
|
fields["stat.processes"] = procstat.Processes
|
|
|
|
}
|
2017-01-20 22:23:31 +00:00
|
|
|
|
2016-10-03 17:55:37 +00:00
|
|
|
if t := stats.Traffic.Rx; t != nil {
|
|
|
|
fields["traffic.rx.bytes"] = int64(t.Bytes)
|
|
|
|
fields["traffic.rx.packets"] = t.Packets
|
|
|
|
}
|
|
|
|
if t := stats.Traffic.Tx; t != nil {
|
|
|
|
fields["traffic.tx.bytes"] = int64(t.Bytes)
|
|
|
|
fields["traffic.tx.packets"] = t.Packets
|
|
|
|
fields["traffic.tx.dropped"] = t.Dropped
|
|
|
|
}
|
|
|
|
if t := stats.Traffic.Forward; t != nil {
|
|
|
|
fields["traffic.forward.bytes"] = int64(t.Bytes)
|
|
|
|
fields["traffic.forward.packets"] = t.Packets
|
|
|
|
}
|
|
|
|
if t := stats.Traffic.MgmtRx; t != nil {
|
|
|
|
fields["traffic.mgmt_rx.bytes"] = int64(t.Bytes)
|
|
|
|
fields["traffic.mgmt_rx.packets"] = t.Packets
|
|
|
|
}
|
|
|
|
if t := stats.Traffic.MgmtTx; t != nil {
|
|
|
|
fields["traffic.mgmt_tx.bytes"] = int64(t.Bytes)
|
|
|
|
fields["traffic.mgmt_tx.packets"] = t.Packets
|
|
|
|
}
|
|
|
|
|
2016-12-22 02:14:51 +00:00
|
|
|
for _, airtime := range stats.Wireless {
|
|
|
|
suffix := airtime.FrequencyName()
|
|
|
|
fields["airtime"+suffix+".chan_util"] = airtime.ChanUtil
|
|
|
|
fields["airtime"+suffix+".rx_util"] = airtime.RxUtil
|
|
|
|
fields["airtime"+suffix+".tx_util"] = airtime.TxUtil
|
|
|
|
fields["airtime"+suffix+".noise"] = airtime.Noise
|
|
|
|
fields["airtime"+suffix+".frequency"] = airtime.Frequency
|
|
|
|
tags.SetString("frequency"+suffix, strconv.Itoa(int(airtime.Frequency)))
|
2016-10-03 17:55:37 +00:00
|
|
|
}
|
|
|
|
|
2017-09-27 11:55:02 +00:00
|
|
|
conn.addPoint(MeasurementNode, tags, fields, time)
|
|
|
|
|
2018-04-19 09:26:08 +00:00
|
|
|
// Add DHCP statistics
|
|
|
|
if dhcp := stats.DHCP; dhcp != nil {
|
|
|
|
fields := models.Fields{
|
|
|
|
"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,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tags
|
|
|
|
tags.SetString("nodeid", stats.NodeID)
|
|
|
|
if nodeinfo := node.Nodeinfo; nodeinfo != nil {
|
|
|
|
tags.SetString("hostname", nodeinfo.Hostname)
|
|
|
|
}
|
|
|
|
|
|
|
|
conn.addPoint(MeasurementDHCP, tags, fields, time)
|
|
|
|
}
|
|
|
|
|
2016-10-03 17:55:37 +00:00
|
|
|
return
|
|
|
|
}
|