log-sqlite: Модуль логирования SQLite для NGINX
Установка
Вы можете установить этот модуль в любой дистрибутив на базе RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и 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
Включите модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_sqlitelog_module.so;
Этот документ описывает nginx-module-log-sqlite v0.0.1, выпущенный 14 февраля 2025 года.
Резюме
Этот модуль использует формат SQLite для логов доступа. GitHub форк https://git.serope.com/me/ngx-sqlitelog
Директивы
sqlitelog
- Синтаксис:
sqlitelogpath[format][buffer=size [max=n] [flush=time]][init=script][if=condition]|off - По умолчанию:
sqlitelogoff - Контекст: http, server
Эта директива определяет базу данных для логирования.
Параметр path — это путь к файлу базы данных. Он должен находиться в директории, где пользователь или группа, владеющая процессами worker Nginx (определены директивой user), имеет права на запись, чтобы он мог создать файл базы данных и любые возможные временные файлы.
Параметр format — это имя формата лога, определенного директивой sqlitelog_format. Если не указано, используется формат по умолчанию.
Параметр buffer создает зону памяти, где записи логов группируются и записываются в базу данных в одной транзакции BEGIN ... COMMIT. Это значительно улучшает производительность, так как групповые вставки быстрее, чем отдельные. Буфер фиксируется, когда происходит одно из следующих событий: превышен его size; накоплено n записей лога; истекло время flush; Nginx перезагружается или завершает работу.
Параметр init — это путь к файлу SQL-скрипта, который выполняется при каждом подключении к базе данных. Это можно использовать для выполнения pragma-команд или для создания дополнительных таблиц, представлений и триггеров для дополнения таблицы логирования; такие операторы должны содержать IF NOT EXISTS, так как они могут выполняться более одного раза.
Параметр if устанавливает условие логирования. Как и в стандартном модуле логирования, если condition оценивается в 0 или пустую строку, логирование пропускается для текущего запроса.
sqlitelog_format
- Синтаксис:
sqlitelog_formattablevar1[type1]var2[type2]...varN[typeN] - По умолчанию:
sqlitelog_formatcombined$remote_addr$remote_user$time_local$request$status$body_bytes_sent$http_referer$http_user_agent - Контекст: http
Эта директива определяет таблицу логирования.
Первый аргумент — это имя таблицы. Остальные аргументы — это переменные с необязательными типами колонок. Некоторые переменные имеют предустановленные типы колонок, в противном случае тип по умолчанию — TEXT. Если переменная имеет тип BLOB, ее значение записывается как неэкранированные байты.
sqlitelog_async
- Синтаксис:
sqlitelog_asyncpool|on|off - По умолчанию:
sqlitelog_asyncoff - Контекст: http
Эта директива включает пул потоков, позволяя записи в файл SQLite происходить без блокировки. Аргумент может быть именем существующего pool, on для пула по умолчанию или off. Эта директива доступна только если Nginx скомпилирован с --with-threads.
Ошибки
Когда происходит ошибка SQLite, модуль отключается (эквивалентно sqlitelog off) для процесса worker, который столкнулся с ошибкой. Это сделано для предотвращения быстрого заполнения error.log сообщениями об ошибках, если база данных непригодна для использования (например, находится в директории, где процессы worker не имеют прав на запись).
- SQLITE_ERROR (1): Это общий код ошибки, который охватывает несколько случаев, таких как синтаксические ошибки SQL в скрипте
init. - SQLITE_BUSY (5): Несколько процессов worker попытались одновременно использовать базу данных и превысили тайм-аут занятости (по умолчанию 1000 мс). Это можно решить, создав
bufferдля ускорения вставок или установив более длительный тайм-аут с помощьюPRAGMA busy_timeoutв скриптеinit. - SQLITE_READONLY (8): Nginx может открыть базу данных, но не может записать в нее. Это, вероятно, связано с правами доступа к файлу.
- SQLITE_CANTOPEN (14): Nginx не может открыть или создать базу данных. Это, вероятно, связано с правами доступа к директории. Пользователь или группа, владеющая процессами worker (определены директивой
user), должны иметь права на запись в директорию. - SQLITE_READONLY_DBMOVED (1032): Файл был перемещен, переименован или удален во время выполнения. Когда это происходит, Nginx пытается воссоздать файл; если это удается, ошибка игнорируется, и логирование продолжается нормально.
Использование
Локации
Директива sqlitelog не может использоваться в контекстах location, но условие regex может достичь аналогичного эффекта. В этом примере логируются только запросы, которые начинаются с "/mylocation".
map $request_uri $is_my_loc {
default 0;
~^/mylocation.*$ 1;
}
sqlitelog access.db if=$is_my_loc;
Наследование
Разрешена только одна директива sqlitelog на контекст, при этом более низкие контексты имеют приоритет. В этом примере запросы к серверу A логируются в global.db, в то время как запросы к серверу B логируются в b.db.
http {
sqlitelog global.db;
...
server {
server_name a;
...
}
server {
server_name b;
sqlitelog b.db;
....
}
````
### Режим WAL
[WAL mode](https://www.sqlite.org/wal.html) включается с помощью `PRAGMA journal_mode=wal` в скрипте `init`. [WAL checkpointing](https://www.sqlite.org/wal.html#ckpt) происходит, когда Nginx перезагружается или завершает работу.
### Logrotate
[Logrotate](https://man.archlinux.org/man/logrotate.8) должен быть настроен для остановки Nginx, ротации логов и повторного запуска Nginx. Таким образом, Nginx корректно закрывает свои соединения с базой данных предыдущего дня и открывает новые соединения с базами данных текущего дня.
Ниже приведен пример скрипта для Debian (`/etc/logrotate.d/nginx`). Предполагается, что пользователю процесса worker, `www-data`, предоставлены права на запись в `/var/log/nginx`, который обычно доступен только для записи пользователю `root`.
```sh
/var/log/nginx/*.log
/var/log/nginx/*.db
{
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 www-data adm
sharedscripts
# Принудить Logrotate работать в этой директории, даже если
# его разрешения были изменены, чтобы разрешить запись
# не-root пользователю
su root adm
# Отправить сигнал quit Nginx и дождаться уничтожения его PID файла
firstaction
systemctl stop nginx.service
while [ -f /var/run/nginx.pid ]; do
sleep 0.1s
done
endscript
# Запустить Nginx снова
lastaction
systemctl restart nginx.service
endscript
}
Типы колонок
Следующие переменные имеют предустановленные типы колонок, но могут быть переопределены при необходимости.
| Переменная | Тип |
|---|---|
| $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
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-log-sqlite.