Servermonitoring 3

NGINX Webserver Monitoring

Martin Schlüter

6 Minuten

Im dritten Teil der PMM2 Servermonitoring Serie beschäftigen wir uns mit dem Monitoring des NGINX Webservers, hierzu installieren wir verschiedene Exporter und passende Grafana Dashboards.

NGINX ins Monitoring einbinden

Es gibt verschiedene Methoden um den NGINX mit ins Monitoring einzubinden, auch abhängig von der Version des NGINX, so bietet der kommerzielle NGINX+ von Haus aus gute Statistiken die man per Exporter abgreifen kann. Bei der NGINX open source Version kann man ohne weiteres nur Daten über Verbindungen abgreifen, für weitere Daten müsste man weitere Module einbinden und mit LUA scripten arbeiten, weiteren Code direkt eincompilieren oder man liest die Logfiles aus. Ich habe mich für eine Kombination aus Verbindungsdaten und Logfiles entschieden, da hier der NGINX selber problemlos upgedatet werden kann.

NGINX Verbindungen

der NGINX kann von sich aus Informationen über die bestehenden Verbindungen und deren Status mit dem Modul ngx_http_stub_status_module ausgeben, dies wird bei Ubuntu mit installiert, muss aber erst konfiguriert gehen. Hierzu editiert man die Datei /etc/nginx/sites-avaible/default

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  root /var/www/html;

  index index.html index.htm index.nginx-debian.html;

  server_name _;

  location / {
		# First attempt to serve request as file, then
	    # as directory, then fall back to displaying a 404.
	    try_files $uri $uri/ =404;
    }


    location = /basic_status {
      stub_status on;
    }
}

Wichtig ist dann im Verzeichnis /etc/nginx/sites-enabled/ zu prüfen ob die default Konfiguration auch aktiviert ist, falls nicht hier einen entsprechenden Softlink einfügen:

ln -s /etc/nginx/sites-avaible/default /etc/nginx/sites-enabled/default

Dann die Konfiguration testen und wenn kein Fehler gefunden wurde den NGINX neu starten

nginx -t

service nginx restart

jetzt kann man die Statusseite mit dem Browser über http://[serverIP]/basic_status aufrufen, sollte etwa so aussehen:

Active connections: 68
server accepts handled requests
 255299 255299 857307
Reading: 0 Writing: 1 Waiting: 66

Der passende exporter prometheus-nginx-exporter ist in den Ubuntu Paketquellen enthalten und kann so simpel per

apt install prometheus-nginx-exporter

installiert werden. Nach der Installation des Exporters muss dieser noch konfiguriert werden, dazu öffnen wir die Datei /etc/default/prometheus-nginx-exporter und fügen diese Zeile ein:

ARGS=" -nginx.scrape-uri http://127.0.0.1/basic_status"

und starten den exporter neu und melden ihn am PMM2 an:

service prometheus-nginx-exporter restart

pmm-admin add external --service-name=nginx --listen-port=9113

Als nächtes importieren wir ein passendes Dashboard für diesen Exporter. Das offizielle Dashboard für den Exporter ist Official dashboard for NGINX Prometheus exporter , wichtig ist hierbei die ID, also die 11199, diese kopieren wir oder merken sie uns einfach und fügen sie in Grafana für den Dashboard Import ein:

Den Dashboard Import öffnen
Den Dashboard Import öffnen

Im Dashboard Import die ID in das Feld für den Import von Grafana.com eingeben und laden, dann kann man noch den Namen des Dashboards, den Ordner, die Unique ID editieren und die Datenquelle auswählen, diese ist Metrics (default) und schon kann man das Dashboard importieren. Und schon zeigt es die bisher gesammelten Daten seit Start des Exporters an.

NGINX Prometheus exporter Dashboard
NGINX Prometheus exporter Dashboard

Hier wird für Beschriftung und Legende noch die instance als Variable verwendet, dies ist recht unübersichtlich, hier wurde sich eher der node_name anbieten. Da das Anpassen von Variablen etwas komplexer ist, gehen wir in einen späteren Teil dieser Monitoring Reihe da nochmal drauf ein. Wenn man aber eh nur einen NGINX im Monitoring hat, kann man auch einfach das {{instance}} aus den Panels für die Legende entfernen, wie das geht sehen wir dann beim Logfile Exporter, dort hat das Dashboard keine Variablen, aber wir müssen kleinere Anpassungen direkt in den Panels vornehmen.

NGINX Logfile Exporter

Zum auslesen der NGINX logfiles nutze ich den prometheus-nginxlog-exporter , zur Installation dort von der release Seite das aktuellste deb paket runterladen und installieren.

wget https://github.com/martin-helmich/prometheus-nginxlog-exporter/releases/download/v1.9.2/prometheus-nginxlog-exporter_1.9.2_linux_amd64.deb

apt install ./prometheus-nginxlog-exporter_1.9.2_linux_amd64.deb

Auch hier müssen wir wieder den NGINX entsprechend konfigurieren, hierzu legen wir im Verzeichnis /etc/nginx/conf.d/ die Datei logfile_exporter.conf mit folgendem Inhalt an:

log_format upstream_time '$remote_addr - $remote_user [$time_local] "$host" "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time $request_time';

und editieren die dateien für die webhosts im Verzeichnis /etc/nginx/sites-avaible/ entsprechend dass sie das neue Logformat auch verwenden:

access_log /var/log/nginx/hostx.log upstream_time;

Hier ist es dann natürlich sinnvoll dass jeweils eigene logfiles für die verschiedenen Webseiten verwendet werden. So habe ich ein /var/log/nginx/matomo.log für die Matomo Installation und ein /var/log/nginx/sudoku.log für meine Sudoku Webseiten.

Und klar, dann wieder die Konfiguration testen und den NGINX neu starten.

Da bei meiner Ubuntu Installation der NGINX die Logfiles mit dem User www-data und der Gruppe adm schreibt, muss der prometheus-nginxlog-exporter mit der Gruppe adm gestartet werden, hierzu ediert man die Datei /lib/systemd/system/prometheus-nginxlog-exporter.service und fügt direkt unter dem [Service] die Gruppenzuteilung ein:

[Service]
Group=adm

alles andere bleibt dort unverändert.

Nun brauchen wir noch die Konfiguration für den Exporter selber die /etc/prometheus-nginxlog-exporter.hcl Datei, die sieht bei mir so aus:

listen {
  port = 5040
}

namespace "Sudoku" {

  metrics_override = { prefix = "nginx" }
  namespace_label = "app"
  source = {
    files = [
      "/var/log/nginx/sudoku.log"
    ]
  }

  format = "$remote_addr - $remote_user [$time_local] \"$host\" \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" $upstream_response_time $request_time"

}

namespace "Matomo" {

  metrics_override = { prefix = "nginx" }
  namespace_label = "app"
  source = {
    files = [
      "/var/log/nginx/matomo.log"
    ]
  }

  format = "$remote_addr - $remote_user [$time_local] \"$host\" \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" $upstream_response_time $request_time"

}

Dort wird also definiert auf welchen Port der Exporter laufen soll, für die verschiedenen Namespaces die Namen und wo die Logfiles liegen und wie das Logformat ausschaut.

Ältere Versionen des Exporters haben den Start abgebrochen sobald sie im logfile eine Zeile entdeckt hatten die nicht dem definiertem Format entspricht, die neuste Version zählt diese Logeinträge dann einfach nur, startet aber dennoch:

service prometheus-nginxlog-exporter restart

pmm-admin add external --service-name=nginx-log --listen-port=5040

Auch hier brauchen wir noch ein passendes Dashboard, gibt es auch schon fertig, die ID lautet 6482. Nach dem Import des Dashboards sehen wir dass wieder die instance verwendet wird, also passen wir das mal an. Jedes Element des Dashboards hat ein Menu über das man es dann auch editieren kann, dies Menu erscheint bei einem Klick auf die Titelleiste des jeweiligen Panel.

Dashboard bearbeiten
Dashboard bearbeiten

Hier tauschen wir bei der Query die 2 mal instance gegen app aus und fügen für die Legende ein {{app}} ein:

nur kleine schnelle Änderungen
nur kleine schnelle Änderungen

Bei den anderen Panel des Dashboards verfahren wir genauso, bei den Querys instance durch app austauschen und für die Legende {{app}} verwenden, ausser bei dem Status Panel, dort müssen wir nur {{status}} für die Legende eintragen.

Bei dem “Response time (90% quantile)” Panel ergänze ich noch gerne die 99% quantile, also einfach eine 2. Query hinzufügen und gegenüber der ersten dann einfach quantile=“0.99” anstatt quantile=“0.9” verwenden und für die Legende dann jeweils den Prozent wert hinzufügen, also {{app}} 90% für die Original Query und {{app}} 99% für unsere neu erstellte. Hier können wir die maximale Zeit ablesen nach der 90% bzw. 99% der Anfragen ausgeliefert wurden.

Bei dieser Query können wir auch sehen dass dort gefiltert wird, es werden nur GET Requests mit einem Requeststatus aus dem 200er Bereich berücksichtigt. So können wir zusätzlich auch noch ein Panel für Statuscodes über 300 einfügen, also Weiterleitungen, Fehler etc. Hierzu duplizieren wir das Panel mit den Statuscodes ( menu -> more -> duplicate) und passen es entsprechend an:

die Abfrage für Statuscodes 300 +
die Abfrage für Statuscodes 300 +

Den Titel des Panel kann man dann auf der rechten Seite ändern.

Und schon haben wir ein angepasstes Dashboard mit übersichtlichen Angaben.

Unser fertiges Dashboard
Unser fertiges Dashboard

Und ja, meine Sudokuseiten werden gewöhnlich in unter 10ms generiert. :)

So gehts weiter

Als nächstes kommt dann ein Blackbox Exporter, dieser wird dann in einem anderen Rechenzentrum aufgebaut, hier mit eigener Prometheus Instanz. Ein Blackbox Exporter testet Webservices auf Erreichbarkeit aus der Ferne, also ob die Webseiten auch erreichbar sind. Dann kommen später auch noch Exporter für den PHP FPM Pool und für die SSL Zertifikate von Let’s Encrypt, bei letzterem müssen wir ein Dashboard komplett selber erstellen.

(1273 Wörter | 9517 Zeichen)

Martins Meinung

Hier blogge ich über verschiedene Themen.