# Log-Datei auslesen



## Replica (14. Mai 2008)

Guten Morgen!

Ich plane grade ein Programm zum Auslesen von Log-Dateien.
Das Szenario sieht so aus, dass die Dateien, während ich auf sie zugreife ständig weitergeschrieben werden und das die Auswertung der Dateien alle paar Sekunden auf den neusten Stand gebracht werden soll.

Ich habe mir das nun so vorgestellt einen Thread zu starten, in dem GUI intialisiert, die Config des Programms eingelesen und die Dateien geöffnet werden.
Dann sollen sie in einem extra Thread auf bestimmte Werte durchsucht werden, der sich dann immer wiederholt, bis das Programm geschlossen wird und prüft, ob neue Zeilen hinzugekommen sind, diese in der Auswertung hinzufügt und selbige ausgibt.
Erst wenn das Programm geschlossen wird, soll der Stream geschlossen werden.

Ist das so möglich?
Ich lese Dateien immer mit BufferedReader->InputStreamReader->FileInputStream(file) aus. Bleibt der Steam dabei auch offen, wenn ich das Ende der Datei erreicht habe (ich wüsste nicht, was dagegen spräche, aber ich meine sowas schon mal gehört zu haben)?


----------



## Joker (14. Mai 2008)

dann du musst aber aufpassen, dass die Logdateien möglichst klein sind, sonst wird das langsam. Auch das sperren der Logdatei ist nicht so einfach zu realisieren, da kommt es dann immer drauf an, dass das die Logdatei beschreibende Programm damit zurecht kommt, das die Logdatei auch mal für ein paar Sekunden nicht schreibbar ist.

Wesentlich günstiger ist es die Logdatei komplett zu kopieren und mit der Kopie zu arbeiten. Zum Überwachen der Datei bietet es sich an mit Inotify und co  zu arbeiten (in Java realisiert z.B. durch jnotify).

Irgendwo hab ich noch ein Perl Skript rumliegen, dass diverse Logs per inotify überwacht und den Inhalt formatiert in eine DB schreibt. Wenn dir das was hilft kann ich dir das gerne schicken.


----------



## Replica (14. Mai 2008)

Erst schon mal danke für deine Antwort!

Ich denke mal (max.) 40 MB an Log-Dateien ist schon recht viel 
Werden die Dateien auch gelockt, wenn ich nur lese? Geschrieben wird dort nicht. Wenn ich die erst kopiere, dauert es noch länger :/

Aus den Logs soll eine Statistik erzeugt werden, die sich ständig aktualisieren soll und quasi in "Echtzeit" (alle paar Sek ein Update reicht) laufen soll.

Ich habe mir grade mal JNotify angeguckt, aber soweit ich das verstehe, muss das auch auf dem ausführenden Computer installiert sein.
Kennt da vielleicht jemand eine andere Alternative?

Oder einen anderen Ansatz, eine ständig weitergeschriebene Datei ständig vollständig ausgelesen zu halten?


----------



## Joker (14. Mai 2008)

musst du ausprobieren was in deinem Fall besser ist. Ich hatte ein Linux als Zielplattform. Da hat es sich angeboten eine Kopie zu erstellen und die Orginaldatei immer bis leer zu halten. Statistiken hab ich dann später auch erzeugt (inkl. schöne JFreeChart Grafiken), aber dann halt basierten auf den Daten des zentralen Logservers, der die Logdaten von 4 anderen Servern (apache, dns, syslog, etc...) und von zwei Firewalls bekommen hat.



> Ich habe mir grade mal JNotify angeguckt, aber soweit ich das verstehe, muss das auch auf dem ausführenden Computer installiert sein.
> Kennt da vielleicht jemand eine andere Alternative?



Installieren musst du da nichts. JNotify nutzt die Funktionen des Betriebssystem. INotify ab Kernel 2.6.13 auf Linuxsystemen und die WinAPI auf Windowssystemen. Man muss dann natürlich die native Bibliothek mitliefern. Der Vorteil davon ist natürlich das die Bearbeitung der Datei sofort startet und keine sekundenlange Wartezeit dazwischen liegt und das dein Programm wirklich nur aktiv wird, wenn Veränderungen in der Logdatei stattfinden.


----------



## Replica (14. Mai 2008)

Bin zu doof für JNotify. Ich kriege das nicht integriert.
Habe eigentlich alles gemacht, wie es auf der Homepage steht, aber geht nicht.
Muss ich nochmal schauen, wie ich das löse.

Aber die Dateien sind doch beim Lesen nicht gelockt, oder?


----------



## Escorter (14. Mai 2008)

Ich hab es bei mir so realisiert, dass ich mir merke wieviel Zeichen ich schon eingelesen haben.

Dann überspringe ich am Anfang die anzahl der Zeichen und lese alle neu dazu gekommenen zeichen ein.

Das ganze läuft in nem Thread mit einer Endlosschleife.

Habe immer wieder getestet und die Dateien wurden nie gelockt.
Das einzige Problem was umgangen werden muss ist, dass man auch schonmal die Datei ließt wenn die Datei nciht zu Ende geschrieben wurde. Als ambesten kommt ein Steuerzeichen an den ANFANG einer zeile (Zeilen werden von hinten geschrieben) damit du erkennst ob die Zeile komplett geschrieben wurde.

Und dann kannst du immer die neuen Zeilen auswerten und speicherst du neue Anzahl der Zeichen.

//Edit: Auch bei Logfiles > 500 MB gab es keine Probleme

Gruß,
Esco


----------



## Replica (15. Mai 2008)

Escorter hat gesagt.:
			
		

> Ich hab es bei mir so realisiert, dass ich mir merke wieviel Zeichen ich schon eingelesen haben.
> 
> Dann überspringe ich am Anfang die anzahl der Zeichen und lese alle neu dazu gekommenen zeichen ein.


Könntest du mir das bitte mal genauer erläutern?
Zählst du die Zeilen mit und springst dann beim nächsten Durchlauf an die entsprechende Stelle? Wie genau springe ich an die ensprechende Stelle in der Datei zurück, die ich mir vorher gemerkt habe?

/edit-add:
Kann ich einfach mit einem _RandomAccessFile_ auf die Datei zugreifen, dann einfach mit _readLine()_ einlesen, bis _null_. Da die Zeiger-Position mit _getFilePointer()_ speichern und dann beim nächsten Aufruf mit _seek()_ dort weiter machen?


----------



## Replica (16. Mai 2008)

Habs hinbekommen.  Danke!
*Haken*


----------



## Escorter (16. Mai 2008)

Schön!

Poste mal bitte den, Code evtl. kann ich ja meine Applikation noch verbessern


----------

