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.
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.
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
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.
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
- Liste mit öffentlichen Jitsi Meet Instanzen
- Anleitung für Jitsi Meet Videokonferenzen
- Jitsi Meet Anleitung für Moderatoren
- Jitsi Meet für Smartphones und Tablets
- Jitsti Meet Nutzung per Desktop App
- Tipps und Tricks mit Jitsi Meet
- Meine eigene Jitsi Meet Instanz
- Jitsi Meet Server mit ressourcensparender Konfiguration
- Neuer Jitsi Meet Testserver (Nightly Builds)
- Virtuelle Webcam in Jitsi Meet verwenden
- Virtuelle Desktops für die Freigabe nutzen
- Neues zu Jitsi Meet – Update und Server
- Breakout Rooms in Jitsi Meet
Jitsi Meet Artikel für Administratoren
- Installation eines eigenen Jitsi Meet Servers
- Jitsi Meet unter Ubuntu 20.04 installieren
- Mehrere Jitsi Meet Varianten per API
- Geschwindigkeitsoptimierung von Jitsi Meet
- Das Design von Jitsi Meet anpassen
- Datenschutzfreundliche Konfiguration von Jitsi Meet
- Jitsi Meet Update Script
- Jitsi Meet Server Auslastung
- Jitsi Meet Statistik als Grafana Dashboard
- Neues Jitsi Meet Feature: Lobby Wartebereich
- Jitsti Meet und die Log4Shell Sicherheitslücke
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.
Hallo Tobias,
nachdem ich mich schon deiner Kompetenten Informationen bezüglich Jitsi-Meet bedient habe, wird es mal Zeit, einfach DANKE zu sagen!
Klasse, wie detailliert und einfach du die Konfiguration bisher erklärt hast – 1A! 😉
Super wäre, wenn du dich dem Thema „Secure Domain“, bzw. schließen der offenen Jitsi-Instanz annehmen würdest. Ich habe dazu zwar eine Page gefunden, aber bei einem ersten Test habe ich mir ziemlich die Konfig. zerschossen. 😉
URL: https://dev.to/noandrea/self-hosted-jitsi-server-with-authentication-ie7
Vorab vielen Dank und mach weiter so…
VG
Oliver