StatusUpdates
auf den Routern
Grafana - Node Overview
Grafana ist eine grafische Übersichtsseite einzelner Nodes.
- Systemlast
- Arbeitsspeicher
- CPU Auslastung
- Netzwerkverbindungen
- Verbunde Clients
- DHCP Leases
- Traffic
Um das Skript auf deinem Router zu installieren, verbinde dich via SSH mit deinem Router.
ssh root@Router-IP
Und führe folgenden Befehl aus (copy & paste).
wget -q -O /tmp/ffp-collect https://monitor.freifunk-potsdam.de/ffp-collect && chmod +x /tmp/ffp-collect && /tmp/ffp-collect install
Troubleshooting: bei Routern mit wenig Flash ist möglicherweise keine HTTPS-Unterstützung gegeben. In diesem Falle kannst du das Script von https://monitor.freifunk-potsdam.de/ffp-collect kopieren und mit
cat > /tmp/ffp-collect && chmod +x /tmp/ffp-collect && /tmp/ffp-collect install
zum laufen bringen, indem du es dann in die Konsole einfügst und am Ende Strg + D drückst.
Beim ersten Start werden alle Schnittstellen aufgelistet, unter denen gewählt werden kann, welche nicht mitgeschnitten werden sollen (z.B. private APs, normalerwise keine).
Beim Start des Scriptes werden drei CronJobs hinzugefügt:
- collect: sammelt Daten (jede Minute)
- upload: läd Daten hoch (alle 10 Minuten)
- upgrade: läd die aktuelle Version dieses Scriptes herunter und installiert sie (zum 1. jeden Monat zu einer zufälligen Uhrzeit)
Achtung: Ein sysupgrade löscht Grafana und dannach muss es neu installiert werden, Issue 1.
Weitere Befehle:
Skript updaten:
/etc/init.d/ffp-collect upgrade
Skript neu konfigurieren:
/etc/init.d/ffp-collect install
Skript stoppen (CronJobs werden entfernt):
/etc/init.d/ffp-collect stop
Skript starten (CronJobs werden hinzugefügt):
/etc/init.d/ffp-collect start
Skript aus Autostart entfernen:
/etc/init.d/ffp-collect disable
Skript in Autostart eintragen:
/etc/init.d/ffp-collect enable
Alle verbleibenden Daten manuell hochladen:
/etc/init.d/ffp-collect upload
Details
- Das Script sammelt die Daten jede Minute in /tmp/collstat
- Einmal alle 10 Minuten werden die Daten zum Server übertragen
auf dem Server
Quellcode
Quellcode für den Server gibts auf GitHub
Doku?
Die Serversoftware fürs Parsen ist in Python geschrieben. InfluxDb wird für alles benutzt, das in Grafana angezeigt wird, für die Daten, die sicht nicht so oft ändern, und eher Statusinfos darstellen, wird eine MongoDb benutzt. Anlaufstelle für die Clients ist fffeed.wsgi, das über das Apache WSGI plugin auf die Webadresse /fff gemappt ist. fffeed.wsgi speichert die hochgeladenen Daten erst mal nur ab, das parsen übernehmen dann ein paar CronJobs:
- parseff1.py: parst alle hochgeladenen Dateien, füllt Daten in die InfluxDb und speichert den aktuelle Status in einer temporären Collection in der MongoDB
- parseff2.py: sammelt die Änderungen zusammen, aktualisiert die Statusinfos in der MongoDb und vermerkt die tatsächlichen Änderungen in einer extra Collection.
Damit wären alle Daten zusammen, die für Grafana und die APDB-Tabelle nötig sind.
Die Infos zu den Links für die Karte sind in der InfluxDB, die Abfrage daraus würde aber zu lange dauern, dafür gibt es:
- lperf.py: aggregiert aus der InfluxDb die Daten der Link Performance und speichert diese in der MongoDb zwischen.
Für die kompletten Pfade innerhalb den Netzwerks, die auf den ApInfo-Seiten angezeigt werden:
- routes.py: ermittelt die kürzesten Routen durch das Netzwerk für alle Router
Dann gibt es noch
- sendtweets.py: liest die Collection mit den Veränderungen und schickt Tweets, außerdem kann es Tagesstatistiken tweeten
InfluxDb
In der InfluxDb sind die folgenden Continuous Queries definiert:
router_count_archive CREATE CONTINUOUS QUERY router_count_archive ON freifunk RESAMPLE EVERY 1h FOR 1d BEGIN SELECT max(count) INTO ffarchive."default".router_count FROM freifunk.twodays.router_count GROUP BY time(1h) fill(none) END router_count CREATE CONTINUOUS QUERY router_count ON freifunk RESAMPLE EVERY 15m FOR 6h BEGIN SELECT count(conn_tcp) INTO freifunk.twodays.router_count FROM freifunk."default".conn GROUP BY time(1m) fill(none) END last_dhcp CREATE CONTINUOUS QUERY last_dhcp ON freifunk RESAMPLE EVERY 5m FOR 6h BEGIN SELECT last(leases), max(leases), min(leases), mean(leases), median(leases) INTO freifunk.twodays.dhcp FROM freifunk."default".dhcp GROUP BY time(1h), network fill(none) END
Außerdem gibt es ein paar Queries, die regelmäßig via Cron ausgeführt werden, weil sie als CQ zu lange brauchen oder nicht funktionieren:
Täglich:
# TRAFFIC TX, freifunk.network -> ffarchive.traffic_tx (5m von -48h) SELECT non_negative_derivative(last(tx_bytes)) AS tx_bytes INTO ffarchive."default".traffic_tx FROM freifunk."default".network WHERE time > NOW() - 48h GROUP BY time(5m), device, hostname fill(none) # TRAFFIC RX, freifunk.network -> ffarchive.traffic_rx (5m von -48h) SELECT non_negative_derivative(last(rx_bytes)) AS rx_bytes INTO ffarchive."default".traffic_rx FROM freifunk."default".network WHERE time > NOW() - 48h GROUP BY time(5m), device, hostname fill(none) # LQ NLQ, freifunk.links -> ffarchive.links (5m von -48h bis -23h) SELECT min(linkQuality) AS lq_min, max(linkQuality) AS lq_max, mean(linkQuality) AS lq_mean, median(linkQuality) AS lq_median, min(neighborLinkQuality) AS nlq_min, max(neighborLinkQuality) AS nlq_max, mean(neighborLinkQuality) AS nlq_mean, median(neighborLinkQuality) AS nlq_median INTO ffarchive."default".links FROM freifunk."default".links WHERE time < now() - 23h and time > NOW() - 48h GROUP BY time(5m), localIP, remoteIP, remoteHostname, hostname fill(none) # LEASES, freifunk.dhcp -> ffarchive.dhcp (5m von -48h bis -23h) SELECT min(leases) AS min, max(leases) AS max, mean(leases) AS mean, median(leases) AS median INTO ffarchive."default".dhcp FROM freifunk."default".dhcp WHERE time < now() - 23h and time > NOW() - 48h GROUP BY time(5m), network, hostname fill(none) # ASSOC, freifunk.wireless -> ffarchive.wireless (5m von -3h) SELECT min(assoc) AS min, max(assoc) AS max, mean(assoc) AS mean, median(assoc) AS median INTO ffarchive."default".wireless FROM freifunk."default".wireless WHERE time < now() - 23h and time > NOW() - 48h GROUP BY time(5m), device, essid, hostname fill(none) # ETX, ffarchive.links -> ffarchive.link_etx (5m von -48h bis -23h) SELECT 1 / (max(lq_max) * max(nlq_max)) AS etx_max, 1 / (min(lq_min) * min(nlq_min)) AS etx_min, 1 / (mean(lq_mean) * mean(nlq_mean)) AS etx_mean, 1 / (median(lq_median) * median(nlq_median)) AS etx_median INTO ffarchive."default".link_etx FROM ffarchive."default".links WHERE time < now() - 23h and time > NOW() - 48h GROUP BY time(5m), localIP, remoteIP, remoteHostname, hostname fill(none)
Stündlich:
# TRAFFIC TX, freifunk.network -> ffarchive.traffic_tx (5m von -3h) SELECT non_negative_derivative(last(tx_bytes)) AS tx_bytes INTO ffarchive."default".traffic_tx FROM freifunk."default".network WHERE time > NOW() - 3h GROUP BY time(5m), device, hostname fill(none) # TRAFFIC RX, freifunk.network -> ffarchive.traffic_rx (5m von -3h) SELECT non_negative_derivative(last(rx_bytes)) AS rx_bytes INTO ffarchive."default".traffic_rx FROM freifunk."default".network WHERE time > NOW() - 3h GROUP BY time(5m), device, hostname fill(none)' # LEASES, freifunk.dhcp -> ffarchive.dhcp (5m von -3h) SELECT min(leases) AS min, max(leases) AS max, mean(leases) AS mean, median(leases) AS median INTO ffarchive."default".dhcp FROM freifunk."default".dhcp WHERE time > now() - 3h GROUP BY time(5m), network, hostname fill(none) # ASSOC, freifunk.wireless -> ffarchive.wireless (5m von -3h) SELECT min(assoc) AS min, max(assoc) AS max, mean(assoc) AS mean, median(assoc) AS median INTO ffarchive."default".wireless FROM freifunk."default".wireless WHERE time > now() - 3h GROUP BY time(5m), device, essid, hostname fill(none) # ETX, freifunk.links -> freifunk.link_etx (1m von -3h bis -1h) SELECT 1 / (mean(linkQuality) * mean(neighborLinkQuality)) AS etx INTO freifunk."default".link_etx FROM freifunk."default".links WHERE time > now() - 3h AND time < now() - 1h GROUP BY time(1m), localIP, remoteIP, remoteHostname, hostname fill(none)
Crontab
Alles, was in der Crontab mit dem Parsen zu tun hat:
# parsing # 0,5,10,... */5 * * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/parseff1.py /var/ffdata/ >> /var/ffdata/ffdata.log # 4,9,14,... 4-59/5 * * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/parseff2.py 59 * * * * root cat /var/ffdata/ffdata.log && rm /var/ffdata/ffdata.log 1 3 * * * www-data find /var/ffdata/mv/ -type f -ctime +1 -delete */15 * * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/lperf.py 8 * * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/routes.py > /dev/null #* * * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/sendmsg.py * * * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/sendtweet.py routermsg 0 8 * * * www-data /var/www/monitor.freifunk-potsdam.de/wsgi/ff/sendtweet.py netstate # Influx stuff 3 * * * * root /root/influxdb_cq.sh hour > /dev/null 2>&1 13 1 * * * root /root/influxdb_cq.sh day > /dev/null 2>&1 27 4 7 * * freifunk /home/freifunk/influxdump.sh
Dashboards
eine Location (Verbund aus mehreren Knoten) anlegen
Beispiel: ich möchte folgende Knoten gruppieren:
- 254-142-ph-werkstatt
- 254-54-ph-up
- 254-119-ph-buero
- 254-86-ph-seminar
- 254-155-ph-heizraum
Vorgehensweise
- bei Grafana einloggen
- im HOME Dashboard am besten ein Dashboard wählen (einer Location) und dieses dann klonen (Einstellungen -> save as)
- die Templating variable $host editieren (Einstellungen -> Templating)
- also z.B. für die oberen Knoten folgenden Regex angeben: /254-142-|254-54-|254-119-|254-86-|254-155-/
- nach Klick auf update sieht mensch auch, ob der Regex die richtigen Knoten getroffen hat
- für Zusatzinfos auf das Dashboard gehen, dann Settings, im Reiter Links können Infos, wie z.B. die Webseite vom Verein der Location verändert/hinzugefügt werden
- die Hosts List aktualisieren: neben hosts auf die Nodes klicken und die aufgelisteten alle anklicken
- nun eventuell noch das Zeitintervall ändern (oben rechts)
- am Ende Dashboard abspeichern & fertig