Zum Inhalt

log-sqlite: SQLite-Logger-Modul für NGINX

Installation

Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:

  • RedHat Enterprise Linux 7, 8, 9 und 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-log-sqlite
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-log-sqlite

Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:

load_module modules/ngx_http_sqlitelog_module.so;

Dieses Dokument beschreibt nginx-module-log-sqlite v0.0.1 veröffentlicht am 14. Februar 2025.


Zusammenfassung

Dieses Modul verwendet das SQLite-Format für Zugriffsprotokolle. GitHub-Fork von https://git.serope.com/me/ngx-sqlitelog

Direktiven

sqlitelog

  • Syntax: sqlitelog path [format] [buffer=size [max=n] [flush=time]] [init=script] [if=condition] | off
  • Standard: sqlitelog off
  • Kontext: http, server

Diese Direktive definiert eine Protokolldatenbank.

Der path Parameter ist der Pfad zur Datenbankdatei. Er muss sich in einem Verzeichnis befinden, in dem der Benutzer oder die Gruppe, die die Nginx-Worker-Prozesse besitzt (definiert durch die user-Direktive), Schreibberechtigungen hat, damit die Datenbankdatei und mögliche temporäre Dateien erstellt werden können.

Der format Parameter ist der Name eines Protokollformats, das durch die sqlitelog_format-Direktive definiert ist. Wenn nicht angegeben, wird das Standardkombinationsformat verwendet.

Der buffer-Parameter erstellt eine Speicherzone, in der Protokolleinträge zusammengefasst und in einer einzigen BEGIN ... COMMIT-Transaktion in die Datenbank geschrieben werden. Dies verbessert die Leistung erheblich, da gruppierte Einfügungen schneller sind als separate. Der Puffer wird committet, wenn eines der folgenden Ereignisse eintritt: seine size wird überschritten; es sammelt n Protokolleinträge; die Flush-time verstreicht; Nginx wird neu geladen oder beendet.

Der init-Parameter ist ein Pfad zu einer SQL-Skriptdatei, die bei jeder Datenbankverbindung ausgeführt wird. Dies kann verwendet werden, um Pragma-Befehle auszuführen oder zusätzliche Tabellen, Ansichten und Trigger zu erstellen, um die Protokolltabelle zu ergänzen; solche Anweisungen sollten IF NOT EXISTS enthalten, da sie mehr als einmal ausgeführt werden können.

Der if-Parameter setzt eine Protokollierungsbedingung. Wie im Standard Log-Modul wird die Protokollierung für die aktuelle Anfrage übersprungen, wenn condition zu 0 oder einem leeren String ausgewertet wird.

sqlitelog_format

  • Syntax: sqlitelog_format table var1 [type1] var2 [type2] ... varN [typeN]
  • Standard: sqlitelog_format combined $remote_addr $remote_user $time_local $request $status $body_bytes_sent $http_referer $http_user_agent
  • Kontext: http

Diese Direktive definiert eine Protokolltabelle.

Das erste Argument ist der Name der Tabelle. Die verbleibenden Argumente sind Variablen mit optionalen Spaltentypen. Einige Variablen haben vorgegebene Spaltentypen, andernfalls ist der Standard TEXT. Wenn eine Variable vom Typ BLOB ist, wird ihr Wert als nicht entkommene Bytes geschrieben.

sqlitelog_async

  • Syntax: sqlitelog_async pool | on | off
  • Standard: sqlitelog_async off
  • Kontext: http

Diese Direktive aktiviert einen Thread-Pool, der es ermöglicht, dass SQLite-Dateischreibvorgänge ohne Blockierung erfolgen. Das Argument kann ein vorhandener pool-Name, on für den Standardpool oder off sein. Diese Direktive ist nur verfügbar, wenn Nginx mit --with-threads kompiliert wurde.

Fehler

Wenn ein SQLite-Fehler auftritt, wird das Modul für den Worker-Prozess, der den Fehler festgestellt hat, deaktiviert (entspricht sqlitelog off). Dies geschieht, um zu verhindern, dass error.log schnell mit Fehlermeldungen überflutet wird, wenn die Datenbank unbrauchbar ist (z. B. sich in einem Verzeichnis befindet, in dem die Worker-Prozesse keine Schreibberechtigung haben).

  • SQLITE_ERROR (1): Dies ist ein allgemeiner Fehlercode, der mehrere Fälle abdeckt, wie z. B. SQL-Syntaxfehler in einem init-Skript.
  • SQLITE_BUSY (5): Mehrere Worker-Prozesse haben versucht, die Datenbank gleichzeitig zu verwenden und haben die Busy-Zeitüberschreitung (standardmäßig 1000 ms) überschritten. Dies kann gelöst werden, indem ein buffer erstellt wird, um die Einfügungen zu beschleunigen, oder indem eine längere Zeitüberschreitung mit PRAGMA busy_timeout in einem init-Skript festgelegt wird.
  • SQLITE_READONLY (8): Nginx kann die Datenbank öffnen, aber nicht darin schreiben. Dies liegt wahrscheinlich an den Dateiberechtigungen.
  • SQLITE_CANTOPEN (14): Nginx kann die Datenbank nicht öffnen oder erstellen. Dies liegt wahrscheinlich an den Verzeichnisberechtigungen. Der Benutzer oder die Gruppe, die die Worker-Prozesse besitzt (definiert durch die user-Direktive), muss Schreibberechtigungen für das Verzeichnis haben.
  • SQLITE_READONLY_DBMOVED (1032): Die Datei wurde zur Laufzeit verschoben, umbenannt oder gelöscht. Wenn dies geschieht, versucht Nginx, die Datei neu zu erstellen; wenn dies erfolgreich ist, wird der Fehler ignoriert und die Protokollierung erfolgt normal weiter.

Verwendung

Standorte

Die sqlitelog-Direktive kann nicht in Standortkontexten verwendet werden, aber eine Regex-Bedingung kann einen ähnlichen Effekt erzielen. In diesem Beispiel werden nur Anfragen, die mit "/mylocation" beginnen, protokolliert.

map $request_uri $is_my_loc {
    default            0;
    ~^/mylocation.*$   1;
}

sqlitelog access.db if=$is_my_loc;

Vererbung

Es ist nur eine sqlitelog pro Kontext erlaubt, wobei niedrigere Kontexte Vorrang haben. In diesem Beispiel werden Anfragen an Server A in global.db protokolliert, während Anfragen an Server B in b.db protokolliert werden.

http {
    sqlitelog global.db;
    ...

    server {
        server_name a;
        ...
    }

    server {
        server_name b;
        sqlitelog b.db;
        ....
    }
````

### WAL-Modus

[WAL-Modus](https://www.sqlite.org/wal.html) wird durch `PRAGMA journal_mode=wal` in einem `init`-Skript aktiviert. [WAL-Checkpointing](https://www.sqlite.org/wal.html#ckpt) erfolgt, wenn Nginx neu geladen oder beendet wird.

### Logrotate

[Logrotate](https://man.archlinux.org/man/logrotate.8) sollte so konfiguriert werden, dass Nginx gestoppt, Protokolle rotiert und Nginx erneut gestartet wird. Auf diese Weise schließt Nginx seine Verbindungen zu den Datenbanken des vorherigen Tages und öffnet neue zu den Datenbanken des aktuellen Tages.

Unten ist ein Beispielskript für Debian (`/etc/logrotate.d/nginx`). Es wird davon ausgegangen, dass der Benutzer des Worker-Prozesses, `www-data`, Schreibberechtigungen für `/var/log/nginx` erhalten hat, das normalerweise nur von `root` beschreibbar ist.

```sh
/var/log/nginx/*.log
/var/log/nginx/*.db
{
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 640 www-data adm
    sharedscripts

    # Zwinge Logrotate, in diesem Verzeichnis zu arbeiten, obwohl
    # seine Berechtigungen geändert wurden, um einem Nicht-Root
    # Benutzer das Schreiben zu ermöglichen
    su root adm

    # Sende ein Quit-Signal an Nginx und warte, bis seine PID-Datei
    # zerstört wird
    firstaction
        systemctl stop nginx.service
        while [ -f /var/run/nginx.pid ]; do  
            sleep 0.1s
        done
    endscript

    # Starte Nginx erneut
    lastaction
        systemctl restart nginx.service
    endscript
}

Spaltentypen

Die folgenden Variablen haben vordefinierte Spaltentypen, können jedoch bei Bedarf überschrieben werden.

Variable Typ
$binary_remote_addr BLOB
$body_bytes_sent INTEGER
$bytes_sent INTEGER
$connection INTEGER
$connection_requests INTEGER
$connection_time REAL
$connections_active INTEGER
$connections_reading INTEGER
$connections_waiting INTEGER
$connections_writing INTEGER
$content_length INTEGER
$gzip_ratio REAL
$limit_rate INTEGER
$msec REAL
$pid INTEGER
$proxy_port INTEGER
$proxy_protocol_port INTEGER
$proxy_protocol_server_port INTEGER
$remote_port INTEGER
$request_time REAL
$server_port INTEGER
$status INTEGER

GitHub

Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-log-sqlite.