Diese Seite wurde vor mehr als 2 Jahren erstellt und vor über einem Monat zuletzt bearbeitet. Eventuell ist längst ihr Mindesthaltbarkeitsdatum überschritten!
Ein Log (hier das Protokoll von DNSmasq) auf einem Server soll live angezeigt werden, ohne jedes Mal mit SSH zu
verbinden und ein tail -f
ausführen zu müssen.
<div>
mit Zeilen der Logdatei<div>
live bei neuen Websocket-MeldungenAuch hier gilt: Dies ist ein Rohgerüst ohne Fehlerbehandlung. "Works for me", macht was draus.
websocketd
(Sourcen, Download) kann die Ausgabe
eines beliebigen Skripts oder Binaries, das auf stdout
schreiben kann, via Websocket
bereit stellen.
Das Skript /pfad/zum/skript/service_ws_dhcplog.sh
zur Anzeige der letzten N Zeilen startet einen Websocket
auf 127.0.0.1, Port 8000:
#!/bin/bash
# Open a websocket on 127.0.0.1:8000
websocketd --address=127.0.0.1 --port=8000 --loglevel=info tail -F -n 100 /var/log/dnsmasq.log
Einen neuen System-Dienst anlegen — hier unter Ubuntu/Debian. Als Namen z.B. ws-dnsmasq
verwenden. Der Inhalt der
Dienst-Konfiguration, /etc/systemd/system/ws-dnsmasq.service
:
[Unit]
Description=Websocket Port 8000: DNSmasq-logfile
After=network.target
After=systemd-user-sessions.service
After=network-online.target
[Service]
User=root
WorkingDirectory=/pfad/zum/skript/
Type=simple
ExecStart=/pfad/zum/skript/service_ws_dhcplog.sh
TimeoutSec=30
Restart=on-failure
RestartSec=30
StartLimitInterval=350
StartLimitBurst=10
[Install]
WantedBy=multi-user.target
Der Service startet das Bash-Skript als Dienst. Aktivieren/bekanntmachen mit systemctl daemon-reload
,
Starten mit service ws-dnsmasq restart
.
Aktivieren der Proxy-Module:
# Proxy - https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
a2enmod proxy
# HTTP-Proxy - https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html
a2enmod proxy_http
# Proxy zu Backend-Websocket - https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
a2enmod proxy_wstunnel
Folgendes in die Konfiguration des (HTTPS-)Virtual Hosts einfügen:
# Websocket
# --------------------------------------------------------------------
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:8000/$1 [P]
ProxyPass /ws ws://127.0.0.1:8000/
In den (HTTPS-)Server Block einfügen:
# Websocket
# ----------------------------------------------------------------------------
location /ws/ {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host 127.0.0.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
add_header X-location websocket always;
}
Das Dokument benötigt jQuery sowie das weiter unten stehende Javascript:
...
<!-- Datum/Uhrzeit aktuell -->
<span id='clock'></span>
<!-- Status Websocket -->
<span id='websocket_status'></span>
<!-- Letzte Message vor N Sekunde(n) -->
<span id='websocket_ago'></span>
<!-- Datum/Uhrzeit letzte Message -->
<span id='websocket_timestamp'></span>
<!-- Timestamp letzte Message, unsichtbar -->
<span id='websocket_last_timestamp' style='display: none;'></span>
<!-- Anzeige Logdatei -->
<pre id='livelog' class='livelog' style='height: 600px;'></pre>
<!-- jQuery -->
<script src="jquery-3.6.0.min.js"></script>
<!-- JavaScript -->
<script src='ws.js'></script>
...
Das Skript ws.js
. Anpassen von vhost.domain.com
.
Nix 127.0.0.1! Dieses Skript läuft im Browser, Hostnamen des Servers eintragen!
/* Ziel-WS auf vhost.domain.com:8000 - ws:// bei HTTP, wss:// bei HTTPS */
var socket_address = 'wss://vhost.domain.com/ws/';
var message_counter = 0;
/* Hallo! */
console.log('Connecting to websocket '+socket_address);
/* WS initialisieren */
var webSocket = new WebSocket(socket_address);
/* WS Error */
webSocket.onerror = function(event) {
onError(event)
};
/* WS Open */
webSocket.onopen = function(event) {
onOpen(event)
};
/* WS Message */
webSocket.onmessage = function(event) {
onMessage(event)
};
/* Event Message */
function onMessage(event) {
/* Timestamp jetzt */
var timeStamp = $.now();
/* Datum jetzt */
var date = new Date(timeStamp);
/* Zähler +1 */
message_counter = message_counter+1;
/* Feld Status */
$('#websocket_status').html('Message received. Total: '+message_counter);
/* Feld Datum */
$('#websocket_timestamp').html(date);
/* Feld Timestamp */
$('#websocket_last_timestamp').html(timeStamp);
/* Feld Messages: Anhängen */
$('#livelog').append('<br />' + event.data);
/* Feld Messages: Scrollen */
$('#livelog').animate({
scrollTop: $('#livelog').get(0).scrollHeight}, 10);
$('#livelog').scrollLeft();
/* Konsole */
console.log('New Message (#' + message_counter + ')');
}
/* Event Open */
function onOpen(event) {
$('#websocket_status').html('Opened');
console.log('WebSocket: Opened');
}
/* Event Error */
function onError(event) {
$('#websocket_status').html('Error :'+JSON.stringify(event));
console.log('Websocket: Error '+JSON.stringify(event));
}
/* Event Ready */
$(document).ready(function() {
clockUpdate();
/* Jede Sekunde */
setInterval(clockUpdate, 1000);
})
/* Uhrzeit und vergangene Zeit seit letztem Empfang */
function clockUpdate() {
/* Jetzt */
var date = new Date();
/* Timestamp letzter Empfyng */
var last_message = $('#websocket_last_timestamp').html();
/* Uhr */
$('#clock').html(Date());
/* Differenz Uhrzeit letzte Message zu jetzt in Sekunden */
var ago_difference = (date - last_message) / 1000;
/* Vor X Sekunden */
$('#websocket_ago').html(parseInt(ago_difference));
};
Bei Zugriff über HTTP und HTTPS muss mit einer Hilfskonstruktion eventuell auch das Protokoll für den Websocket im
Javascript (ws
/wss
) angepasst werden. Tipp:
var protocol = 'ws://';
if (window.location.protocol === 'https:') {
protocol = 'wss://';
}
var socket_address = protocol+ "vhost.domain.com/ws/";
Ansicht mit einem gefilterten dnsmasq.log
(dhcp-script = ...
):