2010-11-22 3 views
0

Anforderung zum schrittweisen Lesen und Verarbeiten der Protokolldatei. Irgendwelche Vorschläge/Ideen, um dies in Java zu tun?Inkrementelles Lesen von Protokolldateien in Java

Notwendigkeit, alle möglichen Szenarien wie Dateiüberschlags, verschiedene Protokollierungsformate zu prüfen usw.

Danke, Sudhanshu

+0

"Protokolldatei inkrementell lesen und verarbeiten." - Bitte fügen Sie weitere Details hinzu. – darioo

+0

Nehmen wir an, es gibt eine Anwendung, die Protokolle erzeugt (in Dateien), dann möchte ich einen Code (in Java) schreiben, der diese neuesten Protokolle lesen würde, wenn sie generiert werden und sie entsprechend der Anforderung verarbeiten. Das erste Lesen von Logs ist kein Problem, aber wie verfolgen wir den letzten Datensatz/Zeilenlesevorgang? Was passiert auch, wenn die Datei aufgrund der Größe oder eines anderen konfigurierten Parameters gerollt wird? –

+0

Als ich dieses Problem hatte, fand ich die Antwort hier: http://www.informit.com/guides/content.aspx?g=java&seqNum=226 – Dan

Antwort

2

Obwohl es ziemlich spät ist, aber nur daran gedacht, den Ansatz zu schreiben, den ich verwendet habe, um diese Funktionalität zu erreichen.

Nehmen wir an, wir beginnen einen Job, um eine Datei regelmäßig zu lesen, alle 5 Minuten.

  1. Während ersten Lauf, lesen Sie die gesamte Datei
  2. Shop Zeilenzahl und der Zeitpunkt der letzten Änderung der Datei

Es ist interessant wird für nachfolgende Auftrag ausgeführt wird.

  1. Überprüfen Sie beim nächsten Joblauf, ob die Datei geändert wurde (mit der Datei der letzten Änderung und der Datei, die während der vorherigen Jobausführung gespeichert wurde). Wenn die Datei nicht geändert wird, nichts tun.
  2. Wenn die Datei geändert wird, müssen wir nur die neuen Zeilen lesen. Wir haben die Zeilenanzahl aus dem früheren Job, also verwenden Sie sie, um die Anzahl der zu überspringenden Zeilen zu bestimmen.

So weit so gut, was ist, wenn die Datei gerollt wird?

  1. Angenommen wir das Muster für die Dateibenennung haben, wenn die Datei über gerollt ...
  2. alle Dateien Holen Sie sich das Pattern-Matching und sie in aufsteigender Reihenfolge sortieren basierend auf Datei zuletzt geändert Zeit
  3. Iterate durch die Dateien und beginnen Sie mit demjenigen, dessen letzte geänderte Zeit größer ist als die Zeit, die vom vorherigen Joblauf gespeichert wurde.Verwenden Sie Linie intelligent gespeichert zählen die bereits gelesenen Zeilen
  4. Reset-Leitung Zahl zu überspringen, wenn Sie mit einer neuen Datei danach

starten Das ist es!

Möglicherweise müssen Sie für einige ungewöhnliche Szenarien IF-Bedingungen an einigen Stellen setzen. Ein solches Szenario ist, wenn Sie durch die Dateien iterieren und wenn die Zeit der letzten Änderung der Datei genau der gespeicherten Datei entspricht, setzen Sie einfach die Zeilenanzahl zurück - so dass sie mit der ersten Zeile der nächsten/neuen Datei beginnt.

Beispielcode für die nachfolgenden Auftrag ausgeführt:

für (Datei: Dateien) {
if (file.lastModified()> storedLastModifiedTime) {
// Sie haben die Datei zu verarbeiten, kümmern die Zeilenzahl
} else if (file.lastModified() == storedLastModifiedTime) {
// Reset gespeichert Zeilenzahl
}
}

Irgendwelche Vorschläge/Kommentare/Fragen?

3

Sie einen Blick darauf werfen können Chainsaw

+0

+1: Ihr erster Absatz ist nicht sehr relevant; In dieser Frage geht es darum, die Protokolle zu lesen, nicht zu schreiben. Kettensäge sieht jedoch völlig passend aus. –

+0

Ich denke Chainsaw ist nur für log4j, was ist mit anderen Logging APIs? –

+0

Ich kenne keine anderen Sorry (zumindest nicht frei Open Source) –

0

Ich versuche, ziemlich zu nähern viel das gleiche Problem. Es scheint, dass es nicht so trivial ist, wie es auf den ersten Blick aussehen könnte. Sie müssen den Begriff EOF/EOS ignorieren und Sie müssen verfolgen, wo in der Protokolldatei Sie sich befinden.

Ich denke, der beste Ansatz ist es, einen separaten Thread zum Lesen der Protokolldatei zu haben. Ich habe einen Test mit BufferedReader gemacht, der ziemlich vielversprechend ist. Der Thread liest alle Daten bis zum Ende der Datei (wobei readLine()null zurückgibt) und geht für N Sekunden in den Ruhezustand (5 in meinem Fall). Dann nach dem Aufwachen versucht es erneut eine Zeile zu lesen. Wenn es String zurückgibt, geht es mit der Verarbeitung weiter. Wenn es null wird, geht es wieder schlafen. Er erhöht den Zeilenzähler bei jedem erfolgreichen Lesen und schreibt/liest ihn bei Stopp/Start, so dass er die letzte Position in der Protokolldatei finden und von diesem Punkt aus fortfahren kann.

Das einzige Problem bei diesem Ansatz ist die Wartezeit von N Sekunden. Es wäre viel genauer, eine Möglichkeit zu haben, Java zu sagen "block on readLine() unabhängig von EOF/EOS". Mit der Wartezeit von N Sekunden schlafen Sie möglicherweise, während Daten bereits verfügbar sind. Der Schlaf scheint jedoch notwendig zu sein, es sei denn, Sie wollen die gesamte CPU-Leistung auffressen.

+0

Ich dachte, der Fragesteller wäre nach dem vorhandenen Code/lib dafür, nicht von Grund auf neu schreiben. –

+0

Nach dem Aufwachen und einem fehlgeschlagenen Versuch, eine andere Zeile zu lesen, sollten Sie auch prüfen, ob die Logs übergelaufen sind. – hidralisk

+0

Das Handling von Holzstämmen ist eine Herausforderung. Wie ermitteln wir die Anzahl der Protokolldateien, die generiert wurden, als der Thread inaktiv war? –