log4j a java.util.loggingPro logování v Javě se již dlouho používá především log4j, dříve součást projektu Jakarta Commons. Postupem času se z log4j stal de facto standard.
Ovšem pravým standardem se později stalo až API z balíčku
java.util.logging v JRE (tuším) 1.4.
log4j je komplexnější a dá se podrobněji konfigurovat pomocí konf. souboru (standardně log4j.properties někde v classpath).
Zde je ukázka konfiguračního souboru pro log4j:
log4j.rootLogger=WARN, stdout, file log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %-5r %-5p [%c] (%t:%x) %m%n log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=WS_klient.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d %-5r %-5p [%c] (%t:%x) %m%n
Z hlediska Java kódu je logování s log4j podobné jako s
java.util.logging – ukázu tedy viz níže.
java.util.loggingjava.util.logging je zobecnění log4j, je tedy
méně komplexní a v konf. souboru lze nastavit jen dost omezeně. Pokud chce
širší možnosti (např. Memory Handler), musíte je (v aktuální verzi)
nastavit programově.
Osobně toto API používám víceméně proto, že má v API 6 úrovní
logování – SEVERE, WARN, INFO,
FINE, FINER, FINEST. Dost mi totiž na
log4j vadilo, že má jen jeden DEBUG, ale i debug informací chci
vidět různě – někdy jen základní hlášky o průběhu, jindy celé
výpisy obsahů objektů.
Ukázka konfiguračního souboru pro java.util.logging:
# Handlers handlers = java.util.logging.ConsoleHandler java.util.logging.FileHandler # Console java.util.logging.ConsoleHandler.formatter = cz.dynawest.logging.SimplestFormatter java.util.logging.ConsoleHandler.level = ALL # File java.util.logging.FileHandler.level = ALL java.util.logging.FileHandler.pattern = WS_klient.log java.util.logging.FileHandler.formatter = cz.dynawest.logging.SingleLineFormatter java.util.logging.FileHandler.limit = 0 java.util.logging.FileHandler.append = true # Default global logging level. .formatter = cz.dynawest.logging.SimplestFormatter .level = INFO
Standardně bere java.util.logging nastavení odkudsi z
$JAVA_HOME/lib/logging.properties, což je programátorovi
samozřejmě k ničemu. Nastavit vlastní konfigurační soubor lze dvěma
způsoby:
java.util.logging.config.file:java -Djava.util.logging.config.file=logging.properties
LogManager.getLogManager().readConfiguration(new FileInputStream("logging.properties"));
V obou případech se pak čte z logging.properties na
classpath, tj. např. z vašeho JAR souboru.
Pro zjednodušení používám zhruba takovýto kód, který respektuje onu
proměnnou, ale defaultně bere logging.properties. Uznávám,
v log4j takovéto opičárny dělat nemusíte.
public class LoggingUtils
{
private static final Logger log = Logger.getLogger( LoggingUtils.class.getName() );
/** Sets up logging. Uses "#/logging.properties" as default path. */
public static void initLogging() {
initLogging("#/logging.properties");
}
/** Sets up logging. */
public static void initLogging( String filePath ) {
String logConfigFile = System.getProperty("java.util.logging.config.file", filePath);
try {
InputStream is;
if( logConfigFile.startsWith("#") )
is = Game.class.getResourceAsStream( logConfigFile.substring(1) );
// "Use getClass().getClassLoader().findResource("path") instead."
else
is = new FileInputStream(logConfigFile);
log.info("Načítám konfiguraci logování ze souboru: "+logConfigFile+" (nastaveno v systémové proměnné java.util.logging.config.file)");
LogManager.getLogManager().readConfiguration( is );
}catch(IOException ex){
System.err.println("Chyba při načítání nastavení logování ze souboru ["+logConfigFile+"]. Bude použito výchozí.");
}
}
}
Samotné logování potom provedete takto:
class LoggingTest {
// Získáte logger s nějakým jménem - obvykle se jménem aktuální třídy.
// Uložíte si ho do privátní statické proměnné - logování je thread-safe.
private static Logger log = Logger.getLogger("cz.dynawest.test.log.LoggingTest");
// Někdy se můžete vidět:
//private Logger log = Logger.getLogger(LoggingTest.class.getName());
// To se používá kvůli budoucímu refaktoringu; někdy je to i kratší na zápis.
// V metodách už potom jednoduše logujete:
public void testLogging(){
log.info("Testujeme logování.");
}
}
Dokumentaci k java.util.logging najdete standardně v JavaDocu a
v dokumentu Java
Logging Overview.