web-dev-qa-db-fra.com

Collecte les erreurs des dernières 24 heures à partir des fichiers journaux nginx

J'essaie d'écrire un script pour collecter les journaux des dernières 24 heures à partir des fichiers journaux nginx. Mon script collecte tous les journaux du fichier journal et je n'ai besoin que des erreurs des dernières 24 heures.

Script à collecter au cours des dernières 24 heures nginx access.log et 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ème script:

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

Exemple de script similaire à celui ci-dessous:

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

Pour grep exception exception au-dessus des journaux des dernières 24 heures seulement et enregistrez-le sous last24hourlogs.log

Format de journal requis:

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"
1
Ramesh Chand

Lecture d'un fichier journal sur x (dernières) heures, recherche de lignes spécifiques

Notes IMPORTANTES

  • La réponse ci-dessous a été écrite, sur la base de l'exemple fourni avec OP, en supposant que l'exemple de sortie est une copie exacte de la manière dont les lignes apparaissent dans le fichier journal. Ceci est essentiel pour une analyse correcte de la date; si le position ou le format de l'horodatage est différent, cela échouera!
  • En raison d'informations de tri manquantes, le script n'a pas pu être optimisé pour la performance. toutes les lignes doivent être vérifiées, avec les informations que nous avons actuellement.
  • Il est également difficile de savoir si le fichier journal indique l'heure UTC ou l'heure locale, et l'heure à laquelle le rapport doit être produit. "24 dernières heures" doit éventuellement être corrigé de la différence de temps locale.

Le scénario

#!/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

Comment utiliser

  1. Copiez le script dans un fichier vide, enregistrez-le sous le nom get_log.py
  2. Exécutez-le avec le fichier source, le fichier de sortie et l'heure comme arguments:

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

Comme mentionné, il est possible que l'heure (24) doive être fixée par le fuseau horaire local. S'il vous plaît, faites-moi savoir.

Ce qu'il fait

  • Le script recherche les lignes avec un horodatage, affichant une heure dans la période définie (x heures à partir de maintenant), en comparant l'heure à partir d'Epoch. En cas de correspondance, il apparaît si une des chaînes conditionnelles est dans le fichier.
  • Si c'est le cas, la ligne est écrite dans le rapport.

MODIFIER

OP a mentionné que cela ne fonctionnait pas. Un test sur les deux exemples de PO postés sur demande montre cependant que le script fait parfaitement son travail:

Pourquoi ça marche?

  • Exemple d'Op - horodatage:

    2016/11/27 13:55:00
    

    est converti dans le format:

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

    par la ligne:

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

    et ensuite converti en Epoch:

    tstamp = convert_toepoch(pattern, stamp)
    
  • La ligne:

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

    sélectionne les lignes, marquées dans last_hrs dès maintenant.

  • La ligne:

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

    regarde par la suite si l’une des chaînes:

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

    se produit dans la ligne.

Comme mentionné, je l'ai testé de manière approfondie avec les exemples exacts fournis, et je ne peux pas en arriver à une autre conclusion que celle voulant que le script fasse son travail.

2
Jacob Vlijm