Aller au contenu

log-sqlite: Module de journalisation SQLite pour NGINX

Installation

Vous pouvez installer ce module dans n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :

  • RedHat Enterprise Linux 7, 8, 9 et 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 et 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

Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :

load_module modules/ngx_http_sqlitelog_module.so;

Ce document décrit nginx-module-log-sqlite v0.0.1 publié le 14 février 2025.


Résumé

Ce module utilise le format SQLite pour les journaux d'accès. Fork GitHub de https://git.serope.com/me/ngx-sqlitelog

Directives

sqlitelog

  • Syntaxe : sqlitelog path [format] [buffer=size [max=n] [flush=time]] [init=script] [if=condition] | off
  • Par défaut : sqlitelog off
  • Contexte : http, serveur

Cette directive définit une base de données de journalisation.

Le paramètre path est le chemin du fichier de base de données. Il doit être situé dans un répertoire où l'utilisateur ou le groupe qui possède les processus de travail Nginx (défini par la directive user) a la permission d'écriture afin de pouvoir créer le fichier de base de données et tout fichier temporaire possible.

Le paramètre format est le nom d'un format de journal défini par la directive sqlitelog_format. S'il n'est pas donné, le format combiné par défaut est utilisé.

Le paramètre buffer crée une zone mémoire où les entrées de journal sont regroupées et écrites dans la base de données dans une seule transaction BEGIN ... COMMIT. Cela améliore considérablement les performances, car les insertions groupées sont plus rapides que celles séparées. Le buffer est validé lorsque l'un des événements suivants se produit : sa size est dépassée ; il accumule n entrées de journal ; le time de vidage s'écoule ; Nginx se recharge ou se termine.

Le paramètre init est un chemin vers un fichier de script SQL qui est exécuté à chaque connexion à la base de données. Cela peut être utilisé pour exécuter des commandes pragma ou pour créer des tables, des vues et des déclencheurs supplémentaires pour compléter la table de journalisation ; de telles déclarations doivent inclure IF NOT EXISTS car elles peuvent être exécutées plusieurs fois.

Le paramètre if définit une condition de journalisation. Comme dans le module de journalisation standard, si condition évalue à 0 ou à une chaîne vide, la journalisation est ignorée pour la requête actuelle.

sqlitelog_format

  • Syntaxe : sqlitelog_format table var1 [type1] var2 [type2] ... varN [typeN]
  • Par défaut : sqlitelog_format combined $remote_addr $remote_user $time_local $request $status $body_bytes_sent $http_referer $http_user_agent
  • Contexte : http

Cette directive définit une table de journalisation.

Le premier argument est le nom de la table. Les arguments restants sont des variables avec des types de colonnes optionnels. Certaines variables ont des types de colonnes prédéfinis, sinon le type par défaut est TEXT. Si une variable est de type BLOB, sa valeur est écrite sous forme d'octets non échappés.

sqlitelog_async

  • Syntaxe : sqlitelog_async pool | on | off
  • Par défaut : sqlitelog_async off
  • Contexte : http

Cette directive active un pool de threads, permettant aux écritures de fichiers SQLite de se produire sans blocage. L'argument peut être un nom de pool existant, on pour le pool par défaut, ou off. Cette directive n'est disponible que si Nginx est compilé avec --with-threads.

Erreurs

Lorsqu'une erreur SQLite se produit, le module est désactivé (équivalent à sqlitelog off) pour le processus de travail qui a rencontré l'erreur. Cela permet d'éviter que error.log ne soit rapidement inondé de messages d'erreur si la base de données est inutilisable (par exemple, située dans un répertoire où les processus de travail n'ont pas la permission d'écriture).

  • SQLITE_ERROR (1) : Il s'agit d'un code d'erreur générique qui couvre plusieurs cas, tels que des erreurs de syntaxe SQL dans un script init.
  • SQLITE_BUSY (5) : Plusieurs processus de travail ont tenté d'utiliser la base de données simultanément et ont dépassé le délai d'attente de disponibilité (1000 ms par défaut). Cela peut être résolu en créant un buffer pour accélérer les insertions ou en définissant un délai d'attente plus long avec PRAGMA busy_timeout dans un script init.
  • SQLITE_READONLY (8) : Nginx peut ouvrir la base de données, mais ne peut pas y écrire. Cela est probablement dû aux permissions de fichier.
  • SQLITE_CANTOPEN (14) : Nginx ne peut pas ouvrir ou créer la base de données. Cela est probablement dû aux permissions du répertoire. L'utilisateur ou le groupe qui possède les processus de travail (défini par la directive user) doit avoir la permission d'écriture sur le répertoire.
  • SQLITE_READONLY_DBMOVED (1032) : Le fichier a été déplacé, renommé ou supprimé à l'exécution. Lorsque cela se produit, Nginx tente de recréer le fichier ; si cela réussit, l'erreur est ignorée et la journalisation continue normalement.

Utilisation

Emplacements

La directive sqlitelog ne peut pas être utilisée dans des contextes de localisation, mais une condition regex peut atteindre un effet similaire. Dans cet exemple, seules les requêtes qui commencent par "/mylocation" sont journalisées.

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

sqlitelog access.db if=$is_my_loc;

Héritage

Une seule sqlitelog est autorisée par contexte, les contextes inférieurs prenant la priorité. Dans cet exemple, les requêtes vers le serveur A sont journalisées dans global.db, tandis que les requêtes vers le serveur B sont journalisées dans b.db.

http {
    sqlitelog global.db;
    ...

    server {
        server_name a;
        ...
    }

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

### Mode WAL

Le [mode WAL](https://www.sqlite.org/wal.html) est activé par `PRAGMA journal_mode=wal` dans un script `init`. Le [checkpointing WAL](https://www.sqlite.org/wal.html#ckpt) se produit lorsque Nginx se recharge ou se termine.

### Logrotate

[Logrotate](https://man.archlinux.org/man/logrotate.8) doit être configuré pour arrêter Nginx, faire pivoter les journaux et redémarrer Nginx. De cette manière, Nginx ferme gracieusement ses connexions aux bases de données de la veille et en ouvre de nouvelles pour les bases de données du jour actuel.

Voici un exemple de script pour Debian (`/etc/logrotate.d/nginx`). Il suppose que l'utilisateur du processus de travail, `www-data`, a reçu la permission d'écriture sur `/var/log/nginx`, qui est normalement uniquement accessible en écriture par `root`.

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

    # Forcer Logrotate à fonctionner dans ce répertoire même si
    # ses permissions ont été modifiées pour permettre à un utilisateur non-root
    # d'y écrire
    su root adm

    # Envoyer un signal de sortie à Nginx et attendre que son fichier PID
    # soit détruit
    firstaction
        systemctl stop nginx.service
        while [ -f /var/run/nginx.pid ]; do  
            sleep 0.1s
        done
    endscript

    # Redémarrer Nginx
    lastaction
        systemctl restart nginx.service
    endscript
}

Types de colonnes

Les variables suivantes ont des types de colonnes prédéfinis, mais peuvent être remplacées si nécessaire.

Variable Type
$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

Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-log-sqlite.