[Java] Afhandeling van rolling files

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Bij de ontwikkeling van een dashboard applicatie voor het weergeven van de status van een systeem, is het nodig om bepaalde log-bestanden te monitoren zodat error boodschappen in het systeem (database) bewaard kunnen worden. Dit werkt vrij aardig.

Nu stel ik me de vraag wat het gedrag zal zijn op het moment dat een dergelijke logfile, bij het bereiken van zijn treshold, zal rollen. Momenteel gebeurd de implementatie aan de hand van een FileReader:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void readLogs() {
    String line;
    try {
        while ((line = reader.readLine()) != null) {
            try {
                saveLogLine(LogLine.fromString(line), reader);
            } catch (MalformedLogLineException e) {
                logger.warn("Couldn't parse the log line", e);
            }
        }
    } catch (IOException e) {
        logger.error("An exception occured while reading the log files", e);
    }
}

In unit tests lijkt dit onder Windows wel vrij goed te blijven functioneren na een roll; het kan enkel wel zijn dat er op het moment van de roll een aantal log lijnen verloren gaan (tussen de poll periode). Maar de nieuwe entries worden wel correct gelezen in de "nieuwe" file. Er zijn echter meerdere systemen waarop de applicatie zal komen te draaien, waaronder Solaris en AIX. Welke problemen mogen we daar precies verwachten?

Zal de referentie (handle) naar de file hetzelfde blijven bij een roll?
Op welke manier zouden we dit kunnen oplossen? Door een roll te detecteren en dan de readers opnieuw te initialiseren??

Graag uw input! :)

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 14:10
Hoe heb je die roll geïmplementeerd dan? Ik kan dat in m'n kristallen bol niet goed zien, en je vermeldt ook nergens of je misschien third party libraries gebruikt hiervoor. ;)

(In die readLogs() functie van je zie ik helemaal geen bestanden geopend of gesloten worden, en daar gaat het natuurlijk wel om.)

[ Voor 26% gewijzigd door Soultaker op 18-03-2009 12:10 ]


Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Topicstarter
Excuseer het gaat om standaard Log4J logging (dus de RollingFileAppender). Het gaat hier wel om een specifieke implementatie waarbij de logging eerst via het netwerk op een centrale server terecht komt, die op zijn beurt de logs gaat wegschrijven in files.

Voor het uitlezen van de logs wordt er dan gebruik gemaakt van een samba share; misschien heeft dit ook wel een impact op het detecteren van nieuwe (gerolde) bestanden?

Verder worden de FileReaders gewoon gecreëerd op het moment van creatie van de service, gewrapped in een BufferedReader. Er zijn dus ook verschillende readers (verschillende logs), met een eigen caching mechanisme om de laatst gelezen lijn te bepalen.

[ Voor 22% gewijzigd door -FoX- op 18-03-2009 12:43 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 14:10
Aha, ik snap nu ook je problem beter, denk ik: log4j schrijft events weg, die veroorzaken dat er een log turnover plaatsvind, en het proces dat de logfile geopend heeft krijgt de kans niet om de laatste paar messages uit te lezen voordat die gearchiveerd worden?

De netste oplossing is natuurlijk om je eigen WriterAppender te implementeren die events direct in de database logt (en eventueel ook nog naar een bestand). Dat is waarschijnlijk het efficienste en zo ben je ook altijd up-to-date.

Een andere oplossing lijkt me om de log-directory in de gaten te houden en elke keer dat een bestand gewijzigd wordt de inhoud verwerken (waarbij je bijvoorbeeld bijhoudt op welke offset de laatst verwerkte regel eindigde, om te zien waar je weer moet beginnen), daarbij moet je er wel voor oppassen dat logfiles ook weer geleegd kunnen worden. Verder moet je dan dus voorkomen dat events dubbel in de database komen, maar je mist dan in ieder geval geen data meer.