Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Stringi i inne boxerki
phpamator
post
Post #1





Grupa: Zarejestrowani
Postów: 328
Pomógł: 3
Dołączył: 10.07.2016
Skąd: UK-raine

Ostrzeżenie: (0%)
-----


Hej hej, witajcie przedszkolaki,
Po dość długiej przerwie wpadłem z pytaniem za które z pewnością zaraz dostanę po głowie ale niech tam smile.gif

Otóż chciałbym sobie wyciągać pewne dane z logów czytając linią po linii. Samo czytanie nie nastręcza żadnych problemów, jednak gdy przychodzi do dzielenia łańcucha ....

.... tu zaczynają się schodki, pewnie dlatego, że powinienem się za to wziąć już dawno temu ale jakoś tak wyszło .... że zajmowałem się innymi rzeczami a te ważne leżały "na półce".

Ale do rzeczy, w każdej linii mam różne sekcje, posłużę się przykładem:

2017-03-12 03:22:01,957 fail2ban.server [15071]: INFO rollover performed on /var/log/fail2ban.log
2017-03-18 12:42:38,575 fail2ban.filter [14691]: INFO [sshd] Found 95.68.146.94
2017-03-18 13:52:21,277 fail2ban.filter [14691]: INFO [sshd] Found 94.50.247.182
2017-03-18 13:52:23,864 fail2ban.filter [14691]: INFO [sshd] Found 94.50.247.182
2017-03-18 13:52:24,170 fail2ban.actions [14691]: NOTICE [sshd] Ban 94.50.247.182
2017-03-18 13:52:26,355 fail2ban.filter [14691]: INFO [sshd] Found 94.50.247.182
2017-03-18 14:07:57,173 fail2ban.filter [14691]: WARNING Determined IP using DNS Lookup: 1-34-200-253.hinet-ip.hinet.net = ['1.34.200.253']
2017-03-18 14:07:57,174 fail2ban.filter [14691]: INFO [sshd] Found 1.34.200.253
2017-03-18 14:07:59,521 fail2ban.filter [14691]: INFO [sshd] Found 1.34.200.253
2017-03-18 14:07:59,848 fail2ban.actions [14691]: NOTICE [sshd] Ban 1.34.200.253
2017-03-18 14:08:01,844 fail2ban.filter [14691]: INFO [sshd] Found 1.34.200.253
2017-03-18 16:35:53,379 fail2ban.filter [14691]: INFO [sshd] Found 123.169.205.199
2017-03-18 16:35:54,980 fail2ban.filter [14691]: INFO [sshd] Found 123.169.205.199
2017-03-18 16:35:55,618 fail2ban.actions [14691]: NOTICE [sshd] Ban 123.169.205.199
mniej więcej takie coś.
[edyta]Jak widać nie wszystkie linie są tak samo zorganizowane ale wybieram tylko te gdzie wykonana została akcja "Ban" i tylko te rozbijam po czym zapisuję do bazy.




Mógłbym sobie policzyć ile każdy segment średnio zajmuje i potem dzielić string na kawałki ale to chyba nie najlepszy pomysł szczególnie, że te "segmenty" nie są tej samej długości a co za tym idzie .... mogą się pojawić błędy. Chyba, że ustawię np pierwszych kilka których długość się nie zmienia a resztę ile wlezie do końca linii.

Nie sądzę jednak aby to miało sens, dlatego pytam, jak to zrobić, żeby za każdym razem linia była dzielona tak samo ?
Druga część pytania: mogę sobie wstaić jakiś delimiter (zamiast spacji) ale jak zauważyliście miejscami spacji jest kilka, nie byłoby problemu gdyby każdy segment oddzielony był jedną ....

Podpowiedzcie proszę, jak?


Pozdrawiam
amator

Ten post edytował phpamator 18.03.2017, 21:58:57
Go to the top of the page
+Quote Post
Pyton_000
post
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


preg_match i robisz sobie pattern. dla tego będzie to np:
Kod
(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d,\d{3}) ([\w.]+?) \[(\d+)\]: (.+)
Go to the top of the page
+Quote Post
Tomplus
post
Post #3





Grupa: Zarejestrowani
Postów: 1 879
Pomógł: 230
Dołączył: 20.03.2005
Skąd: Będzin

Ostrzeżenie: (0%)
-----


Tak jak napisał Python, ale dla podpowiedzi dalej... przetestuj sobie taki pattern np. tutaj: http://regex101.com

Dzięki takiemu narzędziu w prosty i szybki sposób przetestujesz kilka wierszy na raz, dodatkowo ucząc się co dana reguła powoduje w wyrażeniu.
Go to the top of the page
+Quote Post
phpamator
post
Post #4





Grupa: Zarejestrowani
Postów: 328
Pomógł: 3
Dołączył: 10.07.2016
Skąd: UK-raine

Ostrzeżenie: (0%)
-----


Dobrze, że nie pokazałem wam jak sobie poradziłem bo by "kupa" smiechu była i wstyd wink.gif

ale oczywiście chciałbym zrobić to w sposób optymalny i najbardziej poprawny. Dlatego dla porządku wyedytowałem pierwszy post i wkleiłem kilka linii przykładowych co by wszyscy widzieli o czym dokładnie mowa.
Go to the top of the page
+Quote Post
KsaR
post
Post #5





Grupa: Zarejestrowani
Postów: 520
Pomógł: 102
Dołączył: 15.07.2014
Skąd: NULL

Ostrzeżenie: (0%)
-----


preg_* by zapewnił poprawność, ale możesz spróbować w prostszy sposób czy działa ok:
  1. explode("\n", $logs);

Wynik testu - https://eval.in/756896

Ten post edytował KsaR 19.03.2017, 02:13:56


--------------------
Go to the top of the page
+Quote Post
Pyton_000
post
Post #6





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Tak na szybko:
  1. <?php
  2.  
  3. $fileLog = 'path/to/log';
  4.  
  5. $lines = file($fileLog, FILE_IGNORE_NEW_LINES);
  6. $fail2ban = array_filter($lines, function($value) {
  7. return stripos($value, 'fail2ban') !== false;
  8. });
  9.  
  10. foreach ($fail2ban as $item) {
  11. preg_match('/(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d,\d{3}) ([\w.]+?) \[(\d+)\]: (.+)/', $item, $match);
  12. var_dump($match);
  13. }
Go to the top of the page
+Quote Post
phpamator
post
Post #7





Grupa: Zarejestrowani
Postów: 328
Pomógł: 3
Dołączył: 10.07.2016
Skąd: UK-raine

Ostrzeżenie: (0%)
-----


Cytat(KsaR @ 19.03.2017, 02:13:27 ) *
preg_* by zapewnił poprawność, ale możesz spróbować w prostszy sposób czy działa ok:
  1. explode("\n", $logs);

Wynik testu - https://eval.in/756896


Działa, to najprostsza metoda na podzielenie i wrzucenie do tablicy.
Nie do końca jednak rozwiązuje to problem bo każdy element tablicy muszę ponownie dzielić. Dlatego regex będzie najlepszym rozwiążaniem ale tylko na okreslone linie.
Jak wspominałem nie wszystkie one są tak samo zbudowane, w niektórych jak widać na załączonym przykładzie układ elementów jest inny, część także zawiera dodatkowe dane.
Dlatego zrobiłem tak, że wybieram tylko te linie w których wystąpił string "Ban" i tylko te dzielę i wrzucam do tabeli.
ale ... w dalszej części mojego zadania muszę zrobić coś takiego:
najpierw zliczam ile linii znajduje się w pliku/logu, następnie odczytuję z tabeli ile linni było przy poprzednim sprawdzaniu, obliczam różnicę i sprawdzam tylko tyle linii ile zostało dopisanych od ostatniego sprawdzania.
I tu mam pytanie kolejne, jak byście to zrobili, czy puścili pętlę z ostatnio zanotowaną ilością linii i te poprostu pominęli a sprawdzanie zaczęli od ilości z poprzedniego sprawdzenia + 1? Mam nadzieję, że wiecie co mam na myśli /

... coś takiego $ostatnioLiniibylo więc
  1. foreach(file($linie as linia)){$i++;
  2. if($i >= $ostatnioLiniibylo){
  3. //wykonujemy sprawdzanie
  4. }
  5. }
  6.  

czy np obliczyć do której linii skoczyć i od tej kontynuować ?
Go to the top of the page
+Quote Post
Pyton_000
post
Post #8





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Przecież dałem CI gotowe rozwiązanie.
Jeśli chodzi o modyfikację tego to odczytujesz kolejne linie fgets() sprawdzasz czy data lini jest > od zapisaniej ostatniej daty parsowania (tak,powinieneś sobie to gdzieś zapisać) jeśli tak to lecisz dalej i parsujesz sobie jak chcesz...
Go to the top of the page
+Quote Post
phpamator
post
Post #9





Grupa: Zarejestrowani
Postów: 328
Pomógł: 3
Dołączył: 10.07.2016
Skąd: UK-raine

Ostrzeżenie: (0%)
-----


Ooops, dzięki, już "pacze" wink.gif
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 05:59