An example of an instrumented Java program is available for reference; you can cut and paste snippets from there to instrument your program. The example uses multiple threads producing different trace events.
Here we'll explain the basic principles behind Java-level generation of TuningFork traces and how to use the individual APIs.
ILogger logger = LoggerFactory.makeFileLogger(new File(filename));where
filename
is the String with the filename. The generated trace can then be viewed
in TuningFork using the "Open Trace" operation from the File menu.
To create a socket logger, use
ILogger logger = LoggerFactory.makeServerLogger(portNumber);where
portNumber
is the integer port number to use for the socket. The generated trace can
then be viewed in TuningFork as the instrumented program is running by connecting to the trace socket with
"Connect to a Trace" from the File menu.
There is also a logger that simply ignores all logging requests. This is useful so that you don't
have to sprinkle if (LOGGING)
conditionals throughout your code. You can simply decide
at the beginning of execution whether you actually want to generate a trace. If you don't, create a
null logger:
ILogger logger = LoggerFactory.makeNullLogger();
The TuningFork tool will take care of re-assembling the events in the feedlets in order, so you can use the feedlets without worrying about time synchronization between them. To create a feedlet, use
IFeedlet myFeedlet = logger.makeFeedlet("My Feedlet", "Primary feedlet for my program");where the first string parameter is the short name for the feedlet and the second one is a longer description. These names are purely for your convenience, so you can use anything you like.
You can add events to feedlets explicitly, but it's more convenient to associate a feedlet with a thread, which you can do with
myFeedlet.bindToCurrentThread();After that, if you log a trace event on that thread without specifying a feedlet, it will be placed in the feedlet you bound to the thread.
To create a timer event, use
ITimerEvent phaseTimer = logger.makeTimerEvent("Phase of My Program");The timer event can now be used to add events to the log. Similarly, to create a value event, use
IValueEvent sizeEvent = logger.makeValueEvent("Size of My Primary Data Structure");
Value events record a single double
value along with their timestamp.
sizeEvent.addValue(myDataStructure.size());where
myDataStructure
is some object whose size you want to monitor.
To add a timer event marking the beginning and end of some operation, you could use
phaseTimer.start(); myApplicationWork(); phaseTimer.stop();where
myApplicationWork()
is a method in your program whose timing you want to measure.
Properties should only be added once; they are not events. If you have some repeating occurrence that you want to log, use a value event and not a property.
For example, you could add information about the way the program was run:
logger.addProperty("Command", args[0] + " " + args[1]);where
args
is the String array passed to your main()
function.