Es kommt mehr und mehr: Die Abkehr von Google Analytics und Co. Der Grund dürfte nicht nur DSGVO sein sondern auch die zunehmenden Cookie-Fenster. Das nervt. Nicht die DSGVO sondern die Cookie-Fenster. Sie wollen uns fragen, ob wir einem Tracking zustimmen. Und das für jede einzelne Website, die wir besuchen. Warum das Cookie-Fenster nicht einfach weglassen? Das geht, wenn man eben kein krasses Tracking betreibt. Analytics-Daten kann man deswegen trotzdem sammeln. Wie das mit Matomo und NGINX geht, steht in diesem Artikel.
Matomo installieren
Klar ist: Man benötigt Matomo (ehemals Piwik) und es muss laufen. Auf dem eigenen Server, dem eigenen Webspace oder gehostet bei matomo.com. Ganz egal. Auf eine Anleitung verzichte ich gezielt, weil es da schon sehr viele Tipps und Tricks im Web gibt. Zum Beispiel hier bei Matomo direkt in englisch oder z.B. hier auf deutsch.
Alles weitere bezieht sich nun auf ein Ubuntu System:
NGINX konfigurieren
Danach muss NGINX konfiguriert so werden, so dass die Log-Dateien entsprechende Daten enthält, die Matomo lesen kann. Dazu ergänzt man in der nginx.conf
und innerhalb eines http {}
-Blocks folgende Zeilen:
log_format matomo '{'
'"ip": "$remote_addr",'
'"host": "$host",'
'"path": "$request_uri",'
'"status": "$status",'
'"referrer": "$http_referer",'
'"user_agent": "$http_user_agent",'
'"length": $bytes_sent,'
'"generation_time_milli": $request_time,'
'"date": "$time_iso8601"}';
Wie man sieht, wird pro Zugriff eine JSON-Zeile ausgegeben. Das Parsen ist damit recht einfach.
In der Regel ist NGINX so konfiguriert, dass man im Verzeichnis sites-enabled
alle Seiten sieht, die auf einem Server konfiguriert wurden. Dort öffnet man die nötige Datei für seine Domain und ergänzt im server {}
-Block folgende Zeilen:
access_log /var/log/nginx/meine-seite.de.access.log matomo;
Wir weisen NGINX also an, das zuvor gewählte Log-Format zu nehmen und in die Datei meine-seite.de.access.log
zu schreiben.
Den Neustart nicht vergessen:
sudo service nginx restart
Einlesen der Log-Dateien in Matomo
Dazu liefert Matomo bereits ein Script mit. Das findet man indem Verzeichnis, indem man es installiert hat. In meinem Beispiel also hier: /var/www/matomo.meine-seite.de/htdocs/misc/log-analytics/import_logs.py
Zum Einlesen benötigt man Python3.6, weil es sonst zu einem JSON-Fehler kommt. Im Terminal lässt sich folgendes ausführen um die einzelnen Zeilen zu importieren:
python3.6 /var/www/matomo.meine-seite.de/htdocs/misc/log-analytics/import_logs.py --url=https://matomo.meine-seite.de --idsite=1 --log-format-name=nginx_json --enable-http-redirects --enable-static --enable-http-errors --recorders=4 --token-auth=abcdefg /var/log/nginx/meine-seite.de.access.log
Wichtig sind hier folgende Parameter:
- –url: Die URL, auf der Matomo erreichbar ist.
- –idsite: Die ID der Site in Matomo.
- –token-auth: Der Autho-Token ist quasi das Passwort, mit dem überhaupt erst geloggt werden kann. Hier steht, woher man ihn bekommt.
- –recorders: Anzahl der gleichzeitigen Schreibvorgänge (sollte die Anzahl der am Server vorhandenen Prozessoren entsprechen).
- –enable-http-errors: Damit auch HTTP-Fehler aufgezeichnet werden.
- –enable-http-redirects: Damit auch HTTP-Weiterleitungen aufgezeichnet werden.
Weitere Einstellungsmöglichkeiten gibt es natürlich auch. Wer mehr darüber erfahren will, liest gerne bei Github weiter.
Automatisieren
Fehlt nur noch ein Schritt: Das automatische Einlesen der Logdateien. Ich habe das mit dem Programm logtail
gelöst. Folgendes im Terminal ausführen:
logtail /var/log/nginx/meine-seite.de.access.log | python3.6 /var/www/matomo.meine-seite.de/htdocs/misc/log-analytics/import_logs.py --url=https://matomo.meine-seite.de --idsite=1 --log-format-name=nginx_json --enable-http-redirects --enable-static --enable-http-errors --recorders=4 --token-auth=abcdefg -
Wichtig: Hinter ...nginx/meine-seite.de.access.log
befindet sich ein Querstrich (|). Und das letzte Zeichen ist tatsächlich auch ein Minus (-).
Was macht Logtail? Es liest nur die Zeilen ein, die nicht schon gelesen wurden. Ergo werden nur die Zeilen eingelesen, die neu sind.
Dafür könnte man sich jetzt einen Cronjob einrichten:
@horuly logtail /var/log/nginx/meine-seite.de.access.log | python3.6 /var/www/matomo.meine-seite.de/htdocs/misc/log-analytics/import_logs.py --url=https://matomo.meine-seite.de --idsite=1 --log-format-name=nginx_json --enable-http-redirects --enable-static --enable-http-errors --recorders=4 --token-auth=abcdefg -
Achtung bei automatischem Splitting der Logfiles
Wenn man (sehr) viele Zugriffe hat, werden die Logfiles eventuell auf mehrere Dateien zerlegt oder gar gezippt. Das passiert in der Regel mit einem Programm wie Logrotate. Es kann also vorkommen, dass die Logdatei gesplittet wird bevor sie final eingelesen werden konnte. Um das zu vermeiden, muss man die Logrotate-Konfiguration für NGINX anpassen:
nano /etc/logrotate.d/nginx
Die Datei sieht ungefähr so aus:
/var/log/nginx/*.log {
size 10M
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
Zwischen prerotate
und endscript
(Zeile 10 bis 14) lässt sich definieren, was passieren soll, bevor die Datei rotiert wird. Laut Manpage wird als erster Parameter der Dateipfad übergeben. Das kann man nutzen um verschiedene Dinge zu machen. Unter anderem, um die Daten in Matomo zu loggen:
/var/log/nginx/*.log {
size 10M
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
if [ $1 = '/var/log/nginx/meine-seite.de.access.log' ]
then
logtail /var/log/nginx/meine-seite.de.access.log | python3.6 /var/www/matomo.xc-ski.de/htdocs/misc/log-analytics/import_logs.py --url=https://matomo.xc-ski.de --idsite=2 --log-format-name=nginx_json --enable-http-redirects --enable-static --enable-http-errors --recorders=4 --token-auth=abcdefg -
fi
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
Neu hinzugefügt wurden die Zeilen 14 bis 17.
Fertig! 😉