Toon posts:

[perl] syslog ontleden

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil het volgende doen:

Met een cronjob tail ik de laatste bijvoorbeeld 100 lijnen uit de syslog. Dan wil ik dat perl het volgende doet:

Zoek op lijnen met het volgende:
May 31 11:55:54 xas kernel: NET: 4024 messages suppressed.
En als ie dat ziet, en het aantal (hier dus 4024) meer dan bijvoorbeeld 10 is, de VOLGENDE lijn pakt en die gaat ontleden. Die lijn ziet er ongeveer zo uit:
May 31 11:55:54 xas kernel: TCP: drop open request from 123.123.123.123/3718
Dan wil ik dat hij het ip adres daar uithaalt, en daar dan wat mee gaat doen.

Het lukt mij wel om de laatste 100 lijnen te tailen en in een array te zetten. Het grootste probleem vind ik eigenlijk het zoeken en ontleden van de lijnen. Wie kan me hier bij helpen? Regexen kom ik totaal niet uit...

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 16:59

gorgi_19

Kruimeltjes zijn weer op :9

En waar zit nu concreet je probleem? Welk gedeelte kom je niet uit? Wat heb je zelf geprobeerd mbt tot de regular Expressions? Hoe ver ben je tot nu toe gekomen?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Probleem zit dus bij het detecteren en vervolgens ontleden van zo'n lijn, ik heb zelf al met split en s///g; enzo lopen proberen, maar dat werkt voor geen meter. Het kan beslist met regexpen maar ik kom er dus voor geen meter uit.

[ Voor 8% gewijzigd door Verwijderd op 31-05-2004 12:32 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Een probleem moet je stap voor stap aanpakken. De eerste stap is het vinden van alle regels die volgen op zo'n logregel met aantal groter dan 10. Die functie staat los van de tweede stap, namelijk het IP adres uit de zo gevonden regels halen.

Goed, even een beginnetje maken. Je hebt een scriptje als dit:
Perl:
1
2
3
4
5
6
while($line = <>) {
    if($line =~ /messages suppressed/) {
        $next_line = <>;
        print $next_line;
    }
};

Dit print elke regel uit de invoer die volgt op een regel met de tekst 'messages supressed' erin (de code is wat uitgebreider dan nodig, maar dat is om didactische redenen wel nuttig, denk ik). Aardig begin van wat je wilt, maar zoals je al zei moet je op meer matchen dan die twee woorden alleen en bovendien wil je meer met $next_line doen dan printen alleen.

Voor beide stappen heb je alleen maar 'gewone' reguliere expressies te gebruiken. Je hoeft dus niet moeilijk te doen met global substitution of zoiets. De regular expressie voor stap 1 hoef je alleen maar uit te breiden, zo, dat je het aantal messages isoleert en vervolgens er op kunt checken (groter dan 10?). Laat eerst eens zien hoever je daar zelf mee komt.

[ Voor 7% gewijzigd door Soultaker op 31-05-2004 13:02 ]


Verwijderd

Topicstarter
ok, ik heb nu dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl
$file = '/var/log/dos';
$i=0;

(open (FILE, "$file")) || die("Can't open $file");
my @line = <FILE>;

while($line[$i]) {
        if($line[$i] =~ /messages suppressed/) {
                print $line[$i];
                print $line[$i+1];
        }
        $i++;
};

Dat werkt. Maar ik blijf met 't probleem zitten dat het me niet lukt de data uit de regel te halen...

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Het is niet de kern van je probleem, maar waarom lees je nu toch het hele bestand in het geheugen? Zoals ik al liet zien, is dat nergens voor nodig.

Maar heb je al wat gelezen over regular expressions? Hier in de FAQ staat er wel een uitgebreid verhaal inclusief links in. Ik ga de juiste code echt niet voorkauwen, want dan leer je er niets van. ;)
Pagina: 1