logfile parsen
Roger
- php
moin!
ich würde gern ein logfile mittels php auswerten, welches mein router an einen syslog-server gesendet hat.
die einträge sehen wie folgt aus:
Jan 27 11:19:10 192.168.1.1 Vigor: Local User: 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
damit ich das log auswerten kann, muss ich zunächst alle werte in ein array bekommen. leider gibt es kein trennzeichen zwischen den einzelnen spalten ("Vigor: Local User:" schießt da ein wenig quer).
nun ist die frage die, ob ich einfach alles stur per explode(" ", $str) in einen array bringe und dann im nachheinein die felder noch zusammenstricke (zb. datum), oder ob es (zumindest für den server) einfacher / resourcenschonender ist, wenn ich mit regexp arbeite? wobei bei letzterem mir nat. klar das wissen fehlt. aber ich bin nat. aufgeschlossen für alles :)
gruß.
roger.
Hallo,
leider gibt es kein trennzeichen zwischen den einzelnen spalten
Und woran erkennt dann der Mensch, wo eine Spalte[1] anfängt und aufhört?
[1] Definiere doch bitte mal den Begriff 'Spalte'.
LG
Chris
moin!
[1] Definiere doch bitte mal den Begriff 'Spalte'.
ein mehrdimensionaler array besteht doch aus zeilen und spalten. nich? pro spalte steht eben der dazugehörige wert.
in meinem fall müsste der kopf der spalten so heißen:
timestamp | router-ip | router-message | interne ip:port | externe ip:port | portbeschreibung
gruß.
roger.
Hallo,
[1] Definiere doch bitte mal den Begriff 'Spalte'.
ein mehrdimensionaler array besteht doch aus zeilen und spalten. nich? pro spalte steht eben der dazugehörige wert.
in meinem fall müsste der kopf der spalten so heißen:
timestamp | router-ip | router-message | interne ip:port | externe ip:port | portbeschreibung
Vergiss doch bitte mal einen Moment lang deine IT-Kenntnisse und formuliere einfach, woran _DU_ persönlich eine Spalte erkennst in dem Logbuch, dargestellt mit den üblichen Programmen (Texteditor) oder sogar ausgedruckt auf Papier...
Woher kommt das Log? Ist das ein übliches Apache-Log?
LG
Chris
moin!
Vergiss doch bitte mal einen Moment lang deine IT-Kenntnisse und formuliere einfach, woran _DU_ persönlich eine Spalte erkennst in dem Logbuch, dargestellt mit den üblichen Programmen (Texteditor) oder sogar ausgedruckt auf Papier...
na anhand der inhalte, die ich versucht habe in meinem letzten posting (spaltenüberschrift) zu beschreiben.
Woher kommt das Log? Ist das ein übliches Apache-Log?
nein:
ich würde gern ein logfile mittels php auswerten, welches mein router an einen syslog-server gesendet hat.
gruß.
roger.
Hallo Roger,
timestamp | router-ip | router-message | interne ip:port | externe ip:port | portbeschreibung
- %{timestamp} hat eine immergleichbleibende Länge
- %{router-ip} trennt sich von %{router-message} durch ein einzelnes Leerzeichen
- %{interne ip:port} trennt sich durch ein Leerzeichen von %{router-message} ab
- %{interne ip:port} trennt sich von %{externe ip:port} durch String ' -> ' ab
- %{externe ip:port} trennt sich von %{portbeschreibung} durch ein Leerzeichen ab
nach dieser aufgezeigten Logik kommst Du mit (bspw.) substr() und explode() an alle Teile heran
Gruß aus Berlin!
eddi
moin!
nach dieser aufgezeigten Logik kommst Du mit (bspw.) substr() und explode() an alle Teile heran
ja, danke!
allerdings gibt's da noch ein klitzekleines problemchen:
router-message ändert sich. moment! ha, es fängt zumindest immer mit "vigor:" an. ok, und auf das kann man ja auch prüfen.
nun ja, der grundstein ist gelegt ;)
gruß.
roger.
Re:
nach dieser aufgezeigten Logik kommst Du mit (bspw.) substr() und explode() an alle Teile heran
ja, danke!
allerdings gibt's da noch ein klitzekleines problemchen:
router-message ändert sich. moment! ha, es fängt zumindest immer mit "vigor:" an. ok, und auf das kann man ja auch prüfen.
denksde :þ
Nach skizziertem Schema würede %{router-message} per Ausschluß ermittelt werden.
Gruß aus Berlin!
eddi
moin!
denksde :þ
Nach skizziertem Schema würede %{router-message} per Ausschluß ermittelt werden.
shit. klang so einfach...
- %{router-ip} trennt sich von %{router-message} durch ein einzelnes Leerzeichen
- %{interne ip:port} trennt sich durch ein Leerzeichen von %{router-message} ab
um router-message auszuschließen, müsste man hier wohl mittels regexp die positionen der beiden ips (router, intern) ausfindig machen. korrekt?
gruß.
roger.
Hallo Roger,
timestamp | router-ip | router-message | interne ip:port | externe ip:port | portbeschreibung
- %{timestamp} hat eine immergleichbleibende Länge
- %{router-ip} trennt sich von %{router-message} durch ein einzelnes Leerzeichen
- %{interne ip:port} trennt sich durch ein Leerzeichen von %{router-message} ab
- %{interne ip:port} trennt sich von %{externe ip:port} durch String ' -> ' ab
- %{externe ip:port} trennt sich von %{portbeschreibung} durch ein Leerzeichen ab
$a=file('log.datei');
$c=count($a);
for($i=0;$i<$c;$i++){
$b[$i]['time']=substr($a[$i],0,15);
$v=substr($a[$i],16);
list($b[$i]['r-ip'],$v)=explode(' ',$v,2);
$v=explode(' -> ',$v);
$b[$i]['msg']=substr($v[0],0,strrpos($v[0],' ')+1);
$b[$i]['i-ip']=substr($v[0],strrpos($v[0],' '));
list($b[$i]['e-ip'],$b[$i]['po-b'])=explode(' ',$v[1]);
}
so, wie ich es geschrieben hatte...
Selber denken hätte Dich jetzt weiter gebracht!
Gruß aus Berlin!
eddi
moin!
danke. hatte ich doch aber schon. sry.
ich hatte es nur ein wenig anders gemacht. und zwar habe ich beim datei-einlesen gleich auf bestimmte werte überprüft um den speicher nicht zu belasten. deswegen hab ich mit fgetcsv() gearbeitet. oder ist das falsch?
gruß.
roger.
Hi,
die einträge sehen wie folgt aus:
Jan 27 11:19:10 192.168.1.1 Vigor: Local User: 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
wirklich? Apache-Logs z.B. lassen sich eindeutig anhand der Leerzeichen trennen, wenn man nur die in "" bzw. [] eingeschlssenen Strings zusammen läßt.
freundliche Grüße
Ingo
Hallo,
wirklich? Apache-Logs z.B. lassen sich eindeutig anhand der Leerzeichen trennen, wenn man nur die in "" bzw. [] eingeschlssenen Strings zusammen läßt.
Nicht so ganz...
Denn die Aufruf-Methoden (GET, POST, HEAD, ...) hätten z.B. auch eine eigene Spalte verdient. Und Der Text im Client/Accept-Header ist auch recht variabel.
Allerdings kann man sich das Format "vernünftig" einstellen, wenn man auf die Konfiguration des Servers Zugriff hat. Echtes CSV wäre eine Lösung, wenn auch nicht die Beste, da das dann nicht mehr mit jedem Editor lesbar wäre.
Lieber wäre mir für das ungepackte Log-Format ein festes Satzformat. Dann könnte man in den Logs auch extrem schnell navigieren. Leider kenne ich beim Apache keine Konfiguration, die feste Spaltenbreiten ermöglicht. Wäre beim Accept-Header auch schon wieder enorme Platzverschwendung *g*
LG
Chris
Hi,
wirklich? Apache-Logs z.B. lassen sich eindeutig anhand der Leerzeichen trennen, wenn man nur die in "" bzw. [] eingeschlssenen Strings zusammen läßt.
Nicht so ganz...
Denn die Aufruf-Methoden (GET, POST, HEAD, ...) hätten z.B. auch eine eigene Spalte verdient.
können sie doch bekommen: suche nach dem ersten in "" gesetzten String und extrahiere hieraus die Zeichen bis zum ersten Space.
Und Der Text im Client/Accept-Header ist auch recht variabel.
Du meinst z.B. HTTP/1.1? Der steht in meinen Standard-Logfiles im besagten String nach dem zweiten Leerzeichen; leicht herauszufiltern.
freundliche Grüße
Ingo
Hallo,
Denn die Aufruf-Methoden (GET, POST, HEAD, ...) hätten z.B. auch eine eigene Spalte verdient.
können sie doch bekommen: suche nach dem ersten in "" gesetzten String und extrahiere hieraus die Zeichen bis zum ersten Space.
Und Der Text im Client/Accept-Header ist auch recht variabel.
Du meinst z.B. HTTP/1.1? Der steht in meinen Standard-Logfiles im besagten String nach dem zweiten Leerzeichen; leicht herauszufiltern.
Mit Client ist mutmaßlich der Header "User-Agent" gemeint und did Header Accept(-*) sind in der Tat sehr diffiziel zu parsen. Aber daran wird deutlich, wenn man eben die Funktionalität von mod_log_config ausschöpft, statt defaults (worauf Deine Anmerkungen ja anwendbar sein mögen) zu verwenden, das hier, wie bereit von Dir angemerkt wurde, überaus sinnvoll ist mit "sonderzeichen" à la []"'# zu arbeiten.
Nur im eigentlichen geht es nicht um einen log stream Apaches!
Gruß aus Berlin!
eddi
moin!
Jan 27 11:19:10 192.168.1.1 Vigor: Local User: 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
wirklich? Apache-Logs z.B. lassen sich eindeutig anhand der Leerzeichen trennen
wie auch immer. aber o.g. ist kein apache log, sondern wie in meinem allerersten satz beschrieben ein log meines routers, welches an eine linux-maschine mit installiertem syslogd gesendet wird. und darauf hat man leider keinerlei einfluss.
gruß.
roger.
Nabend,
moin!
ich würde gern ein logfile mittels php auswerten, welches mein router an einen syslog-server gesendet hat.
die einträge sehen wie folgt aus:Jan 27 11:19:10 192.168.1.1 Vigor: Local User: 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
damit ich das log auswerten kann, muss ich zunächst alle werte in ein array bekommen. leider gibt es kein trennzeichen zwischen den einzelnen spalten ("Vigor: Local User:" schießt da ein wenig quer).
Dann sieht ein Logfile-Eintrag aber eher so aus:
Jan 27 11:19:10 192.168.1.1 "Vigor: Local User:" 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
Zerleg den String doch erstmal an den "Gänsefüßchen":
$log_entry = 'Jan 27 11:19:10 192.168.1.1 "Vigor: Local User:" 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web';
$bla = explode('"', $log_entry);
Jetzt hast du drei Teile, von denen du den mittleren behältst, und die anderen beiden weiter zerlegen kannst:
$blo = explode(' ', $bla[0]);
$bla = $bla[1];
$bli = explode(' ', $bla[2]);
Das sollten jetzt drei Arrays sein, die folgende Inhalte haben:
$blo:
[0] => 'Jan'
[1] => '27'
[2] => '11:19:10'
[3] => '192.168.1.1'
$bla:
[0] => 'Vigor: Local User:'
$bli:
[0] => '192.168.1.64:1562'
[1] => '->'
[2] => '216.239.59.104:80'
[3] => '(TCP)Web'
Die kannst du jetzt "zusammenstricken" ... ;-)
MffG
EisFuX
moin!
Jan 27 11:19:10 192.168.1.1 Vigor: Local User: 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
("Vigor: Local User:" schießt da ein wenig quer).Dann sieht ein Logfile-Eintrag aber eher so aus:
Jan 27 11:19:10 192.168.1.1 "Vigor: Local User:" 192.168.1.64:1562 -> 216.239.59.104:80 (TCP)Web
nein, weil es gibt keine gänsefüßchen. ich hab die nur zur verdeutlichung gesetzt. ganz oben steht ein copy&paste aus dem logfile und da sind keine dabei.
aber danke für deine mühe. war sehr umfangreich.
gruß.
roger.