it-swarm.com.de

Sammeln Sie in den letzten 24 Stunden Fehler aus Nginx-Protokolldateien

Ich versuche, ein Skript zu schreiben, um die letzten 24 Stunden Protokolle aus Nginx-Protokolldateien zu sammeln. Mein Skript sammelt alle Protokolle aus der Protokolldatei und ich brauche nur die letzten 24 Stunden Fehler.

Skript zum Sammeln der letzten 24 Stunden nginx access.log und 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. Drehbuch:

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

Beispiel eines aussehenden Skripts wie folgt:

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

Um die Fehlerausnahme oben aus den letzten 24 Stunden zu überprüfen, wird nur protokolliert und als last24hourlogs.log gespeichert.

Protokollformat erforderlich:

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

Lesen einer Protokolldatei über x (letzte) Stunden, wobei nach bestimmten Zeilen gesucht wird

Wichtige Notizen

  • Die folgende Antwort wurde basierend auf dem bereitgestellten Beispiel-OP geschrieben, unter der Annahme, dass das Ausgabebeispiel eine exakte Kopie davon ist, wie Zeilen in der Protokolldatei vorkommen. Dies ist wichtig, um das Datum korrekt zu analysieren. Wenn entweder das Position oder das Format des Zeitstempels unterschiedlich ist, schlägt dies fehl!
  • Aufgrund fehlender Sortierinformationen konnte das Skript nicht für die Leistung optimiert werden. Alle Zeilen müssen mit den aktuell verfügbaren Informationen überprüft werden.
  • Unklar ist auch, ob die Protokolldatei in UTC oder Ortszeit meldet, nd zu welcher Zeit der Bericht erstellt werden soll. "last 24 hrs" muss möglicherweise um die lokale Zeitverschiebung korrigiert werden.

Das Drehbuch

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

Wie benutzt man

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es als get_log.py
  2. Führen Sie es mit der Quelldatei, der Ausgabedatei und der Uhrzeit als Argumente aus:

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

Wie bereits erwähnt, muss möglicherweise die Zeit (24) Von der lokalen Zeitzone festgelegt werden. Lass es mich wissen, bitte.

Was es macht

  • Das Skript sucht nach Zeilen mit einem Zeitstempel, der eine Zeit innerhalb des festgelegten Zeitraums (in x Stunden) anzeigt und die Zeit aus der Epoche vergleicht. Im Falle einer Übereinstimmung wird geprüft, ob sich eine der bedingten Zeichenfolgen in der Datei befindet.
  • In diesem Fall wird die Zeile in den Bericht geschrieben

BEARBEITEN

OP erwähnte, dass es nicht funktionierte. Ein Test auf beiden OP-Beispielen, der auf Anfrage veröffentlicht wurde, zeigt jedoch, dass das Skript die Aufgabe perfekt erfüllt:

Warum funktioniert es?

  • Beispiel-Zeitstempel von Op:

    2016/11/27 13:55:00
    

    wird in das Format konvertiert:

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

    durch die Linie:

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

    und anschließend zu Epoche konvertiert:

    tstamp = convert_toepoch(pattern, stamp)
    
  • Die Linie:

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

    wählt ab sofort Zeilen aus, die mit last_hrs gestempelt sind.

  • Die Linie:

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

    anschließend wird geprüft, ob eine der folgenden Zeichenfolgen vorhanden ist:

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

    tritt in der Zeile auf.

Wie bereits erwähnt, habe ich es gründlich mit den mitgelieferten genauen Beispielen getestet und kann zu keinem anderen Ergebnis kommen, als dem, dass das Skript seine Aufgabe erfüllt.

2
Jacob Vlijm