Titel-Logo
Projektstudien
TraceLogger
Abstrakt
Beispiele
Techniken
Javadoc
UML-Klassendiagramm
Download
Basics of Cryptography
Custom JBossAS Login
SOAP Webservice
Role Based Access Control
Techniken

Wo sinnvoll habe ich ThreadLocals verwendet um Threads auf Tracer bzw. Tracing-Kontexte abzubilden. In einem Fall hätte dies jedoch gegenüber einer ConcurrentMap<Thread,AbstractTracer> keine Vorteile eingebracht und die Komplexität des Codes eher erhöht. Um Konfigurationen on-the-fly ändern zu können, sind wo nötig Read-Write-Locks eingesetzt worden. Die XML-Konfiguration wird gegen ein XML-Schema validiert bevor sie wirksam werden kann. Die Unittests via JUnit 4 benutzen diverse ExecutorServices und Callable<V>-Implementierungen um nebenläufige Szenarios darzustellen. Der Build erfolgte mit Maven.

Ein wesentlicher Bestandteil des Konzeptes ist der der Polymorphismus der Tracer. Die Basisklasse AbstractTracer definiert dabei das grundlegende Verhalten der Tracer. Die FileTracer und NetTracer unterscheiden sich nur hinsichtlich der Datensenke ihrer Ausgabeströme. Der NullTracer redefiniert den vom AbstractTracer geerbten Kontrakt in seinem Sinne, indem er die geerbten Methoden mit leeren Methodenrümpfen überschreibt die allenfalls null oder einen NullPrintStream zurückgeben. Der NullPrintStream überschreibt seinerseits die vom PrintStream geerbten Methoden mit leeren Methodenrümpfen. Der finale JDKLoggingRouter ist ein NullTracer der lediglich konventionelle Log-Meldungen an den JDKLogger weiterreicht. Die Java Virtual Machine kann diese leeren Methoden durch Inlining eliminieren, so dass die Auswirkungen auf die Performance in der Produktion bei ausgeschaltetem Tracing gering sind. Betrachten Sie bspw. nachstehendes Codesnippet:

1 TracerFactory.getInstance().reset();
2 AbstractTracer tracer = TracerFactory.getInstance().getCurrentPoolTracer();
3 BigInteger sum = new BigInteger("0");
4 for (long i=0; i<1000*1000*1000; i++) {
5 sum = sum.add(BigInteger.valueOf(i));
6 // tracer.out().printfIndentln("sum = %d", sum);
7 }
8 System.out.printf("sum = %d%n", sum);

Wird die Zeile 6 aktiviert, hat dies bei Verwendung der Server VM keinen messbaren Einfluss auf die Laufzeit, da die Defaultkonfiguration der TracerFactory bei Aufruf von getCurrentPoolTracer() immer einen NullTracer liefert der seinerseits immer via NullPrintStream alle Ausgaben verwirft.

Neben den grundlegenden Ausprägungen FileTracer, NetTracer und NullTracer gibt es noch zwei weitere Tracer-Typen die von AbstractTracer ableiten, den DebugLogTee<T extends AbstractTracer> und den QueueTracer<T extends AbstractTracer>. Ersterer definiert eine Abzweigung die zusätzlich Log-Meldungen an ein (konventionelles) Logging-Framework weiterreicht und letzterer einen Tracer der von einer (blockierenden) Queue angefordert werden kann. Hier kommt jeweils ein Polymorphismus durch Komposition zum Einsatz. Einerseits redefinieren diese beiden Tracer-Typen den geerbten Kontrakt, andererseits soll es bspw. auch einen OueueFileTracer geben der in ein File schreibt. Da Java keine Mehrfachvererbung kennt, delegieren diese Tracer die eigentliche Arbeit an eine interne Instanz des Template-Arguments.

Valid XHTML 1.0 Strict