Für mehr Privatsphäre: Matomo Logging aus NGINX mit Logtail

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! 😉