2013-04-08 13 views
8

Ich arbeite derzeit an einem Programm, in dem ich alle Ausgaben in eine Protokolldatei schreiben muss.Logging mit mehreren Parametern

Ich muss eine Protokollmethode schreiben, die eine Ausgabe mit einer Ebene, einer Nachricht, einem Objektwert, einer anderen Nachricht, einem ganzzahligen Wert, einer anderen Nachricht und einem anderen ganzzahligen Wert in der angegebenen Reihenfolge geben soll . Ich kann keine Log-Methode finden, die das tut. Ich benutze Java.util.logging. Ist das möglich?

+0

Betrachten Log4J http://logging.apache.org/log4j/2.x/ – Mirco

+1

@ verbose-mode Warum? java util logging macht alles was benötigt wird und ist einfacher zu benutzen. Soweit ich es sehe, bricht Ihr Vorschlag das Prinzip KISS (Keep it Simple S ...). – Martin

Antwort

13

Ich nehme an, Sie brauchen das Protokollformat in dem unten stehenden Format FINE, Message1, object.GetValue(), Message2,1, Message3,2

Sie benötigen ein Ausgangsnachrichtenformat

logger.log(Level.INFO, "{0},{1},{2},{3},{4},{5}",new Object[]{Message1,object.getValue(),Message2,1,Message3,2}); 
erstellen

Jetzt müssen Sie einen benutzerdefinierten Formatierer erstellen, die von Formatter-Klasse erweitern

public class DataFormatter extends Formatter { 

@Override 
public synchronized String format(LogRecord record) { 
    String formattedMessage = formatMessage(record); 
    String throwable = ""; 
    String outputFormat = "%1$s, %2$s \n %3$s"; //Also adding for logging exceptions 
    if (record.getThrown() != null) { 
     StringWriter sw = new StringWriter(); 
     PrintWriter pw = new PrintWriter(sw); 
     pw.println(); 
     record.getThrown().printStackTrace(pw); 
     pw.close(); 
     throwable = sw.toString(); 
    } 
    return String.format(outputFormat,record.getLevel().getName(),formattedMessage,throwable); 
} 
} 

nun die neu erstellten Formatierungsprogramm eingestellt

for(int i=0;i<logger.getHandlers().length;i++) 
     logger.getHandlers()[i].setFormatter(new DataFormatter()); 
9

Es ist ein ziemlich altes Thema, jedenfalls, meine zwei Cent, weil ich auch java.util.logging.Logger in meinen Projekten bevorzugen würde, wo ausreichend.

Lambdas machen diese Formatiererweiterung für mehrere benutzerdefinierte Parameter mehr oder weniger überflüssig, es sei denn, Sie profitieren von ihrer anwendungsweiten Wiederverwendung. In (meinen) einfachen Szenarien werden Protokollnachrichten auf den Codeabschnitt zugeschnitten, in den sie eingefügt werden. Daher ist String.format() normalerweise viel einfacher und flexibler.

Vor Java 8 und lambdas war die Formatter die einzige Möglichkeit, die Nachrichtenkonstruktion zu verschieben. Die einzige Alternative war, die Nachricht zu erstellen, um im Voraus zu loggen, bevor die loggable Prüfung basierend auf dem Level stattfand.
Mit Java 8 lambdas kann die String-Formatierung nach der loggable Prüfung verschoben werden, aber immer noch mit Zugriff auf den ursprünglichen Methodenkontext. Der einzige kleine Nachteil ist, dass alle Felder, auf die zugegriffen wird, aufgrund der Lambda-Einschränkungen endgültig sein müssen.

hier ein ziemlich einfaches Snippet:

final String val1 = "lambda expression log message"; 
final Level level = Level.INFO; 
Logger.getGlobal().log(level,() -> 
     String.format("Hello, I'm a %s, evaluated after %s loggable check.", val1, level) 
); 
Logger.getGlobal().log(level, new RuntimeException(),() -> 
     String.format("Hello, I'm a %s with a stack trace, evaluated after %s loggable check.", val1, level) 
); 

hoffe, das hilft einige von euch, die auch die Einbau-Protokollierung verwenden möchten :-)

Prost Ben