2011-10-09 1 views
27

Il mio server ha un utilizzo della CPU insolitamente elevato e vedo che Apache utilizza troppa memoria. Ho la sensazione, sono stato DOS da un singolo IP - forse puoi aiutarmi a trovarlo?Voci del file di registro del filtro in base all'intervallo di date

Ho usato la seguente linea, per trovare i 10 più IP "attive":

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

La top 5 IP hanno circa 200 volte il numero di richieste al server, come l'utente "medio" . Tuttavia, non riesco a scoprire se questi 5 sono solo visitatori molto frequenti, o stanno attaccando i server.

C'è un modo, per specificare la ricerca sopra a un intervallo di tempo, ad es. le ultime due ore O tra le 10 e le 12 di oggi?

Cheers!

AGGIORNATO 23 ottobre 2011 - I comandi avevo bisogno:

Diventa iscrizioni entro le ore ultimo X [qui due ore]

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

Get IP piu 'attivo nelle ultime ore X [qui due ore]

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 

Ricevi voci all'interno relativo periodo

012.351.641.061.
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 

Get voci all'interno periodo assoluta

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 

Get IP piu 'attivo nelle periodo assoluta

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 
+1

Sono pigro; Copio il registro in Excel e creo una tabella pivot ... – Ben

+0

@Ben "Ora hai due problemi." – tripleee

risposta

29

sì, ci sono diversi modi per farlo. Ecco come andrei su questo. Per i principianti, non è necessario reindirizzare l'output di cat, basta aprire il file di registro con awk.

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

supponendo che il registro si presenta come la mia (sono configurabili) oltre la data è memorizzato nel campo 4. ed è tra parentesi. Quello che sto facendo sopra è trovare tutto nelle ultime 2 ore. Note the -d'now-2 hours' o tradotto letteralmente ora meno 2 ore che per me assomiglia a questo: [10/Oct/2011:08:55:23

Quindi quello che sto facendo è memorizzare il valore formattato di due ore fa e confrontandolo con il campo quattro. L'espressione condizionale dovrebbe essere diretta. In seguito stampo la data, seguita dal separatore dei campi di output (OFS - o spazio in questo caso) seguito dall'intera riga $ 0. Si potrebbe usare la tua espressione precedente e basta stampare $ 1 (gli indirizzi IP)

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

Se si voleva utilizzare una gamma di specificare due variabili di data e costruire la tua espressione in modo appropriato.

quindi se si voleva fare trovare qualcosa tra 2-4 ore fa la vostra forza di espressione sembra qualcosa di simile

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' 

Ecco una domanda ho risposto per quanto riguarda le date in bash vi possono essere utili. Print date for the monday of the current week (in bash)

+0

Grazie amico! Grandi esempi con buone spiegazioni. Ho elaborato il tuo codice per le mie esigenze specifiche e l'ho aggiunto alla domanda originale per riferimento futuro per me stesso e gli altri bisognosi. – sqren

+0

sono contento che potrebbe essere di aiuto. – matchew

+0

Un'ultima cosa. Come posso cercare tra più file di registro? Sto provando con find e xargs ma ancora senza fortuna: find -name 'access.log' | awk -vDate = 'date -d '13: 20 '+ [% d /% b /% Y:% H:% M:% S' -vDate2 =' date -d'13: 40' + [% d/% b /% Y:% H:% M:% S' '{if ($ 4> Data e& $ 4 sqren

1

come questo è un comune compito

E perché questo non è esattamente lo stesso di quello extract last 10 minutes from logfile in cui si tratta di un sacco di tempo fino alla fine del file di log.

E perché li ho bisogno, io (rapidamente) ha scritto questo:

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

Questo potrebbe essere utilizzato come:

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

per i registri di stampa tra le 09h18 e 09h24.

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

per la stampa da january 23th, 9h18'12" fino ora.

Al fine di ridurre il codice Perl, ho usato -s interruttore per consentire l'auto-assegnazione di variabili da riga di comando: -s=09:18 sarà popolare un $s wich variabile conterrà 09:18. Cura di non perdere il segno uguale = e nessuno spazio!

Nota: Questo contenere due tipi di diffent regex per due diversi standard di log. Se avete bisogno di diverse analisi formato data/ora, o inviare il proprio regex o inviare un campione di data formattata dal vostro file di log

^(\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] 
+0

Risposta molto bella, l'ho aggiunta a un ciclo e posso facilmente indagare su cosa è successo su un server. – user322049

1

Se qualcuno incontra con la awk: invalid -v option, ecco uno script per ottenere gli IP più attivi in ​​un intervallo di tempo predefinito:

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