it-swarm.com.de

Filtern Sie Protokolleinträge basierend auf dem Datumsbereich

Mein Server hat eine ungewöhnlich hohe CPU-Auslastung, und ich sehe, dass Apache viel zu viel Speicher belegt. Ich habe das Gefühl, ich werde durch eine einzige IP DOS-Adresse behandelt - können Sie mir vielleicht helfen, ihn zu finden?

Ich habe die folgende Zeile verwendet, um die 10 "aktivsten" IPs zu finden:

cat access.log | awk '{print $1}' |sort  |uniq -c |sort -n |tail

Die Top-5-IPs haben ungefähr 200-mal so viele Anfragen an den Server wie der "durchschnittliche" Benutzer. Ich kann jedoch nicht herausfinden, ob diese 5 Besucher nur sehr häufig sind oder die Server angreifen.

Gibt es Möglichkeiten, die obige Suche auf ein Zeitintervall festzulegen, z. die letzten zwei Stunden OR zwischen 10-12 heute?

Prost!

AKTUALISIERT AM 23 OKT 2011 - Die Befehle, die ich brauchte:

Erhalten Sie Einträge innerhalb der letzten X Stunden [Hier zwei Stunden]

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date) print Date FS $4}' access.log

Holen Sie sich die aktivsten IPs innerhalb der letzten X Stunden [Hier zwei Stunden]

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date) print $1}' access.log | sort  |uniq -c |sort -n | tail

Holen Sie sich Einträge innerhalb der relativen Zeitspanne

awk -vDate=`date -d'now-4 hours' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print Date FS Date2 FS $4}' access.log

Holen Sie sich Einträge innerhalb der absoluten Zeitspanne

awk -vDate=`date -d '13:20' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'13:30' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print $0}' access.log 

Holen Sie sich die aktivsten IPs innerhalb der absoluten Zeitspanne

awk -vDate=`date -d '13:20' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'13:30' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print $1}' access.log | sort  |uniq -c |sort -n | tail
35
sqren

ja, es gibt mehrere Möglichkeiten, dies zu tun. Hier ist, wie ich vorgehen würde. Für den Anfang muss die Ausgabe von cat nicht weitergeleitet werden. Öffnen Sie einfach die Protokolldatei mit awk.

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` '$4 > Date {print Date, $0}' access_log

angenommen, Ihr Protokoll sieht wie meins aus (sie sind konfigurierbar), als das Datum in Feld 4 gespeichert ist und in Klammern steht. Was ich oben mache, ist alles innerhalb der letzten 2 Stunden zu finden. Note the -d'now-2 hours' oder wörtlich übersetzt jetzt minus 2 Stunden was für mich ungefähr so ​​aussieht: [10/Oct/2011:08:55:23

Ich speichere also den vor zwei Stunden formatierten Wert und vergleiche ihn mit Feld vier. Der bedingte Ausdruck sollte einfach sein. Ich drucke dann das Datum, gefolgt vom Ausgabefeldtrennzeichen (in diesem Fall OFS - oder Leerzeichen), gefolgt von der gesamten Zeile $ 0. Sie könnten Ihren vorherigen Ausdruck verwenden und nur $ 1 (die IP-Adressen) ausgeben.

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` '$4 > Date {print $1}' | sort  |uniq -c |sort -n | tail

Wenn Sie einen Bereich verwenden möchten, geben Sie zwei Datumsvariablen an und erstellen Sie Ihren Ausdruck entsprechend.

wenn Sie also zwischen 2 und 4 Stunden zuvor etwas gefunden haben möchten, sieht Ihr Ausdruck möglicherweise so aus

awk -vDate=`date -d'now-4 hours' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` '$4 > Date && $4 < Date2 {print Date, Date2, $4} access_log'

Hier ist eine Frage, die ich in Bezug auf Daten in Bash beantwortet habe, die Sie vielleicht hilfreich finden. Druckdatum für den Montag der aktuellen Woche (in Bash)

38
matchew

Wenn jemand mit dem awk: invalid -v option, hier ist ein Skript, um die aktivsten IPs in einem vordefinierten Zeitbereich abzurufen:

cat <FILE_NAME> | awk '$4 >= "[04/Jul/2017:07:00:00" && $4 < "[04/Jul/2017:08:00:00"' | awk '{print $1}' | sort -n | uniq -c | sort -nr | head -20
2

Da dies eine häufigPerl Aufgabe ist

Und weil dies nicht genau dasselbe ist wie extrahiere die letzten 10 Minuten aus der Logdatei wo es um eine Menge Zeit bis zum Ende der Logdatei geht.

Und weil ich sie gebraucht habe, habe ich (schnell) folgendes geschrieben:

#!/usr/bin/Perl -ws
# This script parse logfiles for a specific period of time

sub usage {
    printf "Usage: %s -s=<start time> [-e=<end time>] <logfile>\n";
    die $_[0] if $_[0];
    exit 0;
}

use Date::Parse;

usage "No start time submited" unless $s;
my $startim=str2time($s) or die;

my $endtim=str2time($e) if $e;
$endtim=time() unless $e;

usage "Logfile not submited" unless $ARGV[0];
open my $in, "<" . $ARGV[0] or usage "Can't open '$ARGV[0]' for reading";
$_=<$in>;
exit unless $_; # empty file
# Determining regular expression, depending on log format
my $logre=qr{^(\S{3}\s+\d{1,2}\s+(\d{2}:){2}\d+)};
$logre=qr{^[^\[]*\[(\d+/\S+/(\d+:){3}\d+\s\+\d+)\]} unless /$logre/;

while (<$in>) {
    /$logre/ && do {
        my $ltim=str2time($1);
        print if $endtim >= $ltim && $ltim >= $startim;
    };
};

Dies könnte verwendet werden wie:

./timelapsinlog.pl -s=09:18 -e=09:24 /path/to/logfile

zum Drucken von Protokollen zwischen 09h18 und 09h24.

./timelapsinlog.pl -s='2017/01/23 09:18:12' /path/to/logfile

zum Drucken von january 23th, 9h18'12" bis jetzt.

Um den Perl-Code zu reduzieren, habe ich die Option -s Verwendet, um die automatische Zuweisung von Variablen über die Befehlszeile zu ermöglichen: -s=09:18 Füllt eine Variable $s, Die 09:18. Achten Sie darauf, das Gleichheitszeichen = Und keine Leerzeichen zu verpassen!

Nota: Dies enthält zwei verschiedene Arten von regulären Ausdrücken für zwei verschiedene Protokollstandards. Wenn Sie ein anderes Datums-/Zeitformat-Parsing benötigen, veröffentlichen Sie entweder Ihren eigenen regulären Ausdruck oder ein Beispiel für ein formatiertes Datum aus Ihrer Protokolldatei

^(\S{3}\s+\d{1,2}\s+(\d{2}:){2}\d+)         # ^Jan  1 01:23:45
^[^\[]*\[(\d+/\S+/(\d+:){3}\d+\s\+\d+)\]    # ^... [01/Jan/2017:01:23:45 +0000]
2
F. Hauri