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

net.java.hulp.measure.Probe Maven / Gradle / Ivy

The newest version!
// Copyright (c) 2007 Sun Microsystems
//
// 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.java.hulp.measure;

import net.java.hulp.measure.internal.DelegatorFactory;
import net.java.hulp.measure.internal.FactoryFactoryV2;
import net.java.hulp.measure.internal.FactoryV2;

import javax.management.openmbean.TabularData;

import java.util.List;
import java.util.regex.Pattern;

/**
 * Measures a length of time of an operation and aggregates the results with extremely
 * little overhead so that Probes can be left in production code.
 * 
 * Analogous to logging using java.util.logging.Logger, probes can be used at different 
 * levels: FINE and INFO. Probes at FINE level can be turned off to further reduce 
 * overhead. When probes are turned off, the overhead of having a probe in the code is
 * negligible as it only involves calling an empty method without object creation or
 * synchronization.
 * 
 * Typical usage is:

* * Probe m = Probe.begin(class, topic, subtopic);
* ... do something ...
* d.end();
*
*

* * Notes:
* - A measurement has a source, topic and a subtopic. The source class may be null * in which case the resulting source location string is an empty string. * - Topic and sub topic can be set afterwards. * - A measurement is not reusable. * * @author fkieviet */ public class Probe { private static FactoryV2 sFactory; private static FactoryV2 sAlwaysOnFactory; private static Probe sVoidMeasurement; private static final String FACTORYNAME = "net.sf.hulp.profiler.FactoryFactory"; /** * Constructor; forces callers to use factory method begin() */ protected Probe() { } // Bootstrap: ensures that the begin() factory method will return a void or // concrete measurement static { try { // Try to load factory, taking care of the situation where this class may // be loaded in a self-first delegating classloader String name = System.getProperty(FACTORYNAME, FACTORYNAME); Class cFF = Class.forName(name); Class cparentFF = null; try { cparentFF = Probe.class.getClassLoader().getParent().loadClass(name); } catch (Exception e) { // ignore } Class cparentProbe = null; try { cparentProbe = Probe.class.getClassLoader().getParent().loadClass(Probe.class.getName()); } catch (Exception e) { // ignore } if (cparentFF != null && cFF != cparentFF || cparentProbe != null && cparentProbe != Probe.class) { // Self-first delegating classloader detected... Object factoryfactory = cparentFF.newInstance(); Object alwaysonfactory = cparentFF.getMethod("newAlwaysOnFactoryV2").invoke(factoryfactory); sAlwaysOnFactory = new DelegatorFactory(alwaysonfactory); Object factory = cparentFF.getMethod("newFactoryV2").invoke(factoryfactory); sFactory = new DelegatorFactory(factory); System.out.println("Delegating measurement factory loaded: " + name + " (" + sFactory + ")"); } else { // Ordinary classloading situation FactoryFactoryV2 f = (FactoryFactoryV2) cFF.newInstance(); sAlwaysOnFactory = f.newAlwaysOnFactoryV2(); sFactory = f.newFactoryV2(); System.out.println("Measurement factory loaded: " + name + " (" + sFactory + ")"); } } catch (Throwable ex) { // Ignore error } // Factory failed to load? Disable measurements if (sFactory == null) { sVoidMeasurement = new Probe(); } } /** * Creates a new Probe at FINE level which means that this Probe can be turned off * * @param source source class; may be null * @param topic specifies the operation * @param subTopic qualifies the operation * @return a Probe */ public static Probe fine(Class source, String topic, String subTopic) { if (sVoidMeasurement != null) { return sVoidMeasurement; } else { return sFactory.createV2(FactoryV2.FINE, source, topic, subTopic); } } /** * see {@link #fine(Class, String, String)} */ public static Probe fine(Class source, String topic) { return fine(source, topic, null); } /** * Creates a new probe * @see #fine(Class, String, String) */ public static Probe info(Class source, String topic, String subTopic) { return sAlwaysOnFactory != null ? sAlwaysOnFactory.createV2(FactoryV2.INFO, source, topic, subTopic) : sVoidMeasurement; } /** * @see #fine(Class, String, String) */ public static Probe info(Class source, String topic) { return sAlwaysOnFactory != null ? sAlwaysOnFactory.createV2(FactoryV2.INFO, source, topic, null) : sVoidMeasurement; } /** * Returns if there is a measuring infrastructure installed * @return true if is installed */ public static boolean isFine() { return sVoidMeasurement == null; } /** * Returns if there is a measuring infrastructure installed * @return true if is installed */ public static boolean isInfo() { return sAlwaysOnFactory != null; } /** * @param criteria list of critera of which at least one must match to be included * in the result. Each criterion is an array of two elements, the first element is * a regular expression for the topic and the second element is a regular expression * for the sub topic. * * @return CompositeData if the implementation is present, null if not */ public static TabularData getData(List criteria) { return sAlwaysOnFactory == null ? null : sAlwaysOnFactory.getData(criteria); } /** * Ends the time interval and adds the result to the aggregator */ public void end() { } /** * Resets the topic of the operation */ public void setTopic(String topic) { } /** * Further specifies the operation */ public void setSubtopic(String subTopic) { } /** * Clears the data specified by the criteria * @param criteria list of regular expressions defining the probes */ public static void clearData(List criteria) { if (sAlwaysOnFactory != null) { sAlwaysOnFactory.clearData(criteria); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy