slf4j: come registrare messaggi formattati, array di oggetti, eccezioni


275

Qual è l'approccio corretto per registrare sia un messaggio popolato sia una traccia dello stack dell'eccezione?

logger.error(
    "\ncontext info one two three: {} {} {}\n",
    new Object[] {"1", "2", "3"},
    new Exception("something went wrong"));

Vorrei produrre un output simile a questo:

context info one two three: 1 2 3
java.lang.Exception: something went wrong
stacktrace 0
stacktrace 1
stacktrace ...

slf4j versione 1.6.1


3
Non capisco perché slf4j usi la propria sintassi della stringa di formato anziché lo stile% s standard. Fastidioso.
Keith Tyler,

@KeithTyler Mi piace di {}più, la questione del gusto ...
Betlista,

@KeithTyler Il toString()metodo degli argomenti potrebbe essere costoso. Con questa sintassi, viene passato solo un riferimento a ciascun oggetto e il toString()metodo viene chiamato solo se il particolare messaggio viene effettivamente registrato. Gli oggetti a cui fa riferimento una info()chiamata di registro non avranno il loro toString()metodo chiamato se il livello di registro è WARNo superiore. La {}sintassi ricorda agli utenti che questa non è un'operazione String.format()analoga, ovvero che devono passare oggetti anziché rappresentazioni di stringhe.
user149408,

Risposte:


427

A partire da SLF4J 1.6.0, in presenza di più parametri e se l'ultimo argomento in un'istruzione di registrazione è un'eccezione, SLF4J presumerà che l'utente desideri che l'ultimo argomento sia trattato come un'eccezione e non come un semplice parametro. Vedi anche la voce FAQ pertinente .

Quindi, scrivendo (in SLF4J versione 1.7.xe successive)

 logger.error("one two three: {} {} {}", "a", "b", 
              "c", new Exception("something went wrong"));

o scrivendo (in SLF4J versione 1.6.x)

 logger.error("one two three: {} {} {}", new Object[] {"a", "b", 
              "c", new Exception("something went wrong")});

cederà

one two three: a b c
java.lang.Exception: something went wrong
    at Example.main(Example.java:13)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at ...

L'output esatto dipenderà dal framework sottostante (es. Logback, log4j, ecc.) E dalla configurazione del framework sottostante. Tuttavia, se l'ultimo parametro è un'eccezione, verrà interpretato come tale indipendentemente dal framework sottostante.


4
Quale framework di registrazione sottostante stai usando? Come menzionato nella mia risposta precedente, se l'ultimo parametro è un'eccezione, verrà interpretato come tale indipendentemente dal framework sottostante. (Testato con logback, slf4j-log4j12, slf4j-jdk14 e slf4j-simple.)
Ceki,

3
Spiacenti, non ho riconosciuto che nel tuo esempio hai usato n = 3 segnaposto nella stringa di formato e n + 1 = 4 elementi nella matrice di oggetti. Avevo n segnaposto nella stringa di formato e anche n elementi nell'array di oggetti più un'eccezione come terzo parametro. La mia aspettativa era che l'eccezione sarebbe stata stampata con stacktrace ma questo non è mai accaduto. Funziona come progettato? Inoltre, se ho n segnaposto e n elementi nella matrice di oggetti con un'eccezione come ultimo elemento, non vedo alcuna traccia stack. Forse gli n segnaposto con n + 1 oggetti in un array dovrebbero essere un po 'più enfatizzati.
Rowe,

7
Stavo per dare a @Ceki un momento difficile non essere nei Javadocs ma è in cima alla Loggerclasse javadoc: slf4j.org/apidocs/org/slf4j/Logger.html
Adam Gent

1
Ho creato una richiesta di miglioramento , puoi votarla se ti piace.
Betlista,

8

Oltre alla risposta di @Ceki, se si utilizza il logback e si imposta un file di configurazione nel progetto (in genere logback.xml), è possibile definire il log per tracciare anche la traccia dello stack usando

<encoder>
    <pattern>%date |%-5level| [%thread] [%file:%line] - %msg%n%ex{full}</pattern> 
</encoder>

% ex in pattern è ciò che fa la differenza

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.