Tobias ScheibleCybercrime Dozent & Live Hacking Speaker
Jitsi Meet Server Auslastung

Jitsi Meet Server Auslastung

Jitsi Meet ist aktuell ein sehr populärer Service. Zum Teil sind einige Server stark ausgelastet, so dass es zu Problemen kommen kann. Um die Auslastung einer Instanz darzustellen, hilft eine Statistik. Jitsi Meet hat dazu bereits ein Feature integriert, das sehr einfach aktiviert werden kann.

Montag, 11. Mai 2020
17 Kommentare

03.02.2021 Update: Mehrere kleine Änderungen.

Die frei verfügbare Open-Source-Applikation Jitsi Meet für Online-Meetings kann sehr einfach ohne eine Installation mit einem Webbrowser genutzt werden. Neben den zahlreichen öffentlichen Jitsi Meet Instanzen kann ein eigener Server installiert werden. Je nach Anzahl der Teilnehmer ist der Server unterschiedlich stark ausgelastet. Vor allem die verfügbare CPU-Leistung stellt oft den limitierenden Faktor dar, da die Umwandlung der Videostreams ressourcenintensiv ist.

Daher ist es wichtig, die Auslastung des Jitsi Meet Servers im Blick zu haben, um bei Bedarf die Videoqualität zu reduzieren, um den Server zu entlasten. Jitsi Meet bzw. die dahinterstehende Videobridge hat bereits eine Statistikfunktion integriert, die nur aktiviert werden muss.

Öffentlicher Jitsi Meet Server (meet.scheible.it):

Jitsi Meet Statistik

Die Videobridge ist der Teil von Jitsi Meet, die die Videos umwandelt und bereitstellt. Somit ist es die zentrale Komponente mit der größten Last bei einer Videokonferenz. Die Konfigurationsdatei der Jitsi Videobridge befindet sich im Verzeichnis /etc/jitsi/videobridge/ und besitzt den Namen config ohne Dateiendung. Dort muss die folgende Zeile angepasst werden:

// /etc/jitsi/videobridge/config
16: JVB_OPTS="--apis=rest,xmpp"

In einer weiteren Konfigurationsdatei, der sip-communicator.properties im selben Verzeichnis, muss überprüft werden, ob die folgenden Einträge vorhanden sind. Wenn nicht, müssen sie entsprechend angepasst bzw. hinzugefügt werden.

// /etc/jitsi/videobridge/sip-communicator.properties
3: org.jitsi.videobridge.ENABLE_STATISTICS=true
4: org.jitsi.videobridge.STATISTICS_TRANSPORT=muc,colibri

Danach muss noch die Videobridge neu gestartet werden:

service jitsi-videobridge2 restart

Nun kann die Statistik über die folgende URL aufgerufen werden (meet.example.com muss durch die eigene Domain ersetzt werden):

http://meet.example.com:8080/colibri/stats

Fall die URL nicht im Webbrowser aufgerufen werden kann, liegt es daran, dass Ihr davor die Hauptdomain meet.example.com aufgerufen habt. Dort ist ein HTTP-Header gesetzt, der den Aufruf von HTTPS erzwingt. Da die Statistik nicht per HTTPS verfügbar ist, läuft die Anfrage ins Leere. Wird eine Firewall verwendet, muss noch der TCP Port 8080 freigegeben werden.

Die Ausgabe der Jitsi Meet Statistik im JSON-Format sieht wie folgt aus:

{ "inactive_endpoints":0, "inactive_conferences":0, "total_ice_succeeded_relayed":0, "total_loss_degraded_participant_seconds":0, "bit_rate_download":0, "muc_clients_connected":1, "total_participants":0, "total_packets_received":0, "rtt_aggregate":0.0, "packet_rate_upload":0, "p2p_conferences":0, "total_loss_limited_participant_seconds":0, "octo_send_bitrate":0, "total_dominant_speaker_changes":0, "receive_only_endpoints":0, "total_colibri_web_socket_messages_received":0, "octo_receive_bitrate":0, "loss_rate_upload":0.0, "version":"2.1.169-ga28eb88e", "total_ice_succeeded":0, "total_colibri_web_socket_messages_sent":0, "total_bytes_sent_octo":0, "total_data_channel_messages_received":0, "loss_rate_download":0.0, "total_conference_seconds":0, "bit_rate_upload":0, "total_conferences_completed":0, "octo_conferences":0, "num_eps_no_msg_transport_after_delay":0, "endpoints_sending_video":0, "packet_rate_download":0, "muc_clients_configured":1, "conference_sizes":[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "total_packets_sent_octo":0, "conferences_by_video_senders":[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "videostreams":0, "jitter_aggregate":0.0, "total_ice_succeeded_tcp":0, "octo_endpoints":0, "current_timestamp":"2020-04-17 23:14:38.468", "total_packets_dropped_octo":0, "conferences":0, "participants":0, "largest_conference":0, "total_packets_sent":0, "total_data_channel_messages_sent":0, "total_bytes_received_octo":0, "octo_send_packet_rate":0, "conferences_by_audio_senders":[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "total_conferences_created":0, "total_ice_failed":0, "threads":37, "videochannels":0, "total_packets_received_octo":0, "graceful_shutdown":false, "octo_receive_packet_rate":0, "total_bytes_received":0, "rtp_loss":0.0, "total_loss_controlled_participant_seconds":0, "total_partially_failed_conferences":0, "endpoints_sending_audio":0, "total_bytes_sent":0, "mucs_configured":1, "total_failed_conferences":0, "mucs_joined":1
}

Grafana Dashboard

Die Daten von Jitsi Meet können nun weiterverarbeitet werden. Eine beliebte Methode ist die Verwendung des Grafana Dashboards. Die Open-Source-Software Grafana kann selbst auf einem Server installiert werden und stellt ein flexibel konfigurierbares Dashboard bereit. Die Einrichtung eines Grafana Dashboards beschreibe ich im Artikel „Jitsi Meet Statistik als Grafana Dashboard“.

Der untenstehende Screenshot zeigt das Grafana Dashboard meines Jitsi Meet Servers.

Grafana Dashboard - Jitsi Meet
Jitsi Meet Statistik als Grafana Dashboard
Jitsi Meet - Grafana DashboardJitsi Meet Statistik als Grafana Dashboard

Statistik einbinden

Auf meiner eigenen Jitsi Meet Instanz habe ich die wichtigsten Daten zur Nutzung direkt eingeblendet. Dies kann entweder direkt auf dem Jitsi Meet Server selbst geschehen oder extern, wenn die Daten noch weiter verarbeitet werden sollen.

Jitsi Meet Teilnehmer
Jitsi Meet Statistik
Jitsi Meet AuslastungJitsi Meet Statistik

Daten lokal einbinden

Um das Problem mit der fehlenden HTTPS-Verbindung zu umgehen, wird die Jitsi Meet Statistik per wget heruntergeladen. Da die CPU-Auslastung und die RAM-Nutzung nicht in der Jitsi Meet Statistik vorhanden sind, werden diese ebenfalls regelmäßig generiert. Dazu läuft auf dem Jitsi Meet Server ein Cronjob, der alle 20 Sekunden die Daten erhebt und die Ergebnisse in das Verzeichnis des Webservers schreibt.

#!/bin/bash
# cpu
awk '{u=$2+$4; t=$2+$4+$5; if (NR==1){uu1=u; tt1=t;} else print ($2+$4-u1) * 100 / (t-t1) ""; }' <(grep 'cpu ' /proc/stat) <(sleep 1;grep 'cpu ' /proc/stat) > /usr/share/jitsi-meet/cpu.txt
#memory
free -m | awk 'NR==2{printf "%s", $3 }' > /usr/share/jitsi-meet/memory.txt
# statistic
rm /usr/share/jitsi-meet/stats.json
curl http://127.0.0.1:8080/colibri/stats >> /usr/share/jitsi-meet/stats.json

Mir ist aufgefallen, dass die Berechnung der CPU-Auslastung zum Teil nicht korrekt ist. Je nach Server Modell (Dedicated oder virtualisiert) habe ich unterschiedliche Ergebnisse erhalten. Hier hilft eine alternative Berechnung, die etwas länger läuft, um einen besseren Durchschnittswert zu erhalten. Dazu muss die dritte Zeile durch die folgenden Anweisungen ersetzt werden:

top -b -n2 -p 1 | fgrep "Cpu(s)" | tail -1 | awk -F'id,' -v prefix="$prefix" '{ split($1, vs, ","); v=vs[length(vs)]; sub("%", "", v); printf "%s%.1f%%\n", prefix, 100 - v }' > /usr/share/jitsi-meet/cpu2.txt
rm /usr/share/jitsi-meet/cpu.txt
mv /usr/share/jitsi-meet/cpu2.txt /usr/share/jitsi-meet/cpu.txt

Die entsprechenden Einträge in der Crontab sehen wie folgt aus:

* * * * * /root/stat.sh
* * * * * sleep 20; /root/stat.sh
* * * * * sleep 40; /root/stat.sh 

Auf dem Jitsi Meet Server habe ich in die Datei welcomePageAdditionalContent.html den folgenden HTML-Code eingefügt:

Aktuelle Nutzung: X Konferenzen mit X Teilnehmer | X.X% CPU und X.X% RAM

Direkt darunter folgt der JavaScript-Code, der die aggregierten Daten ausliest und in die entsprechenden Platzhalter schreibt:

<script>	var totelram = 8192; // Arbeitsspeicher in MB	fetch('https://meet.example.com/stats.json').then(function (response) {return response.json();}).then(function (data){document.getElementById('x-conferences').innerHTML = data.conferences;document.getElementById('x-participants').innerHTML = data.participants;}).catch(function (err){console.warn('Something went wrong.', err);});	fetch('https://meet.example.com/cpu.txt').then(response => response.text()).then(data => { document.getElementById('x-cpu').innerHTML = parseFloat(data).toFixed(1)});	fetch('https://meet.example.com/memory.txt').then(response => response.text()).then(data => {var memory =100/totelram*data; document.getElementById('x-memory').innerHTML = memory.toFixed(1)});
</script>

Daten extern zusammenfassen

PHP

Werden die Daten an einer anderen Stelle noch weiterverarbeitet, können sie einfach mit einem PHP-Script zusammengefügt werden. Auf einem weiteren Webserver mit PHP befindet sich dazu das folgende Script:

// jitsi statistic $ch0 = curl_init(); curl_setopt($ch0, CURLOPT_URL, "http://meet.example.com:8080/colibri/stat"); curl_setopt($ch0, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch0, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch0); curl_close($ch0); $arr = json_decode($response, TRUE); //cpu $ch1 = curl_init(); curl_setopt($ch1, CURLOPT_URL, "https://meet. example.com/cpu.txt"); curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true); $cpu = curl_exec($ch1); curl_close($ch1); // memory $ch2 = curl_init(); curl_setopt($ch2, CURLOPT_URL, "https://example.com/memory.txt"); curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); $memory = curl_exec($ch2); curl_close($ch2); $arr['cpu'] = str_replace("\n","",$cpu); $arr['memory'] = 100 / 8000 * $memory; echo json_encode($arr); 

Zusätzlich können die Daten in einer Datenbank gespeichert werden und damit ein eigens Jitsi Meet Dashboard kreiert werden.

JavaScript

An dem HTML-Code ändert sich auf der Jitsi Meet Seite nichts. Nur der JavaScript-Code muss angepasst werden.

<script> fetch('https://example.com/jitsti-stat.php).then(function (response) {return response.json(); }).then(function (data){ document.getElementById('x-conferences').innerHTML = data.conferences; document.getElementById('x-participants').innerHTML = data.participants; document.getElementById('x-cpu').innerHTML = parseFloat(data.cpu).toFixed(1); document.getElementById('x-memory').innerHTML = parseFloat(data.memory).toFixed(1); }).catch(function (err) { console.warn('Something went wrong.', err); });
</script>

Jitsi Meet Artikelserie

Dieser Blogbeitrag ist Teil der Artikelserie „Videokonferenzen mit Jitsi Meet“, die sich mit dem Open-Source-Webkonferenzsystem Jitsi für Video-, Web- und Telefonkonferenzen beschäftigt. Die Artikelserie zu Jitsi Meet umfasst die folgenden Themen:


Jitsi Meet Artikel für Anwender


Jitsi Meet Artikel für Administratoren

Changelog

03.02.2021Mehrere kleine Änderungen.

06.01.2021Berechnung der CPU-Auslastung erweitert.

15.07.2020Abschnitt über das Grafana Dashboard angepasst.

23.05.2020Erweiterungen CronJob und JavaScript-Code hinzugefügt.

20.05.2020Weitere Variante der Einbindung hinzugefügt.

Über Tobias Scheible

Tobias Scheible

Hallo, mein Name ist Tobias Scheible. Ich bin begeisterter Informatiker und Sicherheitsforscher mit den Schwerpunkten Cyber Security und IT-Forensik. Mein Wissen teile ich gerne anhand von Fachartikeln hier in meinem Blog und in meinem Fachbuch. Als Referent halte ich Vorträge und Workshops für Verbände und Unternehmen u. a. auch offene Veranstaltungen für den VDI und die IHK.