
net.sf.hulp.profiler.Profiler Maven / Gradle / Ivy
The newest version!
// Copyright (c) 1999 Frank Gerard
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
package net.sf.hulp.profiler;
import net.sf.hulp.util.Markup;
import net.sf.hulp.util.MarkupHtml;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Map;
/**
* Defines a generic Profiler. See Measurement.
*/
public abstract class Profiler implements net.sf.hulp.measure.Measurement.Factory, net.java.hulp.measure.internal.FactoryV2 {
private static Profiler s_singleton;
/**
* Property id of class that implements provider
*/
public static final String PROVIDER = "net.sf.hulp.profiler.Provider";
/**
* Property id to dump on exit destination
*/
public static final String DUMPONEXITTO = "net.sf.hulp.profiler.dumpto";
/**
* A shutdown handler that will dump out the contents of the specified
* profiler to the specified directory.
*/
public static class DumpOnExit implements Runnable {
private Profiler mProfiler;
private File mDumpTo;
/**
* Constructor
*
* @param dumpWhat Profiler to dump
* @param dumpToDirectory where to dump to
*/
public DumpOnExit(Profiler dumpWhat, File dumpToDirectory) {
mProfiler = dumpWhat;
mDumpTo = dumpToDirectory;
}
/**
* @see java.lang.Runnable#run()
*/
public void run() {
OutputStream out = null;
try {
File f = File.createTempFile("profiler", ".html", mDumpTo);
out = new BufferedOutputStream(new FileOutputStream(f));
PrintWriter o = new PrintWriter(out);
Markup m = new MarkupHtml();
o.println(m.beginPage());
o.println(m.beginTable(Markup.TABLESTYLE_BANNEREGAL));
mProfiler.dump(o, m);
o.println(m.endTable());
o.println(m.endPage());
o.flush();
} catch (Exception e) {
System.out.println("Could not dump profiler data in shutdown handler to "
+ mDumpTo.getAbsolutePath());
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception ex) {
// ignore
}
}
}
}
/**
* Loads the appropriate profiler class or the void one if none specified
*/
private synchronized static void load() {
if (s_singleton != null) {
return;
}
try {
Profiler p = null;
// Lookup the class
String classname = System.getProperty(PROVIDER, RealProfiler.class.getName());
if (classname == null || "".equals(classname)) {
p = new VoidProfiler();
s_singleton = p;
} else {
// Load the class and instantiate it
try {
Class dynclass = Class.forName(classname);
p = (Profiler) dynclass.newInstance();
} catch (Exception e) {
throw new RuntimeException("Error loading profiler provider [" + classname + "]: " + e, e);
}
// Need to dump out the results on exit?
String dumpto = System.getProperty(DUMPONEXITTO, null);
if (dumpto != null && dumpto.length() > 0) {
Thread t = new Thread(new DumpOnExit(p, new File(dumpto)),
"Profiler dump on exit");
Runtime.getRuntime().addShutdownHook(t);
}
s_singleton = p;
}
} catch (Exception e) {
throw new RuntimeException("Error loading profiler provider: " + e, e);
}
}
/**
* Gives access to the profiler singleton. Note: double locking scheme here is
* formally incorrect. This method formally should be synchronized. It's not, and
* due to the purpose of this class (debugging) it's not critical.
*/
static public Profiler get() {
if (s_singleton == null) {
load();
}
return s_singleton;
}
/**
* Prints out all accumulated measurement data; it is assumed that there is an open
* table in the specified Markup
*/
abstract public void dump(final PrintWriter out, final Markup f) throws IOException;
/**
* Gets all aggregated results, one map for each measurement. The maps have column
* names as their keys, and the values (String, Integer, Double) as their values.
* Column names are constants in Profiler, e.g. H_TOPIC.
*
* @return map
*/
abstract public Map[] dump();
/**
* Dumps a help screen on this particular profiler
*
* @param out stream to write to
* @param f Markup
*/
abstract public void help(PrintWriter out, Markup f);
/**
* Returns all aggregated results in the form of a map; the keys are the
* topic+subtopic names separated by the specified parameter; the value is a Map.
* See dump() for the contents of this map.
*
* @param topicSubtopicSeparator
* @return Map
*/
abstract public Map dump(String topicSubtopicSeparator);
/**
* Clears all accumulated data
*/
abstract public void clear();
public static final String H_SOURCE = "source";
public static final String H_TOPIC = "topic";
public static final String H_SUBTOPIC = "sub topic";
public static final String H_N = "n";
public static final String H_TOTALTIME = "total time (ms)";
public static final String H_AVERAGEPRIME = "average' (ms)";
public static final String H_MEDIAN = "median (ms)";
public static final String H_ACT = "act";
public static final String H_FIRST = "first (ms)";
public static final String H_AVERAGE = "average (ms)";
public static final String H_THROUGHPUT = "throughput (s-1)";
public static final String H_TIMESPAN = "last-first (ms)";
public static final String H_LOAD = "load";
public static final String H_HISTPREFIX = "h ";
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy