//
// Trace.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.util;
import java.lang.reflect.Method;
/**
* This class provides a hook into the IDV Trace facility. It uses reflection to call
* the corresponding ucar.unidata.util.Trace methods if that class can be found.
* Else, nothing happens.
* To use this first call: Trace.startTrace();
* <p>
* You can bracket a code segment with:<pre>
* Trace.call1("some label");
* ... code
* Trace.call2("some label");
* </pre>
* This matches the "some label". It will indent subsequent Trace calls to show nesting.
* You can also just print something out with:<pre>
* Trace.msg("some message");
* </pre>
* The output looks like:<pre>
* 196 996 >ImageRenderer type.doTransform
* 11 99 >ImageRenderer build texture length: 4503200
* 2 15 >ImageRenderer new byte
* 691 15683 <ImageRenderer new byte ms: 690
* 1 1 >ImageRenderer color_bytes
* 345 99 <ImageRenderer color_bytes ms: 344
* 0 2 <ImageRenderer build texture ms: 1037
* </pre>
* The first column is the elapsed time since the last print line. The second column is the
* memory delta (note: GC can make this negative). For the call1/call2 pairs the ms:... shows
* the time spent in the block.
*
*/
public class Trace
{
private static boolean doneReflectionLookup = false;
private static Method call1Method;
private static Method call2Method;
private static Method msgMethod;
private static Method startMethod;
private static Method stopMethod;
public static void main(String[]args) {
// Trace.startTrace();
Trace.call1("hello");
Trace.msg("hello there");
Trace.call2("hello");
}
/** Try to load the ucar Trace facility via reflection
*
* @return Was successful
*/
private static boolean checkReflection() {
if(!doneReflectionLookup) {
try {
Class c = Class.forName("ucar.unidata.util.Trace");
call1Method = c.getDeclaredMethod("call1", new Class[]{String.class,String.class});
call2Method = c.getDeclaredMethod("call2", new Class[]{String.class,String.class});
msgMethod = c.getDeclaredMethod("msg", new Class[]{String.class});
startMethod = c.getDeclaredMethod("startTrace", new Class[]{});
stopMethod = c.getDeclaredMethod("stopTrace", new Class[]{});
} catch(Exception exc){
}
doneReflectionLookup = true;
}
return msgMethod!=null;
}
/**
* Bracket a block of code with call1("some unique msg"); ...code...; call2("some unique msg");
* Where "some unique msg" is used to match up the call1/call2 pairs
*/
public static void call1(String msg) {
call1(msg,"");
}
/** Bracket a block of code with call1("some unique msg"); ...code...; call2("some unique msg");
* Append extra to the end of the line
*/
public static void call1(String msg, String extra) {
if(!checkReflection()) return;
try {
call1Method.invoke(null, new Object[]{msg,extra});
} catch(Exception iae){
System.err.println("Trace.call1:" + iae);
}
}
/** Call this to start tracing */
public static void startTrace() {
if(!checkReflection()) {
System.err.println("Could not start tracing");
return;
}
try {
startMethod.invoke(null, new Object[]{});
} catch(Exception iae){
System.err.println("Trace.startTrace:" + iae);
}
}
/** Call this to start tracing */
public static void stopTrace() {
if(!checkReflection()) {
System.err.println("Could not stop tracing");
return;
}
try {
stopMethod.invoke(null, new Object[]{});
} catch(Exception iae){
System.err.println("Trace.stopTrace:" + iae);
}
}
/** Bracket a block of code with call1("some unique msg"); ...code...; call2("some unique msg"); */
public static void call2(String msg) {
call2(msg,"");
}
/** Close the call */
public static void call2(String msg, String extra) {
if(!checkReflection()) return;
try {
call2Method.invoke(null, new Object[]{msg,extra});
} catch(Exception iae){
System.err.println("Trace.call2:" + iae);
}
}
/** Print out a line */
public static void msg(String msg) {
if(!checkReflection()) return;
try {
msgMethod.invoke(null, new Object[]{msg});
} catch(Exception iae){
System.err.println("Trace.msg:" + iae);
}
}
}