log4j: WriterAppender

Status
Nicht offen für weitere Antworten.

byte

Top Contributor
Hallo,

ich nutze log4j zum Logging in meiner Anwendung und gebe es in einer Konsole in der GUI meiner Anwendung aus. Das habe ich bisher so gemacht, dass ich als Appender einen ConsoleAppender verwende. Dazu habe ich einen neuen PrintStream geschrieben, der die Daten in meine GUI schreibt und diesen habe ich als neuen System.out gesetzt. Das funktioniert auch soweit ganz gut.

Jetzt möchte ich aber nicht mehr den Umweg über den System.out gehen. Daher dachte ich mir, ich nutze als Appender den WriterAppender:


XML-Config:
Code:
  <appender name="Console2" class="org.apache.log4j.WriterAppender">
     <param name="Writer" value="de.tubs.jlsc.util.Loggers.out"/>
     <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%d{HH:mm:ss}] Executing :  %m%n"/>
     </layout>
  </appender>

Java Code:
Code:
package de.tubs.jlsc.util;

public interface Loggers {
	
        ...
	
	PrintStream outExecution = new PrintStream(new OutputStream() {
		public void write(final int b) {
                        //hier schreibe ich in die GUI (der Code ist korrekt):
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					Application.getInstance().getExecutionConsole().append(String.valueOf((char) b));
				}
			});
		}
	});
	
	Writer out = new OutputStreamWriter(outExecution);
}

Ich kriege aber jedes mal eine Fehlermeldung:

log4j:WARN Failed to set property [writer] to value "de.tubs.jlsc.util.Loggers.out".

Im Internet findet man irgendwie so gut wie keine Informationen über den log4j WriterAppender. Und ich kann beim besten Willen nicht nachvollziehen, warum das nicht funktioniert. Kann mir jemand helfen? Oder gibts vielleicht eine andere Lösung, wie man die Logging Messages in eine GUI bekommt?

Danke im Voraus!

MFG byto
 

byte

Top Contributor
Ich vermute mal, dass du von dem Appender ableiten musst und dann selber den Writer im Code setzt.

Wie kommst Du darauf? WriterAppender ist nicht abstrakt, also sollte es auch ohne Vererbung klappen.

Und die Warnung sagt nur, dass der Writer nicht geschlossen sein darf und das ist er ja bei mir nicht.
 

Pulvertoastman

Bekanntes Mitglied
das die klasse nicht abstrakt ist, heisst ja nicht unbedingt, dass du sie so verwenden kannst. Das hatte ich so ja auch nicht behauptet.

die warnung sagt aber auch

http://logging.apache.org/log4j/docs/api/org/apache/log4j/WriterAppender.html#setWriter(java.io.Writer) hat gesagt.:
The specified Writer must be opened by the user and be writable.

hast du das auch gelesen?
 

byte

Top Contributor
Ja, die Warnung habe ich gelesen. Aber ein Writer ist doch automatisch geöffnet, wenn man ihn erzeugt und zwar solange, bis das close() kommt. Oder wie soll ich ihn Deiner Meinung nach öffnen?

das die klasse nicht abstrakt ist, heisst ja nicht unbedingt, dass du sie so verwenden kannst. Das hatte ich so ja auch nicht behauptet.

Natürlich kann ich eine Klasse verwenden, wenn sie nicht abstrakt ist und öffentliche Konstruktoren hat. Und das trifft ja in diesem Fall zu. Und es steht auch weder in der log4j Wiki noch in der API, dass man WriterAppender nicht verwenden darf.

WriterAppender appends log events to a Writer or an OutputStream depending on the user's choice.
 

Pulvertoastman

Bekanntes Mitglied
byto hat gesagt.:
Ja, die Warnung habe ich gelesen. Aber ein Writer ist doch automatisch geöffnet, wenn man ihn erzeugt und zwar solange, bis das close() kommt. Oder wie soll ich ihn Deiner Meinung nach öffnen?

Ich denke, dass die Konfiguration des Wrtiers nicht passt und deswegen der Writer nicht gesetzt wird. Soweit ich weiss, kann der Writer nur über die API gesetzt werde. Bin da aber nicht wirklich sicher.

byto hat gesagt.:
Natürlich kann ich eine Klasse verwenden, wenn sie nicht abstrakt ist und öffentliche Konstruktoren hat. Und das trifft ja in diesem Fall zu.

ja kannst du. dagegen wollte ich auch nichts sagen. fraglich bleibt halt bloss, ob das objekt sich dann so verhält wie du denkst, dass es sich verhalten soll. wenn der writer naemlich nicht gesetzt wird, hast du vielleicht ein problem.
 

byte

Top Contributor
Pulvertoastman hat gesagt.:
Soweit ich weiss, kann der Writer nur über die API gesetzt werde. Bin da aber nicht wirklich sicher.

Das wäre ja ziemlich blöd, denn dann könnte man sich die XML Konfiguration ja schenken. Laut log4j Wiki kannst Du alles auch per XML setzen, somit auch den Writer:

The details of the configuration for a specific appender class vary from class to class. Your best bet is to review the javadoc for the appender class you want to use. Pay particular attention to the setter property methods and the values they expect. Each setter method can be accessed using the param element in the xml configuration.

Quelle: http://wiki.apache.org/logging-log4j/Log4jXmlFormat

ja kannst du. dagegen wollte ich auch nichts sagen. fraglich bleibt halt bloss, ob das objekt sich dann so verhält wie du denkst, dass es sich verhalten soll. wenn der writer naemlich nicht gesetzt wird, hast du vielleicht ein problem.

Meinst Du nicht, dass dann irgendwas dahingehend in der API Doc von WriterAppender stehen würde, wenn man diese nicht verwenden darf? Das tut es aber nicht. Und mal ganz unter uns: Ein Framework, das Klassen enthält, die man zwar instanzieren kann aber nicht darf, ist gelinde gesagt ziemlich dämlich entworfen. ;) Denn es gibt ja genug Möglichkeiten, die Instanzierung einer Klasse zu verhindern: Klasse abstrakt machen, Konstruktoren private setzen, ...
 

Pulvertoastman

Bekanntes Mitglied

byte

Top Contributor
Danke für den Link. Das riecht dann ja sehr nach Bug.

Mittlerweile habe ich mir aber sowieso überlegt, dass ich das ganze anders löse, und zwar mit einem eigenen Logger auf Basis von log4j. Dann kann ich in dem Zusammenhang gleich noch andere Sachen mit anpassen.

Thanks anyway.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben