Stworzyłem skrypt, który pomaga mi analizować pliki dziennika dostępu bez SSH na serwerze (mam tylko ten plik). Liczy i sortuje liczbę adresów IP, którymi zarządzam, ale okazało się, że w przypadku dużych plików zajmuje to zbyt dużo czasu (jest to BARDZO podstawowe). Nie chciałem używać skompilowanej aplikacji i nie mam SSH na serwerze, więc zwróciłem się do Powershell.
$sw = [Diagnostics.Stopwatch]::StartNew()
$input_path = ‘c:\temp\access_log2’
$ip_file = ‘c:\temp\IPs.txt’
$output_file = ‘c:\temp\SORTED.txt’
$regex = '\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b'
select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $ip_file
get-content $ip_file | group-object -noelement | Sort-Object count -descending > $output_file
get-Content $output_file -First 25
$sw.Stop()
$sw.Elapsed
Też próbowałem
$regex = ‘\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b’
na pliku 5 MB (14,4 tys. linii) zajęło 18 minut na pliku 37 MB (158,5 tys. linii), zajęło to ponad 3 godziny
Stoper służy tylko do moich testów. Skrypt służy tylko do pobrania adresu IP, policzenia ich i posortowania według najczęściej występujących. Być może zapisywanie plików jest największym spowolnieniem, ale nie znam zbytnio zmiennych przechowywanych w pamięci RAM. Wydaje mi się, że istnieje lepszy sposób na wyodrębnienie adresów IP (może po prostu użyć pierwszych 15 znaków w wierszu?). Oto przykład linii, Combined Log Format
21.198.52.3 - - [06/Aug/2017:11:31:54 -0400] "GET / HTTP/1.0" 301 452 "-" "-"
154.212.178.24 - - [06/Aug/2017:11:10:44 -0400] "GET /images/12345.jpg HTTP/1.1" 200 212443 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.2; +http://ahrefs.com/robot/)"
Jakakolwiek rada?
źródło
Odpowiedzi:
Jest prostsze (miejmy nadzieję szybsze podejście), jeśli ip prowadzi każdą linię. Prosty podział w przestrzeni powinien oddzielić ip.
Podczas przetwarzania linii możesz zwiększyć tablicę hasht, zaadresowaną przez ip
Przykładowe dane wyjściowe tylko z replikowanymi liniami:
źródło
Count Name ----- ---- ...52 127.171.123.44
Name Value ---- ----- 127.171.123.44 145214
To nie odcina wartości zliczania, gdy ma ponad 6 cyfr, ani nie przechwytuje adresów IP agentów, które mogą znajdować się poniżej wiersza zapisu dziennika, noiceDlaczego zapisujesz swoje dane w pliku pośrednim (
$ip_file
)? Dlaczego nie przekazać go bezpośrednio do obiektu grupy? Być może coś takiego?Jeśli to nie przyspieszy, prawdopodobnie powinieneś spróbować dowiedzieć się, która część skryptu jest wolna.
Może zacznij od zrobienia czegoś takiego. Następnie dodaj trochę funkcjonalności, aby zobaczyć, gdzie jest powolność.
Jeśli chcesz założyć, że plik dziennika jest zawsze poprawnie sformatowany, prawdopodobnie możesz przyspieszyć i po prostu pobrać pierwszą kolumnę. (To przetworzyło 233 MB, 1 000 749 linii pliku dziennika apache na moim komputerze w około 15 sekund)
źródło