Check if device is online for statistics processing
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
16dd56e320
commit
22c935ce2a
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"unms": {
|
"unms": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"unmsAPIUrl": "https://unifi.freifunk-troisdorf.de/v2.1",
|
"unmsAPIUrl": "https://uisp.freifunk-troisdorf.de/v2.1",
|
||||||
"APItoken": "UNMS API TOKEN",
|
"APItoken": "UNMS API TOKEN",
|
||||||
"devicesURL": "https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/example.devices.json"
|
"devicesURL": "https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/example.devices.json"
|
||||||
},
|
},
|
||||||
"unifi": {
|
"unifi": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"displayusers": true,
|
"displayusers": true,
|
||||||
"APIUrl": "https://unifi.freifunk-troisdorf.de:8443",
|
"APIUrl": "https://unifi.freifunk-troisdorf.de",
|
||||||
"user": "APIuser",
|
"user": "APIuser",
|
||||||
"password": "PASSWORD",
|
"password": "PASSWORD",
|
||||||
"ucDevicesURL": "https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/example.ucDevices.json"
|
"ucDevicesURL": "https://git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api/raw/branch/master/example.ucDevices.json"
|
||||||
|
10
go.mod
10
go.mod
@ -1,9 +1,17 @@
|
|||||||
module git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api
|
module git.freifunk-rhein-sieg.net/Freifunk-Troisdorf/ubnt-freifunk-map-api
|
||||||
|
|
||||||
go 1.16
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.nils.zone/nils/prettify v0.0.4
|
git.nils.zone/nils/prettify v0.0.4
|
||||||
github.com/fatih/structs v1.1.0
|
github.com/fatih/structs v1.1.0
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
|
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 // indirect
|
||||||
|
github.com/fatih/color v1.9.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.11 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
|
||||||
|
)
|
||||||
|
33
main.go
33
main.go
@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
@ -34,8 +34,19 @@ func main() {
|
|||||||
if *configPath == "" {
|
if *configPath == "" {
|
||||||
log.Fatalln("Please specify path to config.json flag '-configPath'")
|
log.Fatalln("Please specify path to config.json flag '-configPath'")
|
||||||
}
|
}
|
||||||
|
|
||||||
// start API processing (runs in a loop)
|
// start API processing (runs in a loop)
|
||||||
go processAPIs()
|
go func() {
|
||||||
|
if err := processAPIs(); err != nil {
|
||||||
|
log.Fatalln("API processing failed, error is", err)
|
||||||
|
}
|
||||||
|
tick := time.Tick(delay)
|
||||||
|
for range tick {
|
||||||
|
if err := processAPIs(); err != nil {
|
||||||
|
log.Fatalln("API processing failed, error is", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
//processUNMSAPIRouter()
|
//processUNMSAPIRouter()
|
||||||
//createMetrics(influxDBClient())
|
//createMetrics(influxDBClient())
|
||||||
// start webserver on Port 3000
|
// start webserver on Port 3000
|
||||||
@ -55,22 +66,20 @@ func loadconfig(file string) config {
|
|||||||
|
|
||||||
// int to bool converter
|
// int to bool converter
|
||||||
func itob(i int) bool {
|
func itob(i int) bool {
|
||||||
if i == 1 {
|
return i == 1
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func processAPIs() {
|
func processAPIs() error {
|
||||||
tick := time.Tick(delay)
|
|
||||||
for range tick {
|
|
||||||
var nodes []node
|
var nodes []node
|
||||||
var links []link
|
var links []link
|
||||||
|
|
||||||
if conf.Unms.Enabled {
|
if conf.Unms.Enabled {
|
||||||
log.Println("Processing UNMS")
|
log.Println("Processing UNMS")
|
||||||
unmsNodes, unmsLinks := processUNMSAPI()
|
unmsNodes, unmsLinks := processUNMSAPI()
|
||||||
unmsRouters := processUNMSAPIRouter()
|
unmsRouters, err := processUNMSAPIRouter()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
nodes = append(nodes, unmsNodes...)
|
nodes = append(nodes, unmsNodes...)
|
||||||
nodes = append(nodes, unmsRouters...)
|
nodes = append(nodes, unmsRouters...)
|
||||||
links = append(links, unmsLinks...)
|
links = append(links, unmsLinks...)
|
||||||
@ -107,7 +116,7 @@ func processAPIs() {
|
|||||||
}
|
}
|
||||||
// we're done here
|
// we're done here
|
||||||
log.Println("...done")
|
log.Println("...done")
|
||||||
}
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to get file from meshviewer
|
// function to get file from meshviewer
|
||||||
@ -117,7 +126,7 @@ func getFile(url string) []byte {
|
|||||||
log.Println("Error getting file from:", url)
|
log.Println("Error getting file from:", url)
|
||||||
}
|
}
|
||||||
data := resp.Body
|
data := resp.Body
|
||||||
byteValue, _ := ioutil.ReadAll(data)
|
byteValue, _ := io.ReadAll(data)
|
||||||
return byteValue
|
return byteValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
types.go
34
types.go
@ -314,40 +314,26 @@ type UNMSLogResponse struct {
|
|||||||
} `json:"items"`
|
} `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type XY struct {
|
||||||
|
X int `json:"x"`
|
||||||
|
Y int `json:"y"`
|
||||||
|
}
|
||||||
|
|
||||||
type UNMSstatistics struct {
|
type UNMSstatistics struct {
|
||||||
Period int `json:"period"`
|
Period int `json:"period"`
|
||||||
Interval struct {
|
Interval struct {
|
||||||
Start int `json:"start"`
|
Start int `json:"start"`
|
||||||
End int `json:"end"`
|
End int `json:"end"`
|
||||||
} `json:"interval"`
|
} `json:"interval"`
|
||||||
CPU []struct {
|
CPU []XY `json:"cpu"`
|
||||||
X int `json:"x"`
|
RAM []XY `json:"ram"`
|
||||||
Y int `json:"y"`
|
Errors []XY `json:"errors"`
|
||||||
} `json:"cpu"`
|
|
||||||
RAM []struct {
|
|
||||||
X int `json:"x"`
|
|
||||||
Y int `json:"y"`
|
|
||||||
} `json:"ram"`
|
|
||||||
Ping []struct {
|
|
||||||
X int `json:"x"`
|
|
||||||
Y int `json:"y"`
|
|
||||||
} `json:"ping"`
|
|
||||||
Errors []struct {
|
|
||||||
X int `json:"x"`
|
|
||||||
Y int `json:"y"`
|
|
||||||
} `json:"errors"`
|
|
||||||
Interfaces []struct {
|
Interfaces []struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Priority int `json:"priority"`
|
Priority int `json:"priority"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Receive []struct {
|
Receive []XY `json:"receive"`
|
||||||
X int `json:"x"`
|
Transmit []XY `json:"transmit"`
|
||||||
Y int `json:"y"`
|
|
||||||
} `json:"receive"`
|
|
||||||
Transmit []struct {
|
|
||||||
X int `json:"x"`
|
|
||||||
Y int `json:"y"`
|
|
||||||
} `json:"transmit"`
|
|
||||||
} `json:"interfaces"`
|
} `json:"interfaces"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
unifi.go
6
unifi.go
@ -4,7 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -126,10 +126,10 @@ func (u *UnifiAPIData) ucCallAPI(url string, method string, body *bytes.Buffer,
|
|||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
if response.StatusCode != 200 {
|
if response.StatusCode != 200 {
|
||||||
return fmt.Errorf("Login failed %s", u.baseURL+url)
|
return fmt.Errorf("login failed %s", u.baseURL+url)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(response.Body)
|
data, err := io.ReadAll(response.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
48
unms.go
48
unms.go
@ -42,10 +42,7 @@ func processUNMSAPI() ([]node, []link) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isOnline bool = false
|
isOnline := dev.Overview.Status == "active"
|
||||||
if dev.Overview.Status == "active" {
|
|
||||||
isOnline = true
|
|
||||||
}
|
|
||||||
// END OF API CALL 1
|
// END OF API CALL 1
|
||||||
|
|
||||||
// API CALL 2
|
// API CALL 2
|
||||||
@ -104,7 +101,7 @@ func processUNMSAPI() ([]node, []link) {
|
|||||||
return nodes, links
|
return nodes, links
|
||||||
}
|
}
|
||||||
|
|
||||||
func processUNMSAPIRouter() []node {
|
func processUNMSAPIRouter() ([]node, error) {
|
||||||
// Variables for runtime
|
// Variables for runtime
|
||||||
var nodes []node
|
var nodes []node
|
||||||
|
|
||||||
@ -115,7 +112,7 @@ func processUNMSAPIRouter() []node {
|
|||||||
var u []unifiAPIResponse
|
var u []unifiAPIResponse
|
||||||
err := UnmsCallAPI("/devices", &u)
|
err := UnmsCallAPI("/devices", &u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
// END OF API CALL 1
|
// END OF API CALL 1
|
||||||
|
|
||||||
@ -130,26 +127,29 @@ func processUNMSAPIRouter() []node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var isOnline bool = false
|
isOnline := dev.Overview.Status == "active"
|
||||||
if dev.Overview.Status == "active" {
|
|
||||||
isOnline = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// API CALL FOR ROUTER DETAILS (Interface RX/TX)
|
// API CALL FOR ROUTER DETAILS (Interface RX/TX)
|
||||||
log.Println("Getting details of ", d.Devices[i].Name, "from UNMS API")
|
log.Println("Getting details of ", d.Devices[i].Name, "from UNMS API")
|
||||||
var details unifiAPIDetails
|
var details unifiAPIDetails
|
||||||
UnmsCallAPI("/devices/erouters/"+dev.Identification.ID, &details)
|
if err := UnmsCallAPI("/devices/erouters/"+dev.Identification.ID, &details); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// API CALL FOR DEVICE STATISTICS (CPU, RAM)
|
// API CALL FOR DEVICE STATISTICS (CPU, RAM)
|
||||||
log.Println("Getting statistics of ", d.Devices[i].Name, "from UNMS API")
|
log.Println("Getting statistics of ", d.Devices[i].Name, "from UNMS API")
|
||||||
var statistics UNMSstatistics
|
var statistics UNMSstatistics
|
||||||
UnmsCallAPI("/devices/"+dev.Identification.ID+"/statistics?interval=hour", &statistics)
|
if err := UnmsCallAPI("/devices/"+dev.Identification.ID+"/statistics?interval=hour", &statistics); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// API CALL FOR DHCP LEASES
|
// API CALL FOR DHCP LEASES
|
||||||
log.Println("Getting DHCP Leases of ", d.Devices[i].Name, "from UNMS API")
|
log.Println("Getting DHCP Leases of ", d.Devices[i].Name, "from UNMS API")
|
||||||
var dhcpleases UNMSdhcp
|
var dhcpleases UNMSdhcp
|
||||||
if isOnline {
|
if isOnline {
|
||||||
UnmsCallAPI("/devices/erouters/"+dev.Identification.ID+"/dhcp/leases", &dhcpleases)
|
if err := UnmsCallAPI("/devices/erouters/"+dev.Identification.ID+"/dhcp/leases", &dhcpleases); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("Router ist offline, skipping DHCP Leases")
|
log.Println("Router ist offline, skipping DHCP Leases")
|
||||||
}
|
}
|
||||||
@ -164,7 +164,8 @@ func processUNMSAPIRouter() []node {
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
||||||
fields := map[string]interface{}{}
|
// fields := map[string]interface{}{}
|
||||||
|
fields := make(map[string]any)
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
"hostname": strings.ReplaceAll(d.Devices[i].Name, " ", "-"),
|
"hostname": strings.ReplaceAll(d.Devices[i].Name, " ", "-"),
|
||||||
"nodeid": strings.ReplaceAll(dev.Identification.MAC, ":", ""),
|
"nodeid": strings.ReplaceAll(dev.Identification.MAC, ":", ""),
|
||||||
@ -177,15 +178,21 @@ func processUNMSAPIRouter() []node {
|
|||||||
fields[interface_name_tx] = details.Interfaces[eth].Statistics.Txrate
|
fields[interface_name_tx] = details.Interfaces[eth].Statistics.Txrate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set default values if we can't get statistics
|
||||||
|
fields["cpu"] = 0
|
||||||
|
fields["load"] = float64(0)
|
||||||
|
fields["ram"] = 0
|
||||||
|
|
||||||
|
if isOnline {
|
||||||
// Generate fields for all Statistics
|
// Generate fields for all Statistics
|
||||||
load := (float64(statistics.CPU[0].Y) / float64(100))
|
load := (float64(statistics.CPU[0].Y) / float64(100))
|
||||||
fields["cpu"] = statistics.CPU[0].Y
|
fields["cpu"] = statistics.CPU[0].Y
|
||||||
fields["load"] = load
|
fields["load"] = load
|
||||||
fields["ram"] = statistics.RAM[0].Y
|
fields["ram"] = statistics.RAM[0].Y
|
||||||
|
}
|
||||||
|
|
||||||
// Generate field for DHCP Leases
|
// Generate field for DHCP Leases
|
||||||
leases := len(dhcpleases)
|
fields["clients.total"] = len(dhcpleases)
|
||||||
fields["clients.total"] = leases
|
|
||||||
|
|
||||||
// Generate Dataponts
|
// Generate Dataponts
|
||||||
point, err := client.NewPoint(
|
point, err := client.NewPoint(
|
||||||
@ -240,7 +247,7 @@ func processUNMSAPIRouter() []node {
|
|||||||
Model: details.Identification.Model,
|
Model: details.Identification.Model,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return nodes
|
return nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func influxDBClient() client.Client {
|
func influxDBClient() client.Client {
|
||||||
@ -253,7 +260,7 @@ func influxDBClient() client.Client {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnmsCallAPI(url string, i interface{}) error {
|
func UnmsCallAPI(url string, i any) error {
|
||||||
request, err := http.NewRequest(http.MethodGet, conf.Unms.UnmsAPIURL+url, nil)
|
request, err := http.NewRequest(http.MethodGet, conf.Unms.UnmsAPIURL+url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New(fmt.Sprint("can't set request", conf.Unms.UnmsAPIURL+url))
|
return errors.New(fmt.Sprint("can't set request", conf.Unms.UnmsAPIURL+url))
|
||||||
@ -265,7 +272,7 @@ func UnmsCallAPI(url string, i interface{}) error {
|
|||||||
return fmt.Errorf("can't get request %s with x-auth-token %s", conf.Unms.UnmsAPIURL+url, conf.Unms.APItoken)
|
return fmt.Errorf("can't get request %s with x-auth-token %s", conf.Unms.UnmsAPIURL+url, conf.Unms.APItoken)
|
||||||
}
|
}
|
||||||
if response.StatusCode != 200 {
|
if response.StatusCode != 200 {
|
||||||
log.Fatalln("Can´t call UNMS API, check token and URL. HTTP Status: ", response.StatusCode)
|
log.Fatalln("Can't call UNMS API, check token and URL. HTTP Status: ", response.StatusCode)
|
||||||
}
|
}
|
||||||
data, err := ioutil.ReadAll(response.Body)
|
data, err := ioutil.ReadAll(response.Body)
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
@ -273,8 +280,7 @@ func UnmsCallAPI(url string, i interface{}) error {
|
|||||||
return fmt.Errorf("can't read response body: %+v", response.Body)
|
return fmt.Errorf("can't read response body: %+v", response.Body)
|
||||||
}
|
}
|
||||||
// no error occurred, unmarshal to struct
|
// no error occurred, unmarshal to struct
|
||||||
json.Unmarshal(data, &i)
|
return json.Unmarshal(data, &i)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnmsGetAddresses(ip string) []string {
|
func UnmsGetAddresses(ip string) []string {
|
||||||
|
Loading…
Reference in New Issue
Block a user