Forzare logger / appender sulla linea di uscita registrata al di sotto del livello corrente?

2

Considera il seguente scenario:

Sto scrivendo un servlet Dispatcher che delega l'elaborazione a vari gestori in base all'URL della richiesta; gli oggetti del gestore si sono precedentemente registrati per i pattern URL, proprio come Servlet si registrano in web.xml.

Quando un gestore registra o annulla la registrazione di un pattern, voglio registrare una riga che include l'azione e il pattern; e anche i mapping correnti, in modo che quando un'elaborazione di richiesta successiva registra un avviso che una richiesta non è stata elaborata, posso tornare nei log e trovare i mapping.

La domanda è come assicurarsi che le righe registrate da registerUrlPattern / unregisterUrlPattern appaiano effettivamente nel file di registro:

  • Mi sembra che questi metodi debbano registrare le modifiche di mappatura al livello INFO, dal momento che vengono registrati ulteriori INFO. Ma il livello del logger è WARN, quindi non funzionerà. Il logger riceve molti altri messaggi al livello INFO, quindi non è possibile cambiarne il livello in INFO in produzione, tranne che per la risoluzione dei problemi.

  • Potrei registrarlo a livello WARN, ma qa / usability / customer non apprezza che tali avvisi appaiano.

Posso pensare alle seguenti alternative:

  • Modifica il livello del logger su INFO quando accedi a queste linee, eventualmente aggiungendo un metodo forceInfo nel mio Logger (che include un logger di tipo log4j standard)

  • Utilizza un Logger diverso per questi metodi e imposta il suo livello su INFO

  • Accedi al livello di avviso ma cambia la lingua per indicare che non è qualcosa di cui preoccuparsi

posta Miserable Variable 11.07.2013 - 01:21
fonte

3 risposte

7

Quindi, hai bisogno di una soglia diversa all'interno della stessa classe. Penso che tu usi un logger diverso corrispondente a un nome specifico. È quindi possibile impostare il livello di registro su INFO per questo Logger specifico nella classe DispatchServlet.

Per me, i benefici sarebbero:

  • la possibilità di ridurre in modo specifico la soglia a INFO come richiesto (l'obiettivo).
  • se un giorno ti rendi conto che i tuoi registri specifici diventano troppo prolissi e finalmente inutili perché la funzionalità è stabile al 100% e non causa alcun problema, puoi comunque ridurre la soglia per configurazione e senza influire sul resto dei registri. L'accesso al livello di AVVERTENZA o un'operazione basata su forcedLog implicherebbe che tu modifichi i sorgenti per tale scopo.

L'unico CON che vedo è che potrebbe essere "sorprendente" ma una corretta documentazione risolve tutto.

Ad esempio nel file log4j.xml, potresti avere:

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <!-- general application log -->
    <appender name="MyLogFileAppender" class="org.apache.log4j.FileAppender">
        <param name="File" value="mylog.log" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy MM dd - HH:mm:ss,SSS} %-5p %t [%-40.40c] %x - %m%n"/>
        </layout>
    </appender>
    <logger name="DispatchServletSpecific">
        <level value="INFO" />
        <appender-ref ref="MyLogFileAppender" />
    </logger>
    <root>
         <level value="WARNING" />
         <appender-ref ref="MyLogFileAppender" />
    </root>
</log4j:configuration>

E nel codice Java crei un Logger specifico

Logger specificLogger = Logger.getLogger("DispatchServletSpecific");

In questo modo la soglia di log dovrebbe essere impostata su INFO mentre il resto della tua app deve essere solo di registro. Spero che ti aiuti.

    
risposta data 11.07.2013 - 13:14
fonte
2

Change the Logger's level to INFO when logging these lines, possibly by adding a forceInfo method in my Logger (which wraps a standard log4j type logger)

A un certo punto lungo la linea probabilmente considererai il comportamento di registro / annullamento della registrazione abbastanza affidabile da non voler più effettuare il log, e vuoi solo vedere gli avvisi "corretti". A questo punto non avrai altra scelta che andare e cambiare il codice.

Use a different Logger for these methods and set its level to INFO

Sì, fallo. Ti dà il controllo a grana fine di cui hai bisogno in questo scenario.

Log at warning level but change the language to indicate that it is not something to be worried about

Non farlo. I tuoi utenti / QA non lo vogliono, e l'evento non è un avvertimento, quindi non farlo. Inoltre, devi nuovamente modificare il codice per disabilitare la registrazione di questi eventi.

    
risposta data 12.07.2013 - 12:45
fonte
0

Invece di provare a forzare un messaggio contenente i dati che desideri siano disponibili quando viene registrato un altro messaggio, dovresti utilizzare la funzionalità di discussione del thread di Log4J per aggiungere i dati all'altro messaggio. In questo modo, se il messaggio di errore viene emesso, porta con sé i dati che vuoi registrare. Quindi, ad esempio, anziché:

logger.ForceInfoOutputEvenThoughBelowLoggingLevel("Hey, I'm going to be processing record " + recordNumber + ", so if an error happens, you'll know what I'm doing!");
...
logger.Error("OMG!")

che presumibilmente registra:

INFO Hey, I'm going to be processing record 42, so if an error happens, you'll know what I'm doing!
ERROR OMG!

lo faresti invece:

ThreadContext.put("recordNumber", recordNumber);
...
logger.Error("OMG!")

che, con %x o %X nella definizione di layout della tua configurazione di Log4J, registra:

ERROR recordNumber=42 OMG!

Il punto è di aumentare il messaggio di errore con dati utili, piuttosto che forzare un altro messaggio nel registro. Questo ha molti vantaggi, incluso il fatto che puoi aumentare qualsiasi messaggio emesso da qualsiasi codice, senza dover modificare quel codice, anche se non hai la sua fonte .

    
risposta data 12.07.2013 - 12:07
fonte

Leggi altre domande sui tag