2011-11-03 11 views

risposta

10

Questo può essere eseguito in Logback, il successore di Log4J.

Il logback è inteso come un successore del popolare progetto log4j, che preleva da dove parte log4j.

vedere la documentazione per Sifting Appender

Il SiftingAppender è unico nella sua capacità di riferimento e configurare appenders nidificate. Nell'esempio precedente, all'interno di SiftingAppender ci saranno istanze di FileAppender nidificate, ciascuna istanza identificata dal valore associato alla chiave MDC "userid". Ogni volta che alla chiave MDC "userid" viene assegnato un nuovo valore, verrà creata una nuova istanza di FileAppender da zero. SiftingAppender tiene traccia delle appendici che crea. Gli allegati non utilizzati per 30 minuti verranno automaticamente chiusi e scartati.

Nell'esempio, generano un file di registro separato per ciascun utente in base a un valore MDC. Altri valori MDC potrebbero essere utilizzati a seconda delle esigenze.

+0

Ma utilizzare Logback significherebbe che tutte le istruzioni di registrazione devono essere modificate, giusto? ' –

+1

Vedere il bridging API legacy su http://slf4j.org/legacy.html – Ceki

9

Ciò è possibile anche con log4j. Puoi farlo implementando il tuo appender. Immagino che il modo più semplice sia la sottoclasse sottoclasse AppenderSkeleton.

Tutti gli eventi di registrazione terminano con il metodo append(LoggingEvent event) da implementare.

In questo metodo è possibile accedere al MDC da event.getMDC("nameOfTheKeyToLookFor");

Allora si potrebbe utilizzare queste informazioni per aprire il file di scrivere. Potrebbe essere utile dare un'occhiata all'implementazione degli appendici standard come RollingFileAppender per capire il resto.

Ho utilizzato questo approccio personalmente in un'applicazione per separare i registri di diversi thread in diversi file di registro e ha funzionato molto bene.

+0

Non sto utilizzando RollingFileAppender. È possibile in FileAppender? –

+0

Ho menzionato RollingfileAppender solo come esempio di come implementare un appender.Fondamentalmente puoi fare tutto ciò che vuoi nel metodo append. – Wolfgang

5

Ho faticato un po 'a trovare la funzionalità di SiftingAppender in log4j (non potevamo passare al logback a causa di alcune dipendenze), e ho finito con una soluzione programmatica che funziona piuttosto bene, usando un MDC e logger in coda runtime:

// this can be any thread-specific string 
String processID = request.getProcessID(); 

Logger logger = Logger.getRootLogger(); 

// append a new file logger if no logger exists for this tag 
if(logger.getAppender(processID) == null){ 

    try{ 
    String pattern = "%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n"; 
    String logfile = "log/"+processID+".log"; 

    FileAppender fileAppender = new FileAppender(
     new PatternLayout(pattern), logfile, true); 
    fileAppender.setName(processID); 

    // add a filter so we can ignore any logs from other threads 
    fileAppender.addFilter(new ProcessIDFilter(processID)); 

    logger.addAppender(fileAppender); 
    }catch(Exception e){ 
    throw new RuntimeException(e); 
    } 
} 

// tag all child threads with this process-id so we can separate out log output 
MDC.put("process-id", processID); 

//whatever you want to do in the thread 
LOG.info("This message will only end up in "+processID+".log!"); 

MDC.remove("process-id"); 

Il filtro aggiunto sopra solo verifica la presenza di uno specifico ID processo:

public class RunIdFilter extends Filter { 

    private final String runId; 

    public RunIdFilter(String runId) { 
    this.runId = runId; 
    } 

    @Override 
    public int decide(LoggingEvent event) { 
    Object mdc = event.getMDC("run-id"); 

    if (runId.equals(mdc)) { 
     return Filter.ACCEPT; 
    } 

    return Filter.DENY; 
    } 
} 

Spero che questo aiuti un po '.

+0

Come si scrive lo stesso filtro in Log4j 2? –

+0

dove aggiungere il codice nel primo blocco? – NaiveCoder

+0

@NaiveCoder ovunque si voglia avviare il filtro MDC. – bpodgursky