Ich benutze einen Logger der mir die Klasse und Methode nicht anzeigt, wo dei Logging-Methoden aufgerufen werden. Wie ermittle ich ohne explizites Argument von this den Aufrufer?
Pseudo-Code um es zu illustrieren:
class Editor {
method process() {
Logger.log( message );
}
}
. . .
class Logger {
method log( msg ) {
/* write the message to the console or else where */
}
}
Die Ausgabe soll dann in etwa so lauten:
05.11.2009 - 17:33 - Editor - process - UND HIER DIE MESSAGE
Bitte jetzt keine Antworten wie "benutz doch die Standard API" oder "Log4J".
Dafür gibts doch das Makro
> FUNCTION
in so gut wie jeder Sprache, damit kann man innerhalb einer Funktion den Funktionsbezeichner ermitteln.
[UNDERSCORE][UNDERSCORE]FUNCTION[UNDERSCORE][UNDERSCORE]
(Underscores werden leider nicht angezeigt)
Ich hatte vergessen zu erwähnen, dass es sich um Java handelt. Hätte man sich meine letzte Antwort durchgelesen oder sich die Tags angeschaut, hätte man das aber schnell rausgefunden :-D
In Java gibt es keine Makros. Und FUNCTION scheint es hauptsächlich nur in C-Derivaten zu geben, also C++, Objective C etc. Also nicht in jeder Programmiersprache. Java ist überhaupt nicht mit C/C++ verwandt, auch wenn die Syntax sehr ähnlich ist.
An weitere Kommentatoren: Das Problem habe ich längst mit dem Stacktrace gelöst ;-)
hm du hättest die Methode "LOG" so wie die EventHandler gestalten können: public void Log ( LogEvent e). Das LogEvent dann noch initialisieren mit z.B: LogEvent l = new LogEvent ( ID, timestamp, message, this[sender] ). Dann wüsstest du wer wann das Event "geworfen" hat und könntest die Events z.B. anhand der ID in einer Collection speichern.
Genau das wollte ich verhindern, this als Argument zu übergeben. Die von mir gepostete Lösung ist doch schon recht praktisch, ich rufe die Log-Methoden auf und in dieser wird der Stacktrace ausgewertet um den Aufrufer zu ermitteln, das heißt den Klassen- und Methodennamen. Bei deiner Lösung kann man nur den Klassennamen ermitteln. Bitte korrigiere mich, wenn ich falsch liege, aber this ist kein Ersatz für die ganze Aufrufer-Hierarchie. Du übermittelst nur das Objekt.
Das Framework ist mir vorgegeben, ich benutze http://www.theobjectguy.com/javalog/ . Beim Standard Java Logging konnte ich trotz Anpassung der Properties-Datei die zu filternden Log-Levels nicht verändern. Log4j wollte nicht funktionieren und da ich nur einen Prototyp für nen grafischen Editor schreibe, brauche ich auch keine performante Lösung, weil der Prototyp später eh weggeschmissen wird.
Hab's jetzt selber rausgefunden.
Das geht über den Stacktrace.
StackTraceElement[] stea = Thread.currentThread().getStackTrace(); System.out.println(stea[2].getClassName()); System.out.println(stea[2].getMethodName());
Den Index muß man anpassen, je nachdem wie groß die Aufrufhierarchie ist. 0 ist Thread und 1 die Klasse in der der Stacktrace ausgewertet wird.
Am besten die Array-Länge wird überprüft bevor man sich über OutOfBounceExceptions wundert :-D