log-sqlite: Модуль ведения журналов SQLite для NGINX
Установка на Debian/Ubuntu
Эти документы применимы к APT пакету nginx-module-log-sqlite, предоставленному репозиторием GetPageSpeed Extras.
- Настройте APT репозиторий, как описано в настройке APT репозитория.
- Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-log-sqlite
Показать наборы и архитектуры
| Дистрибутив | Версия | Компонент | Архитектуры |
|-------------|-------------------|-------------|----------------|
| debian | bookworm | main | amd64, arm64 |
| debian | bookworm-mainline | main | amd64, arm64 |
| debian | trixie | main | amd64, arm64 |
| debian | trixie-mainline | main | amd64, arm64 |
| ubuntu | focal | main | amd64, arm64 |
| ubuntu | focal-mainline | main | amd64, arm64 |
| ubuntu | jammy | main | amd64, arm64 |
| ubuntu | jammy-mainline | main | amd64, arm64 |
| ubuntu | noble | main | amd64, arm64 |
| ubuntu | noble-mainline | main | amd64, arm64 |
Сводка
Этот модуль использует формат 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 — это путь к файлу базы данных. Он должен находиться в каталоге, где пользователь или группа, владеющая процессами рабочих 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) для рабочего процесса, который столкнулся с ошибкой. Это сделано для того, чтобы предотвратить быстрое заполнение error.log сообщениями об ошибках, если база данных непригодна для использования (например, находится в каталоге, где процессы рабочих не имеют прав на запись).
- SQLITE_ERROR (1): Это общий код ошибки, охватывающий несколько случаев, таких как синтаксические ошибки SQL в
initскрипте. - SQLITE_BUSY (5): Несколько рабочих процессов попытались одновременно использовать базу данных и превысили тайм-аут занятости (по умолчанию 1000 мс). Это можно решить, создав
buffer, чтобы ускорить вставки или установив более долгий тайм-аут с помощьюPRAGMA busy_timeoutвinitскрипте. - SQLITE_READONLY (8): Nginx может открыть базу данных, но не может записать в нее. Это, вероятно, связано с правами доступа к файлам.
- SQLITE_CANTOPEN (14): Nginx не может открыть или создать базу данных. Это, вероятно, связано с правами доступа к каталогу. Пользователь или группа, владеющие рабочими процессами (определяются директивой
user), должны иметь право на запись в каталог. - SQLITE_READONLY_DBMOVED (1032): Файл был перемещен, переименован или удален во время выполнения. Когда это происходит, Nginx пытается восстановить файл; если это удается, ошибка игнорируется, и ведение журнала продолжается нормально.
Использование
Локации
Директива sqlitelog не может использоваться в контекстах местоположения, но можно использовать условие 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](https://www.sqlite.org/wal.html) включается с помощью `PRAGMA journal_mode=wal` в `init` скрипте. [Контрольные точки WAL](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`). Предполагается, что пользователю процесса рабочего `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
# Отправить сигнал завершения 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 |