Dienstag, 20. Januar 2009
Logging mit Java
Folgendes Beispiel demonstriert verschiedene Logging-Mechanismen des in Java integrierten Loggers
Diese Datei sieht etwa so aus:
Will man eine andere Konfiguration verwenden, so kann sie beim Java-Aufruf angegeben werden:
Es folgt das Beispiel, bei dem in einer Klasse in einer Methode
Normalerweise verwendet man einen Logger für ein Programm. Das enstpricht
Durch einen Filter kann zur Laufzeit bestimmt werden, was geloggt wird (in Abhängigkeit des Levels).
java.util.logging.Logger
. Die Einstellungen des Loggers werden in logging.properties
(liegt normalerweise im lib
-Verzeichnis der JRE, also z.B. /usr/lib/jvm/java-1.6.0.u11/jre/lib/logging.properties
).Diese Datei sieht etwa so aus:
############################################################
# Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property.
# For example java -Djava.util.logging.config.file=myfile
############################################################
############################################################
# Global properties
############################################################
# "handlers" specifies a comma separated list of log Handler
# classes. These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler
# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers. For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################
# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
com.xyz.foo.level = SEVERE
Will man eine andere Konfiguration verwenden, so kann sie beim Java-Aufruf angegeben werden:
java -Djava.util.logging.config.file=/pfad/zur/datei/logging.properties StartKlasse
Es folgt das Beispiel, bei dem in einer Klasse in einer Methode
div()
verschiedene Log-Aufrufe gezeigt werden. Die Konfiguration des Loggers erfolgt über den Konstruktor.Normalerweise verwendet man einen Logger für ein Programm. Das enstpricht
private Logger jlog = Logger.getLogger("at.haberstroh");
, wobei man den Logger gleich static
macht, da getLogger()
ohnedies das selbe Objekt liefert.
/**
* java-logging/log.LogDemo.java
* @author (c) 2009, Harald R. Haberstroh
* 20.01.2009
*/
package log;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* Demonstration von Logging.
*
* @author Harald R. Haberstroh (hh)
*
*/
public class LogDemo {
/*
* ein Logger für alle Instanzen - in der Logdatei sollten ALLE div()-Aufrufe
* sein
*/
// private Logger jlog = Logger.getLogger("at.haberstroh");
/*
* einLogger pro Instanz - in der Logdatei sollten nur die beiden
* div()-Aufrufe sein
*/
private Logger jlog = Logger.getAnonymousLogger();
/**
* Objekt mit Default-Logger
*/
public LogDemo() {
jlog.info("erzeuge LogDemo-Objekt");
}
/**
* @param filter
* Log-Filter
*/
public LogDemo(Filter filter) {
this("log.txt");
jlog.setLevel(Level.ALL);
jlog.setFilter(filter);
jlog.info("erzeuge LogDemo-Objekt");
}
/**
* @param level
* Level, der angezeigt wird
*/
public LogDemo(Level level) {
jlog.setLevel(level);
jlog.info("erzeuge LogDemo-Objekt");
}
/**
* Log in Datei, *.txt -> lesbar, sonst XML.
*
* @param filename
* Name der Log-Datei
*/
public LogDemo(String filename) {
try {
if (filename.endsWith("txt")) { // lesbarer Text in datei
Handler handler = new FileHandler(filename);
handler.setFormatter(new SimpleFormatter());
jlog.addHandler(handler);
} else { // sonst XML (default)
jlog.addHandler(new FileHandler(filename));
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
jlog.info("erzeuge LogDemo-Objekt");
}
/**
* unsere Demo-Methode, dividier a durch b.
*
* @param a
* @param b
* @return a/b
*/
public double div(int a, int b) {
jlog.fine("super, bin in div");
jlog.entering("LogDemo", "div"); // verschiedene Log-DingsDas
jlog.info("entering div");
if (b == 0) {
jlog.log(Level.SEVERE, "Division durch 0 ");
}
double result = 0.0;
result = (double)a / b;
jlog.exiting("LogDemo", "div", result);
return result;
}
/**
* @param args
*/
public static void main(String[] args) {
LogDemo demo;
double r;
System.out.println("*** LogDemo() ***");
demo = new LogDemo();
r = demo.div(5, 2);
System.out.printf("Ergebnis: %f\n", r);
r = demo.div(2, 0);
System.out.printf("Ergebnis: %f\n", r);
// Logdatei log.xml
System.out.println("*** LogDemo(\"log.xml\") ***");
demo = new LogDemo("log.xml");
r = demo.div(5, 2);
System.out.printf("Ergebnis: %f\n", r);
r = demo.div(2, 0);
System.out.printf("Ergebnis: %f\n", r);
// Logdatei log.txt
System.out.println("*** LogDemo(\"log.txt\") ***");
demo = new LogDemo("log.txt");
r = demo.div(5, 2);
System.out.printf("Ergebnis: %f\n", r);
r = demo.div(2, 0);
System.out.printf("Ergebnis: %f\n", r);
System.out.println("*** LogDemo(Level.OFF) ***");
// logging off siehe entsprechenden Konstruktor:
demo = new LogDemo(Level.OFF);
r = demo.div(5, 2);
System.out.printf("Ergebnis: %f\n", r);
r = demo.div(2, 0);
System.out.printf("Ergebnis: %f\n", r);
System.out.println("*** LogDemo(Level.ALL) ***");
demo = new LogDemo(Level.ALL); // logging alles
r = demo.div(5, 2);
System.out.printf("Ergebnis: %f\n", r);
r = demo.div(2, 0);
System.out.printf("Ergebnis: %f\n", r);
System.out.println("*** LogDemo(new Filter() ...) ***");
demo = new LogDemo(new Filter() {
@Override
public boolean isLoggable(LogRecord record) {
String msg = record.getMessage();
boolean log = msg.toLowerCase().contains("return");
// System.out.println(".isLoggable(" + msg + ") " + log);
if (log) {
return true;
} else {
return false;
}
}
});
r = demo.div(5, 2);
System.out.printf("Ergebnis: %f\n", r);
r = demo.div(2, 0);
System.out.printf("Ergebnis: %f\n", r);
}
}
Durch einen Filter kann zur Laufzeit bestimmt werden, was geloggt wird (in Abhängigkeit des Levels).
Abonnieren Posts [Atom]
Kommentar veröffentlichen