log-sqlite: Módulo de logger SQLite para NGINX
Instalação
Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:
- RedHat Enterprise Linux 7, 8, 9 e 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 e 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
Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:
load_module modules/ngx_http_sqlitelog_module.so;
Este documento descreve o nginx-module-log-sqlite v0.0.1 lançado em 14 de fevereiro de 2025.
Resumo
Este módulo utiliza o formato SQLite para logs de acesso. Fork do GitHub de https://git.serope.com/me/ngx-sqlitelog
Diretivas
sqlitelog
- Sintaxe:
sqlitelogcaminho[formato][buffer=tamanho [max=n] [flush=tempo]][init=script][if=condição]|off - Padrão:
sqlitelogoff - Contexto: http, server
Esta diretiva define um banco de dados de logging.
O parâmetro caminho é o caminho do arquivo do banco de dados. Ele deve estar localizado em um diretório onde o usuário ou grupo que possui os processos de trabalho do Nginx (definido pela diretiva user) tenha permissão de escrita para que possa criar o arquivo do banco de dados e quaisquer possíveis arquivos temporários.
O parâmetro formato é o nome de um formato de log definido pela diretiva sqlitelog_format. Se não for fornecido, o formato combinado padrão é utilizado.
O parâmetro buffer cria uma zona de memória onde as entradas de log são agrupadas e escritas no banco de dados em uma única transação BEGIN ... COMMIT. Isso melhora muito o desempenho, pois inserções agrupadas são mais rápidas do que as separadas. O buffer é comprometido quando uma das seguintes condições ocorre: seu tamanho é excedido; acumula n entradas de log; o tempo de flush expira; o Nginx é recarregado ou sai.
O parâmetro init é um caminho para um arquivo de script SQL que é executado em cada conexão ao banco de dados. Isso pode ser usado para executar comandos pragma ou para criar tabelas, visões e gatilhos adicionais para complementar a tabela de logging; tais instruções devem incluir IF NOT EXISTS, pois podem ser executadas mais de uma vez.
O parâmetro if define uma condição de logging. Assim como no padrão módulo de log, se condição avaliar para 0 ou uma string vazia, o logging é ignorado para a requisição atual.
sqlitelog_format
- Sintaxe:
sqlitelog_formattabelavar1[tipo1]var2[tipo2]...varN[tipoN] - Padrão:
sqlitelog_formatcombined$remote_addr$remote_user$time_local$request$status$body_bytes_sent$http_referer$http_user_agent - Contexto: http
Esta diretiva define uma tabela de logging.
O primeiro argumento é o nome da tabela. Os argumentos restantes são variáveis com tipos de coluna opcionais. Algumas variáveis têm tipos de coluna predefinidos, caso contrário, o padrão é TEXT. Se uma variável for do tipo BLOB, seu valor é escrito como bytes não escapados.
sqlitelog_async
- Sintaxe:
sqlitelog_asyncpool|on|off - Padrão:
sqlitelog_asyncoff - Contexto: http
Esta diretiva habilita um pool de threads, permitindo que as gravações de arquivos SQLite ocorram sem bloqueio. O argumento pode ser um nome de pool existente, on para o pool padrão, ou off. Esta diretiva só está disponível se o Nginx for compilado com --with-threads.
Erros
Quando um erro SQLite ocorre, o módulo é desativado (equivalente a sqlitelog off) para o processo de trabalho que encontrou o erro. Isso é para evitar que o error.log seja rapidamente inundado com mensagens de erro se o banco de dados for inutilizável (por exemplo, localizado em um diretório onde os processos de trabalho não têm permissão de escrita).
- SQLITE_ERROR (1): Este é um código de erro genérico que cobre vários casos, como erros de sintaxe SQL em um script
init. - SQLITE_BUSY (5): Vários processos de trabalho tentaram usar o banco de dados simultaneamente e excederam o tempo limite de ocupado (1000 ms por padrão). Isso pode ser resolvido criando um
bufferpara acelerar as inserções ou definindo um tempo limite mais longo comPRAGMA busy_timeoutem um scriptinit. - SQLITE_READONLY (8): O Nginx pode abrir o banco de dados, mas não pode escrever nele. Isso é provavelmente devido a permissões de arquivo.
- SQLITE_CANTOPEN (14): O Nginx não pode abrir ou criar o banco de dados. Isso é provavelmente devido a permissões de diretório. O usuário ou grupo que possui os processos de trabalho (definido pela diretiva
user) deve ter permissão de escrita no diretório. - SQLITE_READONLY_DBMOVED (1032): O arquivo foi movido, renomeado ou excluído em tempo de execução. Quando isso acontece, o Nginx tenta recriar o arquivo; se for bem-sucedido, o erro é ignorado e o logging continua normalmente.
Uso
Localizações
A diretiva sqlitelog não pode ser usada em contextos de localização, mas uma condição regex pode alcançar um efeito semelhante. Neste exemplo, apenas requisições que começam com "/mylocation" são registradas.
map $request_uri $is_my_loc {
default 0;
~^/mylocation.*$ 1;
}
sqlitelog access.db if=$is_my_loc;
Herdabilidade
Apenas um sqlitelog é permitido por contexto, com contextos inferiores tendo prioridade. Neste exemplo, requisições para o servidor A são registradas em global.db, enquanto requisições para o servidor B são registradas em b.db.
http {
sqlitelog global.db;
...
server {
server_name a;
...
}
server {
server_name b;
sqlitelog b.db;
....
}
Modo WAL
O modo WAL é habilitado por PRAGMA journal_mode=wal em um script init. O checkpointing WAL ocorre quando o Nginx é recarregado ou sai.
Logrotate
O Logrotate deve ser configurado para parar o Nginx, rotacionar logs e iniciar o Nginx novamente. Dessa forma, o Nginx fecha graciosamente suas conexões com o(s) banco(s) de dados do dia anterior e abre novas conexões com o(s) banco(s) de dados do dia atual.
Abaixo está um exemplo de script para Debian (/etc/logrotate.d/nginx). Ele assume que o usuário do processo de trabalho, www-data, recebeu permissão de escrita em /var/log/nginx, que normalmente só é gravável por root.
/var/log/nginx/*.log
/var/log/nginx/*.db
{
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 www-data adm
sharedscripts
# Forçar o Logrotate a funcionar neste diretório, mesmo que
# suas permissões tenham sido modificadas para permitir que um
# usuário não-root escreva nele
su root adm
# Enviar um sinal de quit para o Nginx e esperar que seu arquivo PID
# seja destruído
firstaction
systemctl stop nginx.service
while [ -f /var/run/nginx.pid ]; do
sleep 0.1s
done
endscript
# Iniciar o Nginx novamente
lastaction
systemctl restart nginx.service
endscript
}
Tipos de coluna
As seguintes variáveis têm tipos de coluna predefinidos, mas podem ser substituídos se necessário.
| Variável | Tipo |
|---|---|
| $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
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-log-sqlite.