# Allgemeine Frage zu Java Logging (JLA, Log4J)



## mad-din (25. Jan 2008)

Hi Leute!

Ich hab eine allgemeine Verständnisfrage: und zwar will ich mich in die Java Logging Api einarbeiten (später danna auch in Log4j, aber das dürfte in etwa gleich sein). Dazu habe ich mir 3 Klassen geschrieben. Die erste Klasse "Startup" enthält eine main()-Methode. Diese main()-Methode instanziiert dann die zwei anderen Klassen. In der "Startup" Klasse wird zusätzlich ein Logger erzeugt, der die Ausgabe in eine Datei leiten soll. Das funktioniert soweit! Die anderen beiden Klassen haben dann ebenfalls einen Logger, in diesen wird aber nichts mehr definiert, sondern diese sollen die Einstellungen der main()-Methode übernehmen. Machen sie aber nicht.
Ich dachte mir, dass das so abläuft: Ich erstelle in der main()-Methode einen Logger und definiere, wie er die Ausgabe machen soll. Sämtliche davon abhängigen Klassen, die ebenfalls einen Logger erstellen, übernehmen dann diese Einstellungen. Muss ich jetzt in jeder Klasse den Logger, die Logdatei und die Ausgabeformatierung neu einstellen. Wo ist dann der Sinn des Logging-Frameworks? 

Kann mich da mal jemand aufklären?

Danke & viele Grüße
Martin


----------



## mad-din (25. Jan 2008)

Jaja,

wer lesen kann hat mehr vom Leben  Ich hab bei den ganzen Dokus und Tutorials einen wichtigen Teil immer irgendwie übersehen. Ich hab natürlich den Logger in der main-Klasse so erstellt:


```
Logger log = Logger.getLogger("de.package.KlassenName");
```

und in der Unterklasse dann so erstellt:


```
Logger log = Logger.getLogger("de.package.KlassenNameDerUnterKlasse");
```

Das sind natürlich zwei unterschiedliche Logger, dann kann es ja nicht funktionieren. Jetzt mach ich es so, dass der Logger immer den Namen des packages übergebe, dann funktionierts auch.

Viele Grüße,
Martin


----------



## maki (25. Jan 2008)

> ch dachte mir, dass das so abläuft: Ich erstelle in der main()-Methode einen Logger und definiere, wie er die Ausgabe machen soll. Sämtliche davon abhängigen Klassen, die ebenfalls einen Logger erstellen, übernehmen dann diese Einstellungen. Muss ich jetzt in jeder Klasse den Logger, die Logdatei und die Ausgabeformatierung neu einstellen. Wo ist dann der Sinn des Logging-Frameworks?


Verstehe dein Problem nicht ganz.

log4j.logger.meinpacket= debug;

Alle Logger die mit "meinpacket" anfangen, loggen debug.

log4j.logger.meinpacket.MeineOberklasse= warn;
log4j.logger.meinpacket.MeineUnterklasse= info;

meinpacket.MeineUnterklasse loggt info, meinpacket.MeineOberklasse loggt warn.




> Jetzt mach ich es so, dass der Logger immer den Namen des packages übergebe, dann funktionierts auch.


Mach das nicht, wäre imho der falsche Weg.


----------



## mad-din (25. Jan 2008)

Hi!

Aber genau das funktioniert bei mir und der Java Logging Api nicht. Nochmal, Es gibt folgende Klassen:

Klasse 1:


```
package de.resolution_m.test;

import java.util.logging.*;

public class LoggingMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {

		Logger log = Logger.getLogger("de.resolution_m.test.LoggingMain");
		Handler fileHandler = new FileHandler("E:/temp/log.txt");
		Formatter simpleFormatter = new SimpleFormatter();
		fileHandler.setFormatter(simpleFormatter);
		log.addHandler(fileHandler);
		
		log.warning("test");
		
		LoggingSubClass lsc = new LoggingSubClass();
		

	}

}
```

Und die dazugehörige Klasse 'LoggingSubClass':


```
package de.resolution_m.test;

import java.util.logging.*;

public class LoggingSubClass {

	public LoggingSubClass() {
		
		Logger log = Logger.getLogger("de.resolution_m.test.LoggingSubClass");
		log.warning("Test der LoggingSubClass");
		
	}
	
}
```


So, wenn ich jetzt LoggingMain starte, gibts in der log.txt nur einen Eintrag, auf der Konsole werden allerdings zwei Einträge angezeigt. Muss ich in der LoggingSubClass den FileHandler wieder neu setzen? Wenn ja, dann finde ich das Konzept nicht gut, weil ich eigentlich den Logger einmal definieren will und alle anderen - davon abhängigen Klassen - sollen diese Einstellung verwenden. Wenn ich allerdings in beiden Klassen bei Logger.getLogger nur das Paket eingebe, dann funktioniert es.

Viele Grüße,
Martin


----------



## maki (25. Jan 2008)

k.A. ehrlich gesagt, ich nutze nur log4j

Nachtrag: Finde es aber sehr ungewöhnlich, für jedes Objekt einen eigenen Logger zu erstellen, ein statischer für die Klasse sollte doch mehr als reichen?


----------



## brabenetz (26. Jan 2008)

Ich verwende apache commons logging.

```
import org.apache.commons.logging.*;
....
private static final Log LOG = LogFactory.getLog(???.class);
```

Ohne spezielle konfiguration passiert folgendes:


* Ist Log4J vorhanden (log4j.jar ), dann wird Log4J verwendet.
* Ansonsten wenn mindesten JDK 1.4 vorhanden ist, dann wird die Logging-Funktionalität von JDK 1.4 verwendet 
* Ansonsten ( < JDK 1.4 und kein Log4J) wird (glaub ich) System.out.println verwendet (aber wann hat man den Fall schon... ).
In *Eclipse* erstell ich dafür auch einen art shortcut:
Window --> Preferences --> Java --> Editor --> Templates 
*Key*: loggr
*Value*:

```
/** General Logger for this Class */ 
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog(${enclosing_type}.class);
```


----------

