log4j - eigene Info-Ausgaben

WIK-Lars

Erfahrenes Mitglied
Hallo,

mal seh’n, ob ich meine Frage in einigermaßen verständliche Worte gefasst bekomme.

Ich arbeite an einem Programm das die log4j-api nutzt. Ich habe bisher noch nicht damit Bekanntschaft gemacht, mir jedoch schon mal einen groben Überblick verschafft, worum es so geht. Nun dachte ich mir, ich kann das Logging auch für einfache Ausgaben nutzten, quasi zum Debuggen u.ä.

Der Programmierer vor mir, gibt durch wie folgt aufgebaute Anweisungen Fehlermeldungen aus:
log.fatal(this.getClass().getName()+".hierStehtDerAktuelleMethodenName() ", exceptionObjekt);

Nun habe ich für Info-Meldungen über die Konfigurationsdatei einen Pfad bzw. eine Datei angelegt, in die bei log.info(...) geschrieben werden soll. Diese existiert auch und wird z.B. bei...

Exception eineEx = new Exception();
StackTraceElement[] stacktraceelem = new StackTraceElement[1];
eineEx.setStackTrace(stacktraceelem);
log.info(this.getClass().getName()+".service()", eineEx);

... auch beschrieben.

Es steht dann als erster im Eintrag so was:

01.01.2005 12:33:35 -- FATAL - [localhost] - [ES] - de.package1.package2.servlets.ControllerServlet.service()
appender. So we set the additivity to false.java.lang.NullPointerException
at java.lang.Throwable.<init>(Throwable.java:59)
at java.lang.Throwable.setStackTrace(Throwable.java:188)
at de.package1.package2.servlets.ControllerServlet.service(ControllerServlet.java:181)
...

Meine bescheidene Frage ist: wie bekomme ich selbst geschriebenen einfachen Text – und sei es nur ein „Hello World“ – in meine Fehlerausgaben? Ich möchte da also Strings ausgeben können.

Vielen, vielen Dank für sachdienliche Hinweise,

Lars
 
Dann hat der Programmierer vor dir log4j völlig falsch benutzt.

Normalerweise benutzt man die Ausgaben mit info nur dazu um eigene Texte auszugeben. Den Namen der Klasse kann log4j selbsständig ins Log dazu schreiben. Ebenso den Namen der Methode (was jedoch nur sehr langsam ist und man daher nicht unbedingt nutzen sollte).

Ein kleines Beispiel:
Java:
package de.tutorials;

import java.io.File;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import de.unibremen.rr.hobbit.util.Constants;


/**
 * @author zeja
 */
public class Log4jTest {
  
  //Einen Logger für diese Klasse initialisieren
  private static final Logger logClass = Logger.getLogger(Log4jTest.class);
  
  public static void testLogging(){
    logClass.info("Hello this is a logging test");
  }
  
  public static void main(String [] args){
    //log4j mit xml Konfigurations Datei einrichten
    DOMConfigurator.configure(Constants.CONF_DIR + File.separator
        + "log4jTest.xml");
    
    logClass.info("Successfully configured log4j");
    
    testLogging();
  }
}

Und die log4jTest.xml
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

<!-- schreibt ausgaben (ab Level DEBUG) in die Console -->
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
	<layout class="org.apache.log4j.PatternLayout">
		<!-- [Datum Level Klassenname.Methodenname] message zeilenumbruch -->
		<param name="ConversionPattern" value="[%d %p %c.%M] %m %n"/>
	</layout>
</appender>

<!-- welche logger sollen benutzt werden. Der initiale Threshold ist debug -->
<root>
	<level value ="debug"/>
	<appender-ref ref="STDOUT"/>
</root>
</log4j:configuration>

Die Ausgabe ist dann:
Code:
[2006-11-01 12:45:41,328 INFO de.unibremen.rr.hobbit.test.Log4jTest.main] Successfully configured log4j 
[2006-11-01 12:45:41,343 INFO de.unibremen.rr.hobbit.test.Log4jTest.testLogging] Hello this is a logging test

Im ConversionPattern des Appenders kann man angeben welche Infos von log4j zusätzlich ausgegeben werden sollen. Welche Platzhalter dort eingesetzt werden können findet man im Javadoc von log4j zu PatternLayout

Eine allgemeine Einführung zu log4j findet man in deren log4j Short Introduction.
 
Hallo Zeja,

vielen Dank für Deine ausführliche Anleitung!

Das Projekt, welches ich vor mir habe, ist allerdings serverseitig programmiert. D.h. es gibt keine main()-class. Alles, was der Programmierer vor mir in dem (Haupt-)Servlet stehen hatte ist:


Code:
private static final Logger log = Logger.getLogger(ControllerServlet.class);
log.fatal(this.getClass().getName()+".service() ",ee);


Ich poste auch nochmal vollständig alle Einträge aus der log4jconfig.properties. Offensichtlich sind auch einige Einträge doppelt, aber das soll wohl nicht weiter stören:

Code:
log4j.rootLogger=debug, R
log4j.appender.R.layout=org.apache.log4j.SimpleLayout
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=c:\\logs\\projekt_log4j_generic.log
log4j.appender.R.MaxFileSize=25000KB
log4j.appender.R.MaxBackupIndex=5
 
log4j.logger.de.firma.projekt=error, R1
log4j.additivity.de.firma.projekt=false
log4j.appender.R1=org.apache.log4j.RollingFileAppender
log4j.appender.R1.File=c:\\logs\\projekt_log4j.log
log4j.appender.R1.MaxFileSize=25000KB
log4j.appender.R1.MaxBackupIndex=5
log4j.appender.R1.layout=org.apache.log4j.PatternLayout
log4j.appender.R1.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} -- %p -  -  - %m%nappender. So we set the additivity to false.
log4j.additivity.de.firma.projekt=false
log4j.appender.R1=org.apache.log4j.RollingFileAppender
log4j.appender.R1.File=c:\\logs\\projekt_log4j.log
log4j.appender.R1.MaxFileSize=25000KB
log4j.appender.R1.MaxBackupIndex=5
log4j.appender.R1.layout=org.apache.log4j.PatternLayout


Hast Du (oder sonst jemand ;-) ) eine Idee, was ich tun kann, um mit den vorhandenen Möglichkeiten, selbstgeschriebene Infos auszugeben?

Da es um serverseitige Programmierung geht, kann ich ja nicht auf die Konsole schreiben. Ich könnte natürlich mit dem PrintWriter (teilweise) Ausgaben im Browser machen. Aber das sieht dann wirklich ziemlich zermurkst aus und klappt auch nicht immer. Also dachte ich mir, das ich alles, was ich ausgeben möchte, in Log-Dateien packe.

Danke, danke für weitere Infos.
Gruss, Lars
 
In dem Manual steht dessen link ich gepostet habe steht auch wie man log4j bei Server-Anwendungen konfiguriert. Dafür braucht man keine main.

Bei dem Eintrag in der log4j.properties unten mit
log4j.appender.R1.layout.ConversionPattern
kannst du wie ich beschrieben habe auch ein anderes Pattern eintragen, was dann den Klassennamen etc ausgeben kann. Kopiere doch einfach das Pattern aus meinem Beispiel mal dahin und gucke was sich geändert hat.

Mehr als im Manual steht kann ich dir aber auch nicht sagen. Habe mein ganze Wissen auch nur daher also lies dir das bitte durch bevor du noch weitere Fragen stellst.
 
Zurück