com.jamonapi.MonitorFactory Maven / Gradle / Ivy
package com.jamonapi;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Static MonitorFactory that is good to use in most cases. In the situation
* when you want a different factory then instanciated FactoryEnabled directly.
* Note this is mostly a wrapper for FactoryEnabled and FactoryDisabled. You can also
* get the underlying factory with a call to getFactory()
*/
public class MonitorFactory {
public static final String EXCEPTIONS_LABEL="com.jamonapi.Exceptions";
private static MonitorFactoryInterface factory; // current factory
private static MonitorFactoryInterface enabledFactory; // factory for enabled monitors
private static MonitorFactoryInterface disabledFactory; // factory for disabled monitors
private static MonitorFactoryInterface debugFactory;
static {
// enable the factory by default.
init();
}
/** Get the current Factory (could be the enabled or disabled factory depending on what is enabled) */
public static MonitorFactoryInterface getFactory() {
return factory;
}
/** Returns the factory for creating debug monitors. The debug factory can be disabled independently from the
* regular factory. Debug monitors are no different than monitors returned by the regular monitor factory.
* However the debug factory can be used to monitor items in a test environment and disable them in production.
*
* Sample Call: MonitorFactory.getDebugFactory().start();
*
*/
public static MonitorFactoryInterface getDebugFactory() {
// both the regular factory (isEnabled()) and the debug factory must be enabled
// in order to return the non null factory.
if (isEnabled())
return debugFactory;
else
return disabledFactory;
}
/** Aggregate the passed in value with the monitor associated with the label, and the units. The aggregation tracks
* hits, avg, total, min, max and more. Note the monitor returned is threadsafe. However, it is best to get a monitor
* vi this method and not reuse the handle as TimeMonitors are not thread safe (see the getTimeMonitor method.
*
*
Sample call:
* {@code
* Monitor mon=MonitorFactory.add("bytes.sent","MB", 1024);
* }
*
*/
public static Monitor add(String label, String units, double value) {
return factory.add(label, units, value);
}
/** Used when you want to create your own key for the monitor. This works similarly to a group by clause where the key is
* any columns used after the group by clause.
*/
public static Monitor add(MonKey key, double value) {
return factory.add(key, value);
}
/** Return a timing monitor with units in milliseconds. stop() should be called on the returned monitor to indicate the time
* that the process took. Note time monitors keep the starttime as an instance variable and so every time you want to use a TimeMonitor
* you should get a new instance.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.start("pageHits");
* ...code being timed...
* mon.stop();
* }
*
*/
public static Monitor start(String label) {
return factory.start(label);
}
/** Return a timing monitor with units in milliseconds, that is not aggregated into the jamon stats. stop() should be called on the returned monitor to indicate the time
* that the process took. Note time monitors keep the starttime as an instance variable and so every time you want to use a TimeMonitor
* you should get a new instance.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.start();
* ...code being timed...
* mon.stop();
* }
*
*/
public static Monitor start() {
return factory.start();
}
public static Monitor getMonitor() {
return factory.getMonitor();
}
/** Return a timing monitor with units in milliseconds, that is not aggregated into the jamon stats. The concept of primary allows
* you to correlate performance of all monitors with the most resource intensive things the app does which helps you determine scalability.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.startPrimary("myPrimaryMonitor");
* ...code being timed...
* mon.stop();
* }
*
*/
public static Monitor startPrimary(String label) {
return factory.startPrimary(label);
}
/** Start a monitor with the specified key and mark it as primary */
public static Monitor startPrimary(MonKey key) {
return factory.startPrimary(key);
}
/** Start using the passed in key. Note activity stats are incremented */
public static Monitor start(MonKey key) {
return factory.start(key);
}
/** start nanosecond timer */
public static Monitor startNano(String label) {
return factory.startNano(label);
}
/** Provide your own key to a nanosecond timer */
public static Monitor startNano(MonKey key) {
return factory.startNano(key);
}
/**Return the monitor associated with the label, and units. All statistics associated with the monitor can then be accessed such
* as hits, total, avg, min, and max. If the monitor does not exist it will be created.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.getMonitor("myPrimaryMonitor");
* }
*
*/
public static Monitor getMonitor(String label, String units) {
return factory.getMonitor(label, units);
}
/** Get the monitor associated with the passed in key. It will be created if it doesn't exist */
public static Monitor getMonitor(MonKey key) {
return factory.getMonitor(key);
}
/** Return the time monitor associated with the label. All statistics associated with the monitor can then be accessed such
* as hits, total, avg, min, and max. If the monitor does not exist it will be created.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.getTimeMonitor("myPrimaryMonitor");
* }
*
*/
public static Monitor getTimeMonitor(String label) {
return factory.getTimeMonitor(label);
}
/** Get the time monitor associated with the passed in key. It will be created if it doesn't exist. The units
* are in ms.*/
public static Monitor getTimeMonitor(MonKey key) {
return factory.getTimeMonitor(key);
}
/** Determine if the monitor associated with the label, and the units currently exists.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.getTimeMonitor("myPrimaryMonitor");
* }
*
*/
public static boolean exists(String label, String units) {
return factory.exists(label, units);
}
/** Return true if the monitor associated with the passed in key exists */
public static boolean exists(MonKey key) {
return factory.exists(key);
}
/** Return the composite monitor (a collection of monitors) associated with the passed in units. Note in JAMon 1.0 this
* method would take a label and would return all monitors that matched that criterion. This ability is now better performed
* using ArraySQL from the FormattedDataSet API. See JAMonAdmin.jsp for an example.
*
* Sample call:
* {@code
* Monitor mon=MonitorFactory.getComposite("ms.");
* mon=MonitorFactory.getComposite("allMonitors");
* }
*
*/
public static MonitorComposite getComposite(String units) {
return factory.getComposite(units);
}
/** This returns the number of monitors in this factory. */
public static int getNumRows() {
return factory.getNumRows();
}
/** Return the header for displaying what ranges are available. */
public static String[] getRangeHeader() {
return factory.getRangeHeader();
}
/** Return the ranges in this factory. */
public static Object[][] getRangeNames() {
return factory.getRangeNames();
}
/** Return the composite monitor of all monitors for this factory */
public static MonitorComposite getRootMonitor() {
return factory.getRootMonitor();
}
/** Return the version of JAMon */
public static String getVersion() {
return factory.getVersion();
}
/** Remove/delete the specified monitor */
public static void remove(String label, String units) {
factory.remove(label, units);
}
/** Remove the monitor associated with the passed in key */
public static void remove(MonKey key) {
factory.remove(key);
}
/** Use the specified map to hold the monitors. This map should be threadsafe. This allows for the use
* of a faster map than the default: synchronzied HashMap()
*/
public static void setMap(Map map) {
factory.setMap(map);
}
public static Map getMap() {
return factory.getMap();
}
/** Associate a range with a key/unit. Any monitor with the given unit will
* have this range. Any monitor with no range associated with its unit will have no range.
*/
public static void setRangeDefault(String key, RangeHolder rangeHolder) {
factory.setRangeDefault(key, rangeHolder);
}
/**
* Enable/Disable MonitorFactory. When enabled (true) the factory returns monitors that store aggregate
* stats. When disabled (false) null/noop monitors are returned. enable()/disable() can also be used to
* perform the same function
*/
public static void setEnabled(boolean enable) {
if (enable)
factory = enabledFactory;
else
factory = disabledFactory;
}
/** Enable or disable the debug factory. The debug factory can be
* enabled/disabled at runtime. Calling this method with a false also disables
* calls to MonitorFactory.getDebugFactory(int debugPriorityLevel)
*
* Sample Call:
* {@code
* MonitorFactory.setDebugEnabled(false);
* MonitorFactory.getDebugFactory().start(); // no stats are gathered.
* }
*
*/
public static void setDebugEnabled(boolean enable) {
if (enable)
debugFactory = enabledFactory;
else
debugFactory = disabledFactory;
}
/** Enable MonitorFactory. When enabled the factory returns monitors that
* store aggregate stats. This method has the same effect as calling MonitorFactor.setEnabled(true).
*/
public static void enable() {
setEnabled(true);
}
/** Disable MonitorFactory. When disabled the factory returns null/noop
* monitors. This method has the same effect as calling MonitorFactor.setEnabled(true).
*/
public static void disable() {
setEnabled(false);
}
/** Is the MonitorFactory currently enabled? */
public static boolean isEnabled() {
return (factory == enabledFactory) ? true : false;
}
/** Is the Debug Monitor Factory currently enabled? */
public static boolean isDebugEnabled() {
return (debugFactory == enabledFactory) ? true : false;
}
public static boolean isGlobalActiveEnabled() {
return factory.isGlobalActiveEnabled();
}
public static void enableGlobalActive(boolean enable) {
factory.enableGlobalActive(enable);
}
/** Reset/remove all monitors. If the factory is disabled this method has no action. */
public static void reset() {
if (isEnabled())
init();
}
private static void init() {
// enable the factory by default.
boolean isKeySizeTrackingEnabled= (factory==null) ? false : factory.isTotalKeySizeTrackingEnabled();
factory = debugFactory = enabledFactory = new FactoryEnabled();
if (isKeySizeTrackingEnabled) {
factory.enableTotalKeySizeTracking();
}
disabledFactory = new FactoryDisabled(enabledFactory);
setDebugEnabled(false);
}
/** This returns the header for basic data with no range info in the header.
* This method is deprecated. use the methods associated with the CompositeMonitor.
* The various getXXXHeader() methods of CompositeMonitors can return this information and more.
*/
@Deprecated
public static String[] getHeader() {
return factory.getRootMonitor().getBasicHeader();
}
/** This returns the data for basic data with no range info. The various getXXXData() methods of
* CompositeMonitors can return this information and more.
*/
public static Object[][] getData() {
return factory.getRootMonitor().getBasicData();
}
/** This returns an HTML report for basic data with no range info in the header.
*/
public static String getReport() {
return factory.getRootMonitor().getReport();
}
/** This returns an HTML report for basic data with no range info in the header for the past in units.
* This method will be removed in the next release.
*/
public static String getReport(String units) {
return getComposite(units).getReport();
}
/** Iterator that contains Monitor's that are in this factory */
@Deprecated
public static Iterator iterator() {
return factory.iterator();
}
public static void enableActivityTracking(boolean enable) {
factory.enableActivityTracking(enable);
}
public static boolean isActivityTrackingEnabled() {
return factory.isActivityTrackingEnabled();
}
/**
* Set the maximum number of monitors that JAMon can store. This can be set to reduce the jamon memory footprint. By default
* JAMon's size is unlimited.
*
* @param maxMonitors maximum number of monitors that JAMon can store.
*/
public static void setMaxNumMonitors(int maxMonitors) {
factory.setMaxNumMonitors(maxMonitors);
}
/** Get the maximum number of monitors that JAMon can store. */
public static int getMaxNumMonitors() {
return factory.getMaxNumMonitors();
}
/** Call this method if you want to be able to call MonitorFactory.getTotalKeySize() to determine
* the size of all labels/keys in JAMon.
*/
public static void enableTotalKeySizeTracking() {
factory.enableTotalKeySizeTracking();
}
/** Call this method if you want to disable key size tracking. */
public static void disableTotalKeySizeTracking() {
factory.disableTotalKeySizeTracking();
}
/**
* @return true if totalKeySizeTracking is enabled.
*/
public static boolean isTotalKeySizeTrackingEnabled() {
return factory.isTotalKeySizeTrackingEnabled();
}
/** Returns the total key sizes which is the size of all String lables stored in JAMon. This can be helpful to trigger a call to reset if
* the amount of memory consumed gets too high.
*
* @return Size of all monitor label strings
*/
public static long getTotalKeySize() {
return factory.getTotalKeySize();
}
/** Set the maximum size for a sql statement. Sql bigger than this will be truncated before a JAMon label is created via the JAMon JDBC proxy driver.
* This is useful to limit the size in memory that jamon occupies due to really long sql statements. For backwards compatibility The default is to not
* limit the statement size.
*
* @param size
*/
public static void setMaxSqlSize(int size) {
factory.setMaxSqlSize(size);
}
/** Return the size that sql statements can be before truncating them. This will limit the size of JAMon labels for sql statements
*
* @return returns the max size that sql statements are allowed to be
*/
public static int getMaxSqlSize() {
return factory.getMaxSqlSize();
}
/** Add 2 exception monitors. One for the specific exception and the other a catchall monitor for all exceptions.
* It will also put the stacktrace in the details for both of these monitors as well as for the monitor being passed in
* which would typically be the code associated with throwing the exception. Passing in a null for mon is
* acceptable.
*
* @param mon optional monitor where we want to store the stack trace.
* @param throwable exception that we want to create a monitor for
* @return Returns only the monitor associated with the specific exception even though 2 monitors are created.
*/
public static Monitor addException(Monitor mon, Throwable throwable) {
return factory.addException(mon, throwable);
}
/** Track an exception except there is no other associated monitor to put the details in. Equivalent to
* addException(null, throwable);
*
* @param throwable exception to create a monitor for.
* @return Returns only the monitor associated with the specific exception even though 2 monitors are created.
*/
public static Monitor addException(Throwable throwable) {
return factory.addException(throwable);
}
/**
* Add listeners. These can be read from a properties file (@see JamonPropertiesLoader). It should
* be done as part of application startup. One use is to ensure that exceptions details are tracked at
* application startup. The @see JamonServletContextListener automatically reads the values from the properties
* file if there are any of them.
*
* @since 2.79
*/
public static void addListeners(List listeners) {
factory.addListeners(listeners);
}
}