log4j
a java.util.logging
Pro 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.logging
java.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.