Linux, Speedtest, Netzwerk · 22 min read · Nov 11, 2025
So verwenden Sie Speedtest auf einem Linux-Server, um Internetgeschwindigkeiten grafisch zu überprüfen, zu speichern und zu berichten
Nach einer Reihe von Problemen mit einer schlechten Breitbandverbindung, die ich erlebt habe, beschloss ich, dass ich die Mbps-Geschwindigkeit, die ich von meinem Anbieter erhielt, regelmäßig überwachen wollte. Besonders schlechte Werte sah ich, als ich versuchte, abends Dateien herunterzuladen, während ich sehr früh am Morgen viel schnellere Geschwindigkeiten erzielte.
Ich habe einen Linux Debian-Server, der in einer Ecke steht und meine Test- und Entwicklungsmaschine für ISPConfig-gehostete Websites ist, sowie einige Let’s Encrypt-Codes, mit denen ich gerne experimentiere. Daher suchte ich nach einer Software, die Bandbreitentests ermöglicht, die von einer Linux-Befehlszeile aus ausführbar ist und die Grundlage für ein automatisiertes Shell-Skript-System bilden könnte, um die Rohdaten zu erzeugen, die ich benötigte. Ich wollte die Daten in einer SQL-Datenbank speichern, um die Abfrage zu vereinfachen (ich könnte dann leicht mehr Daten sammeln und einfach eine kleinere Teilmenge für Zeiträume extrahieren, die mich interessierten) und ein Web-Frontend haben, das ein einfaches Diagramm zur Visualisierung der Daten erzeugen und helfen könnte, die Verbindungsprobleme hervorzuheben.
Das erste Ergebnis meiner Suche war der wirklich nützliche Artikel von Antonio Valencia unter: https://www.howtoforge.com/tutorial/check-internet-speed-with-speedtest-cli-on-ubuntu/
Nachdem ich die Anweisungen dort befolgt hatte, um Speedtest zu installieren, zeigte ein schneller Test, dass ich es verwenden konnte, um Tests gegen eine breite Palette von Internetservern durchzuführen und auch Ausgaben im CSV-Format zu erzeugen, das sich gut für den direkten Import in eine SQL-Tabelle mit minimalem Aufwand in der Softwareentwicklung eignet.
Für die relativ geringe Menge an Daten, die erzeugt werden würden, entschied ich mich, SQLite als Backend-Speicher zu verwenden, und eine schnelle Suche nach den verfügbaren Open-Source-JavaScript-basierten Diagrammbibliotheken führte mich zu chart.js, das ein einfaches, sauberes Design mit einer einfachen Datenoberfläche hat, aber viele Möglichkeiten bietet, erweiterte Optionen bei Bedarf anzupassen. SQL-Daten zu konvertieren, um nur die Teilmenge der Daten zu extrahieren, die ich grafisch darstellen wollte, mit Ausgabe über JSON über einige einfache PHP-Codes, war der richtige Weg.
Insgesamt musste ich ein System entwerfen, das so aussah:
Ein Linux-Server, der Speedtest als Cronjob ausführt - vielleicht 1 pro Stunde - wobei die Speedtest-Ausgabe in einer SQLite-Datenbank gespeichert wird - alles gesteuert durch eine Bash-Shell-Skriptdatei. Ein Web-Frontend, das eine Mischung aus HTML, CSS, JavaScript und PHP ist, um Daten aus SQLite zu extrahieren und ein Balkendiagramm zu erzeugen, das die erreichten Mbps-Zahlen für die vorhergehenden 24 Stunden (oder einen anderen Zeitraum, den ich entscheiden könnte) zeigt.
Ein wenig Experimentieren mit dem Ausführen von Speedtest ein Dutzend Mal oder mehr interaktiv zeigte mir, dass es einige Server gab, die Ergebnisse lieferten, die eng mit den Geschwindigkeiten übereinstimmten, die ich erlebte. Ich hielt es für eine gute Idee, gegen mehr als einen Server zu testen, um ein besseres Verständnis dafür zu bekommen, wie meine Mbps-Zahlen von der Lage des Zielservers und der Tageszeit in einer anderen Zeitzone beeinflusst wurden.
Wenn Sie folgen und ein ähnliches System für sich selbst einrichten möchten, müssen Sie einen oder mehrere Server aus den Hunderte auswählen, die für Speedtest zur Verfügung stehen und die für Ihren Standort geeignet sind.
1 Voraussetzungen
- ein Linux-Server - ich verwende Debian 9.1 - stretch
- tty-Zugriff auf den Server mit Root-Login - ich verwende PuTTY von einem Windows-Laptop
- ISPConfig installiert und eine Website mit einem FTP-Konto konfiguriert - ich verwende 3.1.6 mit Apache als Webserver (Sie könnten auch nur mit einem Webserver auskommen, mit einigen geringfügigen Änderungen an den folgenden Anweisungen)
- PHP - ich verwende 7.0, aber das sollte auch mit den meisten vorherigen Versionen funktionieren
- FTP-Client - ich verwende Filezilla - und PureFTPd, das auf dem Server läuft
- nano - oder Ihren bevorzugten visuellen Editor
Ich gehe davon aus, dass Sie sich mit dem Anmelden auf einem Linux-Server, dem Navigieren durch die Verzeichnisse, dem Layout, wo Ihr Webserver Dateien erwartet, und dem Hochladen von Dateien in diese Verzeichnisse auskennen.
Hier sind die detaillierten Schritte, um all dies einzurichten.
2 Installieren Sie Speedtest
Melden Sie sich als Root auf Ihrem Linux-Server an und führen Sie den Befehl aus:
# pip install speedtest-cliSiehe https://www.howtoforge.com/tutorial/check-internet-speed-with-speedtest-cli-on-ubuntu/ und https://pypi.python.org/pypi/speedtest-cli für weitere Informationen, wenn Sie Probleme haben.
Hinweis: Speedtest und speedtest-cli sind auf meiner Installation identisch, daher werde ich in den folgenden Abschnitten nur auf Speedtest verweisen.
3 Installieren Sie SQLite3
# apt-get install sqlite3Verwenden Sie das Äquivalent für Ihre Distribution, wenn apt-get nicht für Sie geeignet ist.
4 Erstellen Sie bandwidth.sh
Geben Sie den folgenden Bash-Skriptcode in eine Datei ein und speichern Sie sie als /usr/local/etc/bandwidth.sh - wir werden dies später ein wenig bearbeiten, um es spezifisch für Sie zu machen.
#!/bin/bash
# Führen Sie Speedtests gegen 3 Server aus und speichern Sie alle Ausgabewerte in einer CSV-Datei für den Import in die SQLite-Datenbank
#
# von Cronjob einmal pro Stunde ausgeführt
#
#
function getCSVString () {
# Wenn Speedtest fehlgeschlagen ist (z. B. wenn es nicht auf einen Server zugreifen konnte), müssen wir einen Dummy-Eintrag mit Null für diesen Zeitraum erstellen
# Holen Sie sich einen Zeitstempel-String im selben Format, das Speedtest erzeugt - und wir benötigen UTC-Zeit
local RIGHTNOW=$(date --utc +%Y-%m-%dT%H:%M:%SZ)
# Gegen welchen Server testen wir?
if [ $1 = "5443" ]
then
echo "5443,Fasthosts Internet,Gloucester,$RIGHTNOW,73.09,0.0,0.0,0.0"
fi
if [ $1 = "1234" ]
then
echo "1234,Uno,Milton Keynes,$RIGHTNOW,168.27,0.0,0.0,0.0"
fi
if [ $1 = "1783" ]
then
echo "1783,Comcast,\"San Francisco, CA\",$RIGHTNOW,8420.0,0.0,0.0,0.0"
fi
# Test-/Debugfall nur
if [ $1 = "199999999" ]
then
echo "99999,Test,Test,$RIGHTNOW,99.99,0.0,0.0,0.0"
fi
}
function runTest () {
# Führen Sie Speedtest gegen den benannten Server mit CSV-Ausgabe aus, die in einer temporären Datei gespeichert wird
/usr/local/bin/speedtest --csv --server $1 > /usr/local/etc/speedtest.tmp
if [ $? -gt 0 ]
then
# Speedtest fehlgeschlagen, also erstellen Sie einen Null-Eintrag anstelle einer Fehlermeldung
getCSVString $1 > /usr/local/etc/speedtest.tmp
fi
# Speichern Sie die Ausgabe für den nächsten Server-Test
cat /usr/local/etc/speedtest.tmp >> /usr/local/etc/speedtest.csv
}
# Haupt
#######
# Führen Sie Speedtest gegen 3 Server aus und speichern Sie alle Ausgabewerte in einer CSV-Datei
cd /usr/local/etc
# CSV-Datei leeren - muss zu Beginn des Laufs leer sein
rm -f /usr/local/etc/speedtest.csv
############################################
# Test-/Debugfall - zwingt Speedtest zum Fehlschlagen
############################################
# runTest "199999999"
# sleep 5
####### nach dem Testen auskommentieren ##########
############################################
runTest "5443"
sleep 10
runTest "1234"
sleep 10
runTest "1783"
sleep 1
# Jetzt importieren Sie die CSV-Daten in die SQLite-Datenbank
sqlite3 -batch /usr/local/etc/bandwidth.db <<"EOF"
.separator ","
.import /usr/local/etc/speedtest.csv bandwidth
EOF
# Fügen Sie den aktuellen Lauf-CSV zur Sicherung hinzu
cat /usr/local/etc/speedtest.csv >> /usr/local/etc/speedtest.bak
Ich entschuldige mich für meinen “Gürtel- und Hosenträger”-Ansatz, überall vollständige Pfade für Dateien zu verwenden, auch wenn dies nicht erforderlich ist. Es ist einfach die Art, wie ich es gerne mache. Fühlen Sie sich frei, dies zu verbessern, wenn Sie sich mit dem Bearbeiten von Bash-Skripten wohlfühlen.
Setzen Sie die Dateieigenschaften, um dieses Skript ausführbar zu machen:
# chmod 0700 bandwidth.sh5 Erstellen Sie eine SQLite-Datenbank
Erstellen Sie die bandwidth.db SQLite-Datenbank in /usr/local/etc:
#sqlite3 bandwidth.dbund dann, an der sqlite> Eingabeaufforderung, erstellen Sie eine neue Tabelle mit dem folgenden Befehl (vergessen Sie nicht das abschließende Semikolon):
sqlite> CREATE TABLE IF NOT EXISTS "bandwidth" ("serverid" INTEGER NOT NULL , "sponsor" VARCHAR NOT NULL , "servername" VARCHAR NOT NULL , "times" DATETIME PRIMARY KEY NOT NULL UNIQUE , "distance" FLOAT NOT NULL , "ping" FLOAT NOT NULL , "download" FLOAT NOT NULL , "upload" FLOAT NOT NULL );sqlite> .quitDies erstellt eine Tabelle namens bandwidth mit Feldern, die direkt auf das CSV-Format der Speedtest-Ausgabe abgebildet sind.
6 Holen Sie sich eine Liste von Servern
Sie benötigen eine Liste der Server, die Speedtest verwendet.
# speedtest --list > servers.txtÜberprüfen Sie nun servers.txt auf die numerischen IDs der Server, gegen die Sie Ihre Tests durchführen möchten.
# nano servers.txtDie Datei sieht ungefähr so aus:
Rufe die Konfiguration von speedtest.net ab...
5833) Hub Network Services Ltd (Newport, Wales) [57.50 km]
5938) Spectrum Internet (Cardiff, Großbritannien) [65.89 km]
5443) Fasthosts Internet (Gloucester, Großbritannien) [74.31 km]
6504) Secure Web Services Ltd (Shrewsbury, Großbritannien) [78.64 km]
7265) Unitron Systems & Development Ltd (Telford, Großbritannien) [87.11 km]
8225) Exascale Limited (Wolverhampton, Großbritannien) [96.08 km]
3110) zero.net.uk Ltd (Studley, Großbritannien) [96.12 km]
12401) Dragon WiFi LTD (Haverfordwest, Vereinigtes Königreich) [120.78 km]
1153) Warwicknet Ltd. (Coventry, Großbritannien) [125.18 km]
1685) Vodafone UK (Newbury, Großbritannien) [153.25 km]
4384) Iomart (Leicester, Großbritannien) [157.40 km]
1234) Uno (Milton Keynes, Großbritannien) [170.71 km]
3504) TNP Ltd. (Manchester, Großbritannien) [170.93 km]
11747) Vispa (Manchester, Vereinigtes Königreich) [170.93 km]
Die Server-IDs befinden sich auf der linken Seite. Die Zahl am Ende jeder Zeile ist die Schätzung, die Speedtest über die Entfernung in Kilometern zwischen Ihrem Standort und dem des Servers gemacht hat, obwohl ich mir nicht sicher bin, ob dies zu genau ist und es von Lauf zu Lauf variieren kann. Die Testserver werden in der Reihenfolge dieser Entfernung aufgelistet, beginnend mit dem nächsten. Tests gegen die Server in der oberen Liste sollten theoretisch die schnellsten Pings und die besten Download- und Uploadgeschwindigkeiten im Vergleich zu Servern weiter unten in der Liste bieten, die viel weiter entfernt sind.
7 Wählen Sie Server-IDs aus und bearbeiten Sie bandwidth.sh
Jetzt wäre es an der Zeit, Speedtest manuell gegen eine Auswahl der verschiedenen verfügbaren Server-IDs auszuführen und zu sehen, welche Ergebnisse Sie erhalten. Ich wählte ein paar Server in meiner Nähe im Vereinigten Königreich und einen in Kalifornien zum Vergleich. Das Format des zu verwendenden Befehls lautet:
# speedtest --server 1234Die Ausgabe, die Sie sehen, wird ähnlich sein:
Rufe die Konfiguration von speedtest.net ab...
Teste von xxxxxxx (n.n.n.n)...
Rufe die Serverliste von speedtest.net ab...
Wähle den besten Server basierend auf Ping...
Gehostet von Uno (Milton Keynes) [187.87 km]: 33.243 ms
Teste die Downloadgeschwindigkeit................................................................................
Download: 1.60 Mbit/s
Teste die Uploadgeschwindigkeit...............................................................................................
Upload: 0.55 Mbit/s
Sobald Sie die Server ausgewählt haben, die Sie verwenden möchten, setzen Sie die numerischen Server-IDs (ich habe 3 Server verwendet, aber Sie können dies variieren, wenn Sie möchten) in die entsprechenden Zeilen in bandwidth.sh ein.
runTest "5443"
sleep 10
runTest "1234"
sleep 10
runTest "1783"
sleep 1Sie müssen auch den Code in der Fehlerbehandlungsroutine anpassen, die einen Dummy-Eintrag erstellt, wenn Speedtest bei einem bestimmten Lauf fehlschlägt.
# Gegen welchen Server testen wir?
if [ $1 = "5443" ]
then
echo "5443,Fasthosts Internet,Gloucester,$RIGHTNOW,73.09,0.0,0.0,0.0"
fi
if [ $1 = "1234" ]
then
echo "1234,Uno,Milton Keynes,$RIGHTNOW,168.27,0.0,0.0,0.0"
fi
if [ $1 = "1783" ]
then
echo "1783,Comcast,\"San Francisco, CA\",$RIGHTNOW,8420.0,0.0,0.0,0.0"
fiDie Zahlen nach $RIGHTNOW dort (z. B. 73.09) sind die Entfernungen in Kilometern von Ihrem Standort zum betreffenden Server. Ich verwende diese nirgendwo, daher sind sie nur Platzhalter und könnten jeden numerischen Wert haben.
Beachten Sie bei diesem Beispiel 1783, dass wir die Anführungszeichen um den Standort setzen und sie entkommen müssen, um sie in die CSV-Datei zu bekommen, die wir erstellen. Die Anführungszeichen sind hier erforderlich, da dieser Standort zufällig ein Komma enthält. Ohne die entkommenen Anführungszeichen würde das Komma als CSV-Feldbegrenzer behandelt, was ein Problem beim SQLite-Import verursachen würde. Wenn der von Ihnen ausgewählte Server einen ähnlichen Standorttext mit einem Komma enthält, müssen Sie die entkommenen Anführungszeichen verwenden.
8 Richten Sie einen Cronjob ein
Richten Sie einen Cronjob ein, der einmal pro Stunde (oder so oft, wie Sie möchten, im Rahmen des Möglichen) /usr/local/etc/bandwidth.sh ausführt. Wenn Sie ISPConfig verwenden, können Sie es verwenden, um einen Cronjob zu planen.

Alternativ könnten Sie an der Linux-Befehlszeile Folgendes eingeben:
# crontab -eSie sollten etwas Ähnliches sehen (denken Sie daran, dass Sie als ‘root’ angemeldet sind):
* * * * * /usr/local/ispconfig/server/server.sh 2>&1 | while read line; do echo `/bin/date` "$line" >> /var/log/ispconfig/cron.log; done
* * * * * /usr/local/ispconfig/server/cron.sh 2>&1 | while read line; do echo `/bin/date` "$line" >> /var/log/ispconfig/cron.log; done
1 * * * * /usr/local/etc/bandwidth.sh 2>&1Wenn Sie ISPConfig nicht verwenden, könnte dies zunächst leer sein. Fügen Sie diese letzte Zeile genau wie oben gezeigt hinzu - der Abstand ist wichtig - um das Shell-Skript zu starten, das um 00:01 Uhr ausgeführt wird und dann jede Stunde, jeden Tag wiederholt. Sie können natürlich andere Zeiten wählen. (Beim allerersten Ausführen wird crontab Sie fragen, welchen Editor Sie verwenden möchten - ich wähle nano.)
9 Setzen Sie PHP open_basedir
Fügen Sie /usr/local/etc zur PHP open_basedir-Einstellung für die Website hinzu. In ISPConfig finden Sie dies im Tab Optionen für die Website.

Dies ermöglicht dem Code bandwidth.php, auf die SQLite-Datenbank zuzugreifen, die wir gerade erstellt haben, in diesem Verzeichnis.
Wir hätten dies überspringen können, wenn wir beschlossen hätten, die Datenbank in einem Verzeichnis zu erstellen, das bereits als zugänglich festgelegt ist, z. B. /var/www/clients/client1/web1/web/, aber das wäre aus Sicherheitsgründen eine schlechte Wahl.
10 Erstellen Sie bandwidth.php
Sie müssen diesen Code in eine Datei mit dem Namen bandwidth.php auf Ihrem Server im Basis-Webdokumentverzeichnis kopieren. Wenn Sie ISPConfig verwenden, wird dies etwas wie /var/www/clients/client1/web1/web/ sein.
Bandbreitenmonitor - Downloadgeschwindigkeiten in den letzten 24 Stunden
Downloadgeschwindigkeiten - letzte 24 Stunden
Bearbeiten Sie diese Datei, um die serverid zu verwenden, über die Sie berichten möchten. Ich verwende hier Server 1234 in meinem Beispiel, da ich festgestellt habe, dass dieser Server, nachdem ich einige Tage Daten untersucht habe, die Mbps-Zahlen erzeugte, die am engsten mit den Geschwindigkeiten übereinstimmten, die ich zu erhalten glaubte. Die serverid befindet sich in der WHERE-Klausel der SQL SELECT-Anweisung:
SELECT serverid, strftime("%H:%M", times) || " " || strftime("%d/%m/%Y", times) AS timestamp, sponsor, servername, download
FROM bandwidth
WHERE serverid = 1234
ORDER BY times
LIMIT 24 OFFSET (SELECT COUNT(*)/3 FROM bandwidth)-24;Was genau macht diese SQL-Anweisung? Wenn Sie mit SQL nicht vertraut sind, schauen wir uns jeden Teil an.
a. SELECT ist der Befehl zum Lesen von Datensätzen aus einer SQL-Datenbanktabelle und wird von den zu lesenden Feldern und anderen Optionen gefolgt.
b. strftime(“%H:%M”, times) || “ “ || strftime(“%d/%m/%Y”, times) AS timestamp
ist dazu da, den Zeitstempel-String, den Speedtest in seiner CSV-Ausgabe erstellt hat, in etwas benutzerfreundlicheres umzuwandeln. Ich möchte UK-formatierte Daten, also wird dies einen String wie “2017-08-31T12:02:51.898186Z” nehmen und ihn in “12:02 31/08/2017” umwandeln. Es ist einfacher, diese Umformatierung direkt in der SQL-Anweisung vorzunehmen, als sie danach verarbeiten zu müssen. Die Zeiten hier werden UTC/GMT sein, was für mich in Ordnung ist, aber Sie möchten dies möglicherweise ändern; z. B. wenn Sie US-formatierte Daten möchten, ändern Sie den zweiten Teil in strftime(“%m/%d/%Y”, times).
c. serverid, timestamp, sponsor, servername, download sind die Felder, die wir aus der SQL-Tabelle lesen und in unserem JSON-Objekt erstellen möchten.
d. FROM bandwidth ist der Name der SQL-Tabelle, aus der wir lesen.
e. WHERE serverid = 1234 legt die Teilmenge der Tabelle fest, die gelesen werden soll - ändern Sie dies, um mit der serverid übereinzustimmen, die Sie verwendet haben, und Sie möchten möglicherweise Daten für mehr als einen Server lesen - aber das wird das Diagramm komplizieren.
f. ORDER BY times legt die Sortierreihenfolge der Ausgabe fest - wir möchten, dass sie nach dem Zeitstempel sortiert wird, den Speedtest für jeden Lauf festgelegt hat.
g. LIMIT 24 beschränkt die Ausgabe auf 24 Datensätze, da wir nur 24 Stunden Daten anzeigen möchten und da unser Cronjob so eingestellt ist, dass er einmal pro Stunde ausgeführt wird. Wenn Sie zweimal pro Stunde laufen würden, müssten Sie dies auf 48 setzen, um 24 Stunden Daten zu erhalten.
h. OFFSET (SELECT COUNT()/3 FROM bandwidth)-24; wir möchten die letzten 24 Datensätze aus der Tabelle, da dies die aktuellsten Einträge sind, an denen wir interessiert sind, also müssen wir ein OFFSET angeben, um mit dem LIMIT übereinzustimmen. Ohne dies würden wir immer die ersten 24 Datensätze in der Tabelle erhalten, anstatt die 24 aktuellsten. Um das richtige Offset zu erhalten, zählen wir alle Datensätze in der Tabelle mit (SELECT COUNT()) und teilen dies dann durch 3 (da wir Speedtest 3 Mal pro Stunde ausführen, einmal für jeden der 3 verschiedenen Server) und ziehen dann 24 von dieser Gesamtzahl ab, um die richtige OFFSET-Position zu erhalten, sodass LIMIT 24 dann die Datensätze erhält, die wir möchten.
Wenn Sie das Bash-Skript geändert haben, um etwas anderes als 3 verschiedene Servertests pro Stunde auszuführen, passen Sie diesen /3-Teil entsprechend an. Wenn Sie nur gegen einen Server testen, ist die Division überhaupt nicht erforderlich.
Sie möchten möglicherweise auch die Gesamtgröße des Diagramms anpassen, wo ich den einfachen Weg gewählt habe, eine Größe zu codieren, die für meinen Bildschirm geeignet ist - sie wird in dieser Zeile festgelegt:
11 Holen Sie sich eine lokale Kopie von Dateien
Ich bevorzuge es, lokale Versionen aller CSS- und JS-Bibliotheksdateien (aber nicht Google-Schriften) zu haben, die in einer Webseite benötigt werden, und wenn Sie dasselbe tun, müssen Sie eine Kopie von Chart.bundle.min.js auf Ihren Server herunterladen und sie im Verzeichnis /var/www/clients/client1/web1/web/scripts auf Ihrem Server ablegen (oder in welchem Basisverzeichnis auch immer für Sie richtig ist).
Sie können die Datei von: https://cdnjs.cloudflare.com/ajax/libs/Chartajs/2.6.0/Chart.bundle.min.js herunterladen
Wenn Sie keine lokale Kopie verwenden möchten, bearbeiten Sie bandwidth.php, um stattdessen auf die öffentliche CDN-Version zu verweisen. Ändern Sie einfach diese Zeile:
in diese:
12 Aktivieren Sie PHP in ISPConfig
Vergessen Sie nicht, PHP in Ihren Website-Einstellungen zu aktivieren, falls dies nicht bereits festgelegt wurde.

13 Laden Sie bandwidth.php im Browser
Wir sind endlich fertig. Sobald das Shell-Skript bandwidth.sh Zeit hatte, ein paar Mal zu laufen, um einige Daten zu generieren (oder Sie könnten es anfangs manuell mehrmals ausführen), richten Sie Ihren Browser auf die Website Ihres Linux-Servers, laden Sie bandwidth.php und Sie sollten etwas sehen wie dies:

Und ja, mein Breitband ist wirklich so schlecht!
Schließlich sind hier einige zusätzliche Punkte, die es wert sind, behandelt zu werden:
14 Balkendiagrammausgabe
Wir sollten beachten, dass die Download- und Uploadzahlen, die in der SQL-Tabelle gespeichert sind, in bps und nicht in Mbps (neben einer verwirrenden Anzahl von Dezimalstellen - Zahlen wie 1533681.5922415722) vorliegen. So produziert Speedtest die Daten, wenn es im CSV-Modus ausgeführt wird. Um die Mbps-Zahl anstelle von bps auf der y-Achse des Balkendiagramms anzuzeigen, sind einige Zeilen im JavaScript-Code in bandwidth.php enthalten, um die Umwandlung durchzuführen:
mbps = Math.round(bandwidth_data[i].download/1000).toFixed(3)/1000;
bvalue = mbps.toLocaleString(undefined, { minimumFractionDigits: 3 });Die Verwendung von toLocaleString sollte die korrekte Dezimalradix-Punktuation (ein “.” oder “,”) gemäß den Locale-Einstellungen Ihres Browsers einfügen, aber dies ist implementierungsabhängig und etwas inkonsistent. Wenn Sie . anstelle von , sehen und es Sie stört, ist Globalize der Weg, dies zu beheben. Siehe ‘18 Weitere Schritte und Ideen’ unten.
Ein paar weitere Zeilen sind erforderlich, um die Standardbehandlung des Hover-Codes für nachfolgende Nullen zu überschreiben, da chart.js normalerweise “2.000” einfach als “2” anzeigt, was ich nicht möchte, insbesondere nachdem ich mir die Mühe gemacht habe, sicherzustellen, dass sie dort sind:
// wir überschreiben das Standard-Tooltip, das nachfolgende Nullen entfernt, obwohl wir sie bereits dort haben
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var value = data.datasets[0].data[tooltipItem.index];
var label = 'Download: ';
var retvalue = value.toLocaleString(undefined, { minimumFractionDigits: 3 });
return label + ' ' + retvalue + ' Mbps';
}
}
},Dies ist ein schönes Beispiel dafür, wie Sie in chart.js „hineinbohren“ und die Art und Weise ändern können, wie es Dinge tut.
Außerdem habe ich die Diagrammoptionen so eingestellt, dass der Zeitstempel auf der x-Achse für jeden Balken angezeigt wird:
xAxes: [{
ticks: {
autoSkip: false,
maxTicksLimit: 24
}
}],Die Standardoption (mit autoSkip auf true gesetzt) führte zu ein paar seltsam aussehenden Lücken in den Beschriftungen. Sie müssen maxTicksLimit ändern, wenn Sie etwas anderes als 24 Einträge anzeigen möchten.
Wenn Sie weitere Hilfe bei der Änderung von Optionen in chart.js benötigen oder wenn Sie nicht das bekommen, was Sie möchten, überprüfen Sie bitte die spezifischen chart.js Stack Overflow-Seiten - dort gibt es viele nützliche Informationen - https://stackoverflow.com/questions/tagged/chart.js - Verwenden Sie einfach das Suchfeld, um einzugrenzen, wonach Sie suchen. Leider fehlt der chart.js-Dokumentation in einigen der fortgeschritteneren Beispiele, die sicherlich eine große Hilfe wären, um mit diesem großartigen Stück Open-Source-Code schnell voranzukommen.
15 Fehlerbehandlung
Während meiner ersten Testläufe bemerkte ich ein paar Mal, dass Speedtest “Kann die Serverliste von Speedtest nicht abrufen” in der CSV-Datei meldete. Vermutlich spiegelte dies die Zeiten wider, als meine Breitbandverbindung so schlecht war, dass Speedtest nicht einmal eine Verbindung zum Testserver herstellen konnte. Dieser Text ist offensichtlich nicht in einem Format, das wir in die SQLite-Datenbank importieren möchten, also benötigte ich eine Lösung dafür, die sowohl diesen unerwünschten Text aus der CSV-Datei entfernt als auch einen Null-Eintrag in der Datenbank für den spezifischen Zeitraum enthält, da sonst jeder fehlende Eintrag in der SQL-Tabelle einfach unsichtbar wäre und auch die Ausrichtung, die ich wollte, von 24 Einträgen pro Tag beim Erstellen des Diagramms durcheinanderbringen würde.
Sie werden in bandwidth.sh sehen, dass das Skript den Exit-Code überprüft, den Speedtest mit der Skriptvariablen $? festlegt, und wenn er größer als null ist, zeigt dies an, dass Speedtest fehlgeschlagen ist. Dies wird die Funktion auslösen, um einen Dummy-CSV-Eintrag zu erstellen - der dann verwendet wird, um die CSV-Datei für diesen Lauf zu überschreiben.
Es gibt ein paar Zeilen im Bash-Skript, die auskommentiert sind, aber die diese Fehlerbehandlungsroutine testen, um einen Dummy-Null-Eintrag zu generieren, wenn Sie das Skript nach dem Auskommentieren dieser Zeilen ausführen.
############################################
# Test-/Debugfall - zwingt Speedtest zum Fehlschlagen
############################################
# runTest "199999999"
# sleep 5
####### nach dem Testen auskommentieren ##########
############################################Dies verwendet eine “Unsinn”-Server-ID, die Speedtest nicht mag, wodurch es einen nicht-null Exit-Code zurückgibt. Das Skript sollte dann einen Dummy-Eintrag erstellen, der in der SQL-Tabelle sitzen und ignoriert werden kann oder den Sie löschen könnten.
Eine andere Möglichkeit, Speedtest zum Fehlschlagen zu zwingen, wäre zu Testzwecken die Netzwerkverbindung des Servers zu entfernen. Vergessen Sie nicht, dass Sie das Skript bandwidth.sh jederzeit manuell ausführen können, Sie müssen nicht warten, bis der Cronjob es ausführt, obwohl Sie vermeiden sollten, es manuell auszuführen, wenn ein Cronjob unmittelbar bevorsteht. Wenn zwei Skripte gleichzeitig ausgeführt werden, könnte dies wahrscheinlich die CSV-Dateien durcheinanderbringen und dann die SQL-Tabelle.
Wenn das Schlimmste passiert, gibt es eine Sicherungs-CSV-Datei, die als /usr/local/etc/speedtest.bak aufbewahrt wird, die alle CSV-Ausgaben von Speedtest ab dem ersten Lauf des Bash-Skripts enthalten sollte. Diese könnte bearbeitet werden, um unerwünschte Einträge zu entfernen, die SQL-Tabelle geleert werden und dann die gesamte Menge an CSV-Einträgen erneut in SQLite importiert werden.
16 Zeitzonen
Speedtest gibt die Zeit in UTC an (im Grunde ist dies dasselbe wie Greenwich Mean Time oder GMT). Die Verwendung von UTC bedeutet, dass alle Zeiten, die in der SQL-Tabelle gespeichert sind, konsistent sind und die Sommerzeit keine unerwünschten Auswirkungen hat.
Aber das bedeutet, dass die Fehlerbehandlungsroutine in bandwidth.sh einen Zeitstempel für den Dummy-Eintrag erstellen muss, um dies widerzuspiegeln. Das ist ziemlich einfach - wir haben einfach die –utc-Option hinzugefügt:
local RIGHTNOW=$(date --utc +%Y-%m-%dT%H:%M:%SZ)Wenn Sie möchten, dass die x-Achsenbeschriftungen des Diagramms Zeiten anzeigen, die etwas anderes als UTC/GMT sind, wäre der beste Ort, eine solche Änderung vorzunehmen, in der SQL SELECT-Anweisung, z. B.:
strftime("%H:%M", time(times, 'localtime')) || " " || strftime("%d/%m/%Y", times) AS timestampDies würde die Zeitzoneneinstellungen Ihres Linux-Servers verwenden, um die angezeigten Zeiten im Diagramm anzupassen. Oder Sie könnten herausfinden, wie Globalize dies im Frontend tun könnte.
Siehe https://www.timeanddate.com/time/gmt-utc-time.html und http://www.tutorialspoint.com/sqlite/sqlite_date_time.htm für weitere Informationen.
17 Weitere Schritte und Ideen
Speedtest muss nicht die Quelle Ihrer Rohdaten sein - sie könnte von überall kommen und für alles sein, nicht nur für die Internetgeschwindigkeit. Das Prinzip ist dasselbe - ein Backend-Serverprozess, der die Rohdaten in einem nützlichen Format abrufen kann und diese dann von einem Bash-Skript in SQLite importiert, mit einem Frontend, das die Teilmenge der Daten extrahiert, die Sie möchten, und sie dann diagrammiert.
Ein komplexeres Bash-Skript könnte Daten direkt in eine SQL-Tabelle schreiben (unter Verwendung des SQL INSERT-Befehls), wenn das Formatieren als CSV keine Option ist. Wenn Sie die SQL-Tabelle entwerfen, denken Sie daran, wie Sie die Daten später extrahieren möchten.
Bei Änderungen sollten Sie den Kontext des Codes, den Sie bearbeiten, im Auge behalten; d. h. wir haben SQL-Anweisungen innerhalb von PHP-Skripten innerhalb von JavaScript innerhalb von HTML. Denken Sie an die Ebene, auf der Sie sich befinden, und codieren Sie entsprechend. Es kann leicht sein, den Überblick zu verlieren und am Ende PHP-Code dort zu schreiben, wo es JavaScript sein sollte! Ich kann garantieren, dass dies nicht funktionieren wird.
Hier sind einige Ideen für weitere Erkundungen:
- toLocaleString ist nicht konsistent in verschiedenen Browsern implementiert. Verwenden Sie Globalize und behandeln Sie alle Zahlen-, Datums- und Zeitzonenformate damit.
- Überprüfen Sie httpstat (es gibt eine Bash-Skriptversion), die es ermöglicht, verschiedene Arten von Internetverbindungsdaten zu sammeln. Speichern Sie dies in einer (separaten) SQL-Tabelle und diagrammieren Sie die Ausgabe.
- Verbessern Sie das Frontend bandwidth.php, um dem Benutzer die Wahl zwischen verschiedenen Optionen zu geben: 24, 48, 72 Stunden; ein bestimmtes Datum auswählen, Upload- und Downloaddaten, Ping-Zeiten einbeziehen.
- Konvertieren Sie das HTML, um responsiven Bootstrap-Code zu verwenden, damit es gut auf verschiedenen Geräten oder Bildschirmgrößen funktioniert.
- Erkunden Sie einige der anderen Optionen von chart.js; vielleicht ein kombiniertes Linien- und Balkendiagramm; ändern Sie die Farben und die Balkengröße.
- Ersetzen Sie SQLite durch MySQL und fügen Sie mehr Sicherheit mit Lesezugriff von PHP über Benutzer/Passwort hinzu.
- Bauen Sie ein ähnliches System, aber mit node.js.
18 Links
- Speedtest: https://github.com/sivel/speedtest-cli
- SQLite3: https://sqlite.org/
- chart.js: http://www.chartjs.org/
- Globalize: https://github.com/globalizejs/globalize
- httpstat: https://github.com/b4b4r07/httpstat
- Bootstrap: http://getbootstrap.com/
- PHP: http://www.php.net/
- ISPConfig: http://www.ispconfig.org/
- Debian: http://www.debian.org/
Erhalte neue Beiträge in deinem Posteingang.
Kein Spam. Jederzeit abmelden.