Class TracerFactory
- java.lang.Object
-
- de.christofreichardt.diagnosis.TracerFactory
-
public class TracerFactory extends Object
A factory and holder of tracers.Tracers will be created according to a given (XML-)configuration. So long as no configuration has been read some methods provide a default tracer. This default tracer traces nothing and routes log messages to the core logging facilities of the Java platform, see java.util.logging and
JDKLoggingRouter.The configuration file consists of four main sections. You can put tracer into a pool and access them by name. Second you may redefine the default tracer. Third you can map threads on tracer and subsequently access the primary tracer for a given thread. Or you may configure a blocking queue of tracer for multi-threading environments for which you cannot control thread creation. Consider for example the following definitions:
<?xml version="1.0" encoding="UTF-8" ?> <TraceConfig xmlns="http://www.christofreichardt.de/java/tracer"> <Pool> <TraceLogger name="ExampleTracer" class="de.christofreichardt.diagnosis.file.FileTracer"> <LogDir>./log/</LogDir> <AutoFlush>true</AutoFlush> <BufSize>1024</BufSize> <Limit>1048576</Limit> <Context> <Thread name="main"> <Online>true</Online> <DebugLevel>5</DebugLevel> </Thread> </Context> </TraceLogger> </Pool> <Map> <Threads> <Thread name="main"> <TraceLogger ref="ExampleTracer" /> </Thread> </Threads> </Map> </TraceConfig>The definitions above make use of the first and the third section. A
FileTracerhas been configured. Its outputfile is located at ./log/ExampleTracer.log. The tracer is in autoflush mode, that is every time an observed method is popped from the stack the output stream will be flushed. The tracer will back up its file when it reaches the size of one MebiByte (1024*1024 Byte). The 'ExampleTracer' is interested in output from the main-Thread up to a stack size of five. Note that this is not the call stack of the Java Virtual Machine. You may put only methods you are interested in on a separate stack managed by aTracingContext. The main-Thread has been mapped on the 'ExampleTracer'. Therefore you may invoke a convenience method to retrieve the tracer for this thread. Assuming you put the configuration file into ./config/ExampleConfig.xml, the TracerFactory can be configured and used like this from the main-Thread:File configFile = new File("." + File.separator + "config" + File.separator + "ExampleConfig.xml"); TracerFactory.getInstance().readConfiguration(configFile); final AbstractTracer tracer = TracerFactory.getInstance().getCurrentPoolTracer(); tracer.open(); try { class Foo { void bar() { tracer.entry("void", this, "bar()"); try { tracer.out().printfIndentln("This is an example."); } finally { tracer.wayout(); } } } Foo foo = new Foo(); foo.bar(); // nothing will be printed because no tracing context has been provided tracer.initCurrentTracingContext(); // the configured tracing context will be used foo.bar(); // this will generate output } finally { tracer.close(); }The generated output can be found at ./log/ExampleTracer.log - whereas the directory ./log must exist - and looks like:
--> TraceLog opened! Time : Mi Apr 02 23:14:41 MESZ 2014 Bufsize : 512 Autoflush: true ENTRY--void Foo[12275192].bar()--main[1] This is an example. RETURN-void Foo[12275192].bar()--(+0ms)--(+0ms)--main[1] --> TraceLog closing! Time : Mi Apr 02 23:14:41 MESZ 2014This approach makes sense if you control the creation of threads. Keep in mind that the Java Virtual Machine doesn't guarantee the uniqueness of thread names. That is when you invoke
TracerFactory.getInstance().getCurrentPoolTracer()from another thread called 'main' later on, you will get the default tracer which routes log messages (but not the tracing output) to the JDK logger.- Author:
- Christof Reichardt
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classTracerFactory.ExceptionBase exception class for all exceptional situations within the context of the TracerFactoryprotected classTracerFactory.QueueIf appropriately configured it enables access to a blocking deque of tracers.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidclosePoolTracer()Closes all pooled tracers.booleancloseQueueTracer()Tries to close all enqueued QueueTracer.AbstractTracergetCurrentPoolTracer()Returns the mapped tracer for the current thread.QueueTracer<?>getCurrentQueueTracer()Returns the QueueTracer for the current thread.NullTracergetDefaultTracer()Returns the configured default tracer (aNullTracer).static TracerFactorygetInstance()Retrieves the single TracerFactory.intgetQueueSize()Returns the size of the configured tracer queue.StringgetQueueTracerClassname()Returns the classname of the configured QueueTracer.AbstractTracergetTracer(String name)Returns the pooled tracer with the given name.AbstractTracergetTracer(Thread thread)Returns the mapped tracer for the given thread.booleanisQueueEnabled()Indicates if the tracer queue is enabled.protected booleanofferTracer(QueueTracer<? extends AbstractTracer> tracer)Used to enqueue a tracer which has been previously retrieved by a call totakeTracer().voidopenPoolTracer()Opens all pooled tracers.booleanopenQueueTracer()Tries to open all enqueued QueueTracer.voidreadConfiguration(File configFile)Reads the given configuration file, validates it against an XML-Schema and creates the tracer pool, its mappings and the queue accordingly.voidreadConfiguration(InputStream inputStream)Reads the configuration from the given InputStream.voidreset()Clears the pool, the mappings and the queue.QueueTracer<? extends AbstractTracer>takeTracer()Takes the tracer from the head of the deque.
-
-
-
Method Detail
-
getInstance
public static TracerFactory getInstance()
Retrieves the single TracerFactory.- Returns:
- the single TracerFactory
-
getDefaultTracer
public NullTracer getDefaultTracer()
Returns the configured default tracer (aNullTracer).- Returns:
- the defaultTracer
-
getQueueSize
public int getQueueSize()
Returns the size of the configured tracer queue.- Returns:
- the size of the tracer queue
-
isQueueEnabled
public boolean isQueueEnabled()
Indicates if the tracer queue is enabled.- Returns:
- true if the tracer queue is enabled
-
getQueueTracerClassname
public String getQueueTracerClassname()
Returns the classname of the configured QueueTracer.- Returns:
- the classname of the configured QueueTracer
-
readConfiguration
public void readConfiguration(File configFile) throws TracerFactory.Exception, IOException
Reads the given configuration file, validates it against an XML-Schema and creates the tracer pool, its mappings and the queue accordingly. This method should normally be invoked once at program start. Multiple calls with the same configuration file leads to instantiations of new tracer objects and mappings which will replace the old tracers and their mappings.- Parameters:
configFile- the configuration file- Throws:
TracerFactory.Exception- indicates a configuration problemIOException- indicates an I/O problem, e.g. a missing configuration file
-
readConfiguration
public void readConfiguration(InputStream inputStream) throws TracerFactory.Exception
Reads the configuration from the given InputStream.- Parameters:
inputStream- the input stream providing the configuration. Caller is responsible for closing the stream.- Throws:
TracerFactory.Exception- indicates a configuration problem- See Also:
readConfiguration(java.io.File)
-
getTracer
public AbstractTracer getTracer(String name) throws TracerFactory.Exception
Returns the pooled tracer with the given name.- Parameters:
name- the name of the desired tracer- Returns:
- the pooled tracer
- Throws:
TracerFactory.Exception- if no tracer exists with the given name
-
getTracer
public AbstractTracer getTracer(Thread thread)
Returns the mapped tracer for the given thread. The given Thread object is used as key to a map. If no tracer can be found within the map for the given Thread the configuration will be searched for the thread's name. That is initially the resolution is based on thread names (prior to program execution no threads do exist but someone may know the to be used thread names). If there isn't an entry for a given Thread but the name of the thread has been encountered before (thread names aren't unique) a NullTracer will be returned.- Parameters:
thread- the thread for which a tracer is searched- Returns:
- the mapped tracer for the given thread
-
getCurrentPoolTracer
public AbstractTracer getCurrentPoolTracer()
Returns the mapped tracer for the current thread.- Returns:
- the mapped tracer for the current thread
- See Also:
getTracer(java.lang.Thread)
-
reset
public void reset()
Clears the pool, the mappings and the queue.
-
openPoolTracer
public void openPoolTracer()
Opens all pooled tracers.
-
closePoolTracer
public void closePoolTracer()
Closes all pooled tracers.
-
takeTracer
public QueueTracer<? extends AbstractTracer> takeTracer()
Takes the tracer from the head of the deque. If the deque is empty the methods blocks until a tracer will become available. By default, a QueueTracer wrapping a NullTracer will be (non-blocking) delivered.- Returns:
- the tracer from the head of the deque
-
offerTracer
protected boolean offerTracer(QueueTracer<? extends AbstractTracer> tracer)
Used to enqueue a tracer which has been previously retrieved by a call totakeTracer().- Parameters:
tracer- the to be enqueued tracer- Returns:
- indicates if the tracer has been enqueued (true) or has been discarded (false)
-
openQueueTracer
public boolean openQueueTracer()
Tries to open all enqueued QueueTracer.- Returns:
- true if all configured tracers has been opened, false otherwise
-
closeQueueTracer
public boolean closeQueueTracer()
Tries to close all enqueued QueueTracer.- Returns:
- true if all configured tracers has been closed, false otherwise
-
getCurrentQueueTracer
public QueueTracer<?> getCurrentQueueTracer()
Returns the QueueTracer for the current thread. If no one was found a QueueNullTracer will be returned.- Returns:
- the QueueTracer for the current thread
-
-