Maneira correta de girar logs do Nginx

12

Gostaria de conseguir a rotação dos logs nginx que:

  1. funcionaria sem nenhum software extra (ie - melhor se sem "logrotate")
  2. criaria arquivos girados com nomes com base na data

A melhor abordagem é algo que o PostgreSQL possui - ou seja, em sua variável de configuração log_filename, eu posso especificar o estilo strftime% Y-% m-% d, e ele mudará automaticamente a alteração na data (ou hora) do logon.

Outra abordagem do apache - envio de logs via pipe para o programa rotatelogs.

Tanto quanto pude pesquisar - não existe essa abordagem. Tudo o que posso fazer é usar o logrotate com a opção dateext, mas ele tem seu próprio conjunto de desvantagens, e eu prefiro usar algo que funcione como | rotatelogs ou log_filename no PostgreSQL.

Bryan
fonte
Este artigo descreve uma possível solução para o seu problema. Mas eu tenho uma pergunta: por que você não deseja usar o logrotate? Ele faz o trabalho muito bem, quase não tem dependências e está comprovadamente funcionando (se for o caso). Por que pular os bastidores e usar uma solução caseira que possa ser inferior e propensa a erros, se você puder usar o logrotate (que também pode ser útil para girar alguns outros logs nessa máquina)?
Joschi
O logrotate (com dateext) quase funciona, mas eu não gosto porque precisa ser executado via cron, e isso tem algumas desvantagens.
Como o nginx não suporta a canalização de seus logs para outros programas, não suporta a rotação de logs por si só e você não gosta de uma abordagem baseada em cron, é possível que não consiga o que deseja. Às vezes "quase funciona" é tão bom quanto possível. ;) A menos que, é claro, você queira corrigir o nginx por conta própria.
Joschi

Respostas:

7

Enquanto o mundo está dividido sobre se o humilde tubo nomeado é amigo ou inimigo, é provavelmente a solução mais simples para o seu problema. Ele tem algumas desvantagens (em que você precisa criar os pipes com antecedência), mas elimina a necessidade de um cron e permite que você use o filtro de tubos de registro de sua escolha.

Aqui está um exemplo usando o cronolog em access.log:

  1. Escolha um caminho para o nosso pipe nomeado. Eu pretendo manter meus registros /var/log/nginx, então vou colocar meus cachimbos lá também. O nome é com você; Acrescento .fifo, e é access.log, então o meu estará em /var/log/nginx/access.log.fifo.
  2. Exclua o arquivo, se existir.
  3. Faça um pipe nomeado para o arquivo de log:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Configure nginx.confpara apontar o log para o canal que você acabou de criar:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Modifique seu script init.d para iniciar o rotador de log ouvindo o canal antes de iniciarmos o servidor:

    LOGS="/var/log/nginx"
    pkill -f "/usr/sbin/cronolog --symlink $LOGS/access.log"
    ( cat $LOGS/access.log.fifo | /usr/sbin/cronolog --symlink $LOGS/access.log "$LOGS/%Y/%m/%d/access.log" ) &
    

    Uma linha de comando semelhante seria usada rotatelogsse você preferir cronolog- consulte os documentos para a sintaxe.

    Se sua distrobuição tiver um start-stop-daemon, você deve usá-lo, pois teoricamente ele possui qualquer conhecimento especial sobre sua plataforma e cuida de pkillvocê. Basta enrolar o comando em um script, e passá-lo como --execa start-stop-daemonsua init.d/nginx.

dsc
fonte
Eu amo cronolog; é bom ver mais pessoas usando / recomendando.
Natacado
1

Eu escrevi um programa simples, datelog, para dividir logs comuns com base na data do logon, em oposição à hora atual do sistema quando a linha de log é vista pelo programa. Isso pode ou não ser exatamente o que o cronolog ou outro divisor de logs já faz, mas foi mais rápido escrever o meu próprio do que descobrir o que os outros fazem.

Usando o ano e o mês na solicitação registrada, a linha é gravada em um arquivo ou canal que inclui o AAAAMM computado a partir dos dados registrados. Sim, isso é um pouco específico para o formato de log comum. O primeiro [supõe-se que delimite a data. Cuidado com os endereços IPv6. :)

Para análise de log, é importante que cada log realmente contenha apenas as solicitações para cada mês respectivo, e cada log deve estar idealmente completo para resultados corretos da análise. Não é suficiente determinar o nome do arquivo com base no horário atual no divisor de logs, porque uma solicitação lenta iniciando às 23:59:59 acabará no arquivo de log no mês errado.

Eu uso isso com o nginx por meio de um fifo nomeado, que é verificado para existir antes do nginx ser iniciado. Observe que existe uma troca no programa entre a detecção de erros e a saída em buffer, em que o datelog atualmente prefere a saída em buffer por razões de desempenho, portanto, verifique se a sua configuração realmente funciona, especialmente ao usar pipes de shell, para não perder nenhum dado de log .

Código fonte: http://stuge.se/datelog.c

Por favor, sinta-se livre para me enviar qualquer feedback e, claro, patches!

stuge
fonte
1

Você pode conseguir isso usando um script bash simples e cron:

#!/bin/bash
DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/nginx.pid`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE

Mais detalhes sobre a configuração do crontab etc. são encontrados aqui: Rotação de arquivos de log do Nginx via Cron

John Collins
fonte
0

Receio não ter entendido sua pergunta: como o nginx não oferece suporte a nenhuma logrotation integrada, você terá que usar algo como

mv access.log access.log.$(date "+%Y-%m%d")
kill -USR1 $(cat master.nginx.pid)

em algum lugar no /etc/cron.daily (é necessário qualificar os nomes de arquivos acima com nomes de caminho completos, é claro) ou instalar os utilitários apache2 para ter acesso aos rotatelogs.

Stefan Förster
fonte
É o mesmo que eu poderia fazer com o logrotate. E eu quero isso melhor.