Colete erros nas últimas 24 horas dos arquivos de log nginx [closed]

1

Estou tentando escrever um script para coletar os últimos logs de 24 horas dos arquivos de log nginx. Meu script está coletando todos os logs do arquivo de log e eu preciso apenas dos últimos 24 horas de erros.

Script para coletar as últimas 24 horas nginx access.log e error.log

awk -vDate='date -d'now-24 hours' +[%d/%b/%Y:%H:%M:%S' '$4 > Date {print Date, $0}' /var/log/nginx/access.log > /data/production_logs/nginxaccess.log
awk -vDate='date -d'now-24 hours' +[%d/%b/%Y:%H:%M:%S' '$4 > Date {print Date, $0}' /var/log/nginx/error.log > /data/production_logs/nginxerror.log

2º script:

egrep 'Error|error|Exception|failed|Unhandled|err|Err' /data/production_logs/myapp.log > /data/production_logs/myapp_error.log

Veja o exemplo de script como abaixo:

egrep 'Error|error|Exception|failed|Unhandled|err|Err' /var/log/nginx/error.log > /var/log/nginx/last24hourlogs.log

Para grep exceção de erro acima das últimas 24 horas somente logs e salve-o como last24hourlogs.log

Formato de log requerido:

2016/11/27 13:55:00 [error] 6822#0: *14569 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 223.182.171.4, server: myappserver
2016/12/03 12:51:26 [error] 6820#0: *19094 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 157.48.95.8, server:

tail -f /home/example.com/.forever/bdapp.log

2016/12/19 12:30:51 [error] 2147#0: *5647 open() "/usr/share/nginx/html/example.com/myapp_email-templates/social-01.png" failed (2: No such file or directory), client: 66.249.84.191, server: example.com, request: "GET /myapp_email-templates/social-01.png HTTP/1.1", host: "example.com"
2016/12/19 12:30:51 [error] 2147#0: *5646 open() "/usr/share/nginx/html/example.com/myapp_email-templates/social-02.png" failed (2: No such file or directory), client: 66.249.84.128, server: example.com, request: "GET /myapp_email-templates/social-02.png HTTP/1.1", host: "example.com"
    
por Ramesh Chand 14.12.2016 / 07:33

1 resposta

3

Lendo um arquivo de log por x (últimas) horas, procurando por linhas específicas

Notas importantes

  • A resposta abaixo foi escrita com base no exemplo OP fornecido, supondo que o exemplo de saída seja uma cópia exata de como as linhas ocorrem no arquivo de log. Isso é essencial para a análise correta da data; Se a posição ou o formato da data e hora forem diferentes, ela falhará!
  • Devido à falta de informações de classificação, o script não pôde ser otimizado para desempenho; todas as linhas precisam ser verificadas, com as informações que temos atualmente.
  • Também não está claro se o arquivo de log informa em UTC ou horário local, e em que horas o relatório deve ser produzido. "Últimas 24 horas" possivelmente precisa ser corrigido pela diferença de horário local.

O script

#!/usr/bin/env python3
import time
import calendar
import sys

#--- set conditions below 
matches = ['Error', 'error', 'Exception', 'failed', 'Unhandled', 'err', 'Err']
# ---

pattern = "%Y/%m/%d%H:%M:%S"

source = sys.argv[1]
report = sys.argv[2]
last_hrs = sys.argv[3]

# shift =  time.timezone
shift = 0
now = time.time()

def convert_toepoch(pattern, stamp):
    """
    function to convert readable format (any) into epocherror
    """
    return int(time.mktime(time.strptime(stamp, pattern)))

with open(source) as infile:
    with open(report, "wt") as outfile:
        for l in infile:
            try:
                # parse out the time stamp, convert to epoch
                stamp = "".join(l.split()[:2])
                tstamp = convert_toepoch(pattern, stamp)
                # set the conditions the line has to meet
                if now - tstamp - shift <= int(last_hrs)*3600:
                    if any([s in l for s in matches]):
                        outfile.write(l)
            except (IndexError, ValueError):
                pass

Como usar

  1. Copie o script em um arquivo vazio, salve-o como get_log.py
  2. Execute-o com o arquivo de origem, o arquivo de saída e a hora como argumentos:

    python3 /path/to/get_log.py <logfile> <ouput_file> 24
    

Como mencionado, possivelmente o tempo ( 24 ) precisa ser corrigido pelo fuso horário local. Por favor me avise.

O que faz

  • O script procura linhas com um registro de data e hora, mostrando uma hora dentro do período de tempo definido (x-horas de volta a partir de agora), comparando o tempo da época. No caso de uma correspondência, parece que alguma das cadeias condicionais está no arquivo.
  • Se sim, a linha é gravada no relatório

EDITAR

OP mencionou que não funcionou. No entanto, um teste nos dois exemplos publicados pelo OP, a pedido, mostra que o script faz o trabalho perfeitamente:

Por que isso funciona?

  • Exemplo-timestamp de op:

    2016/11/27 13:55:00
    

    é convertido no formato:

    "%Y/%m/%d%H:%M:%S"
    

    pela linha:

    stamp = "".join(l.split()[:2])
    

    e subsequentemente convertido em época:

    tstamp = convert_toepoch(pattern, stamp)
    
  • A linha:

    if now - tstamp - shift <= int(last_hrs)*3600:
    

    seleciona linhas, carimbadas em last_hrs a partir de agora.

  • A linha:

    if any([s in l for s in matches]):
    

    subseqüentemente procura se alguma das strings:

    ['Error', 'error', 'Exception', 'failed', 'Unhandled', 'err', 'Err']
    

    ocorre na linha.

Como mencionado, testei-o completamente com os exemplos exatos do OP, e não posso chegar a outra conclusão do que o script fazer o seu trabalho.

    
por Jacob Vlijm 14.12.2016 / 15:21