All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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