Dienstag, 20. Januar 2009

 

Logging mit Java

Folgendes Beispiel demonstriert verschiedene Logging-Mechanismen des in Java integrierten Loggers 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).

Labels: , ,


Kommentare:

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]