diff --git a/influx.go b/influx.go new file mode 100644 index 0000000..0bc30ad --- /dev/null +++ b/influx.go @@ -0,0 +1,63 @@ +package main + +import ( + "encoding/json" + "log" + + client "github.com/influxdata/influxdb1-client/v2" +) + +// Create InfluxDB Client +func influxDBClient(port string) client.Client { + c, err := client.NewHTTPClient(client.HTTPConfig{ + Addr: conf.General.InfluxURL + ":" + port, + }) + if err != nil { + log.Fatalln("Error: ", err) + } + return c +} + +// Get a single Datapoint from InfluxDB +func getInfluxDataPoint(dp string, h string, p string) float64 { + + //Build the Query + query := "SELECT last(" + dp + ") FROM system WHERE host = '" + h + "'" + + c := influxDBClient(p) + q := client.NewQuery(query, "udp", "s") + response, err := c.Query(q) + if err != nil { + log.Println("Influx query error!") + } + res := 0.0 + if len(response.Results) > 0 { + res, err := response.Results[0].Series[0].Values[0][1].(json.Number).Float64() + if err != nil { + log.Println("Error in type conversion") + } + return res + } + return res +} + +// Send Datapoints to InfluxDB, point map and InfluxDB Port needed +func sendInfluxBatchDataPoint(point *client.Point, influxPort string) { + + // Open connection to InfluxDB + bp, err := client.NewBatchPoints(client.BatchPointsConfig{ + Database: "freifunk", + Precision: "s", + }) + if err != nil { + log.Fatalln("Error: ", err) + } + + bp.AddPoint(point) + c := influxDBClient(influxPort) + err = c.Write(bp) + if err != nil { + log.Fatal(err) + } + // +} diff --git a/main.go b/main.go index c7d16b7..c44288b 100644 --- a/main.go +++ b/main.go @@ -47,8 +47,6 @@ func main() { } } }() - //processUNMSAPIRouter() - //createMetrics(influxDBClient()) // start webserver on Port 3000 serveJSON() } diff --git a/staticDevices.go b/staticDevices.go index 8ad7b1e..ff12d6a 100644 --- a/staticDevices.go +++ b/staticDevices.go @@ -4,15 +4,59 @@ import ( "log" "strings" "time" + + client "github.com/influxdata/influxdb1-client/v2" ) func processGateways() []node { d := getDevices(conf.Gateways.GatewaysURL) var nodes []node + for i := range d.Devices { log.Println("Processing Static Device: ", d.Devices[i].Name) + currentDevice := d.Devices[i] + + //Calulate Memory + mem := getInfluxDataPoint("mem", currentDevice.FQDN, conf.General.ProxmoxInfluxPort) + maxmem := getInfluxDataPoint("maxmem", currentDevice.FQDN, conf.General.ProxmoxInfluxPort) + memory := mem / maxmem * 100 + rx := getInfluxDataPoint("netin", currentDevice.FQDN, conf.General.ProxmoxInfluxPort) + tx := getInfluxDataPoint("netout", currentDevice.FQDN, conf.General.ProxmoxInfluxPort) + // Get CPU + cpu := getInfluxDataPoint("cpu", currentDevice.FQDN, conf.General.ProxmoxInfluxPort) + //Uptime (seconds) + uptime := getInfluxDataPoint("uptime", currentDevice.FQDN, conf.General.ProxmoxInfluxPort) + t := time.Duration(uptime * float64(time.Second)) + up := time.Now().Add(-t) + + // fields := map[string]interface{}{} + fields := make(map[string]any) + tags := map[string]string{ + "hostname": strings.ReplaceAll(d.Devices[i].Name, " ", "-"), + "nodeid": strings.ReplaceAll(d.Devices[i].MAC, ":", ""), + } + + //Build fields for InfluxDB + fields["load"] = cpu + fields["ram"] = int(memory) + fields["time.up"] = int(uptime) + //Network + fields["traffic.rx.bytes"] = int(rx) + fields["traffic.tx.bytes"] = int(tx) + + point, err := client.NewPoint( + "node", + tags, + fields, + time.Now(), + ) + if err != nil { + log.Fatalln("Error: ", err) + } + sendInfluxBatchDataPoint(point, conf.General.FreifunkInfluxPort) + //Build Nodes nodes = append(nodes, node{ - Firstseen: time.Now().Format(iso8601), + Firstseen: up.Format(iso8601), Lastseen: time.Now().Format(iso8601), IsOnline: true, IsGateway: true, @@ -21,9 +65,9 @@ func processGateways() []node { ClientsWifi5: 0, ClientsOther: 0, RootFSUsage: 0, - LoadAVG: 0, - MemoryUsage: 0, - Uptime: time.Now().Format(iso8601), + LoadAVG: cpu, + MemoryUsage: memory, + Uptime: up.Format(iso8601), GatewayNexthop: "", Gateway: "", NodeID: strings.ReplaceAll(d.Devices[i].MAC, ":", ""), diff --git a/types.go b/types.go index 0d47dc7..b086ba2 100644 --- a/types.go +++ b/types.go @@ -10,6 +10,11 @@ import ( ) type config struct { + General struct { + FreifunkInfluxPort string `json:"freifunk_influx_port"` + ProxmoxInfluxPort string `json:"proxmox_influx_port"` + InfluxURL string `json:"influx_url"` + } Unms struct { Enabled bool `json:"enabled"` UnmsAPIURL string `json:"unmsAPIUrl"` @@ -40,6 +45,7 @@ type config struct { type device struct { Name string `json:"name"` + FQDN string `json:"fqdn"` MAC string `json:"mac"` GatewayNexthop string `json:"gateway_nexthop"` LinkedTo string `json:"linked_to"` diff --git a/unms.go b/unms.go index e58d6e4..3566e5e 100644 --- a/unms.go +++ b/unms.go @@ -104,7 +104,6 @@ func processUNMSAPI() ([]node, []link) { func processUNMSAPIRouter() ([]node, error) { // Variables for runtime var nodes []node - d := getDevices(conf.Unms.RouterURL) // API CALL 1, get all devices list from UNMS @@ -154,16 +153,6 @@ func processUNMSAPIRouter() ([]node, error) { log.Println("Router ist offline, skipping DHCP Leases") } - // Open connection to InfluxDB - bp, err := client.NewBatchPoints(client.BatchPointsConfig{ - Database: "freifunk", - Precision: "s", - }) - if err != nil { - log.Fatalln("Error: ", err) - } - // - // fields := map[string]interface{}{} fields := make(map[string]any) tags := map[string]string{ @@ -204,14 +193,8 @@ func processUNMSAPIRouter() ([]node, error) { if err != nil { log.Fatalln("Error: ", err) } - // Add Datapoints in InfluxDB - bp.AddPoint(point) - c := influxDBClient() - err = c.Write(bp) - if err != nil { - log.Fatal(err) - } + sendInfluxBatchDataPoint(point, conf.General.FreifunkInfluxPort) // Get info from json file (static) nodes = append(nodes, node{ Firstseen: dev.Overview.CreatedAt.Format(iso8601), @@ -250,16 +233,6 @@ func processUNMSAPIRouter() ([]node, error) { return nodes, nil } -func influxDBClient() client.Client { - c, err := client.NewHTTPClient(client.HTTPConfig{ - Addr: "http://statistik.freifunk-troisdorf.de:8886", - }) - if err != nil { - log.Fatalln("Error: ", err) - } - return c -} - func UnmsCallAPI(url string, i any) error { request, err := http.NewRequest(http.MethodGet, conf.Unms.UnmsAPIURL+url, nil) if err != nil {