--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/jmx/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * JMX examples for Java Simon - single point {@link org.javasimon.jmx.SimonManagerMXBean} and per Simon
3 | * {@link org.javasimon.jmx.CounterMXBean}/{@link org.javasimon.jmx.StopwatchMXBean} usage via
4 | * {@link org.javasimon.examples.jmx.JmxCallbackExample}.
5 | */
6 | package org.javasimon.examples.jmx;
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/quantiles/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * {@link org.javasimon.callback.quantiles.QuantilesCallback} sorts splits to categories
3 | * ({@link org.javasimon.callback.quantiles.Bucket}s) based on time ranges. This can be used to
4 | * compute quantile approximations or to draw distribution charts.
5 | */
6 | package org.javasimon.callback.quantiles;
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java Simon embeddable Web console base package.
3 | * Contains Front controller {@link org.javasimon.console.SimonConsoleRequestProcessor} which is used
4 | * by a Servlet {@link org.javasimon.console.SimonConsoleServlet} and a Servlet Filter {@link org.javasimon.console.SimonConsoleFilter}.
5 | */
6 | package org.javasimon.console;
--------------------------------------------------------------------------------
/console-webapp/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JavaSimon Console
6 |
7 |
8 |
JavaSimon Console
9 | Look here!
10 |
11 |
12 |
--------------------------------------------------------------------------------
/jdbc41/src/main/java/org/javasimon/jdbc4/jmx/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Work in progress: MX beans specific to Simon JDBC driver.
3 | *
4 | * {@link org.javasimon.jdbc4.jmx.JdbcMXBean} provides more specific information about JDBC driver metrics and more convenient
5 | * view than generic MX bean or bean tree provided by {@link org.javasimon.jmx.JmxRegisterCallback}.
6 | */
7 | package org.javasimon.jdbc4.jmx;
8 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/proxy/Delegating.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.proxy;
2 |
3 | /**
4 | * Interface indicating that an object is wrapping another object.
5 | *
6 | * @param Wrapped type
7 | * @author gerald
8 | */
9 | public interface Delegating {
10 |
11 | /**
12 | * Get wrapped object.
13 | *
14 | * @return Wrapped object
15 | */
16 | T getDelegate();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToStringConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter for String type.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToStringConverter implements Converter {
9 |
10 | @Override
11 | public String convert(Class> targetClass, String strVal) {
12 | return strVal;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/test/resources/org/javasimon/callback/quantiles/quantiles.properties:
--------------------------------------------------------------------------------
1 | .min=0
2 | .max=60000
3 | .nb=5
4 | .type=LINEAR
5 |
6 | # For org.javasimon group: more buckets
7 | org.javasimon.nb=10
8 |
9 | # SlowClass is a performance bottleneck: higher upper bound
10 | org.javasimon.slow.SlowClass.max=300000
11 | *
12 | # Can use Exponential buckets for some Stopwatches
13 | org.javasimon.special.type=EXPONENTIAL
14 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/SimonVisitor.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console;
2 |
3 | import java.io.IOException;
4 |
5 | import org.javasimon.Simon;
6 |
7 | /**
8 | * Callback interface used when visiting Simon manager and it Simons.
9 | *
10 | * @see SimonVisitors
11 | * @author gquintana
12 | */
13 | public interface SimonVisitor {
14 |
15 | void visit(Simon simon) throws IOException;
16 | }
17 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/text/Stringifier.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.text;
2 |
3 | /**
4 | * Value formatter for given type.
5 | * @param Input type
6 | * @author gquintana
7 | */
8 | public interface Stringifier {
9 | /**
10 | * Converts/formats a value into string.
11 | * @param value Input value
12 | * @return Ouput string
13 | */
14 | String toString(T value);
15 | }
16 |
--------------------------------------------------------------------------------
/development/readme.txt:
--------------------------------------------------------------------------------
1 | If you use IDEA 12, please use this scheme and copy it into
2 | Java Simon project. Thanks :-)
3 |
4 | Move the file into your .IntelliJIdea12/config/codestyles directory, then:
5 | - start IDEA,
6 | - open the project,
7 | - go to Settings,
8 | - in the left section Project Settings choose Code Style,
9 | - click the Manage button,
10 | - select "Java Simon IDEA 12",
11 | - click Copy to Project,
12 | - confirm, close... you're ready to go.
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/logging/LogMessageSource.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.logging;
2 |
3 | /**
4 | * Message provider, converts context into a loggable string.
5 | *
6 | * @author gquintana
7 | */
8 | public interface LogMessageSource {
9 |
10 | /**
11 | * Returns message for given context.
12 | *
13 | * @param context Context
14 | * @return Message
15 | */
16 | String getLogMessage(C context);
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/SimonUnitTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | import org.testng.annotations.BeforeMethod;
4 |
5 | import java.lang.reflect.Method;
6 |
7 | public abstract class SimonUnitTest {
8 |
9 | @BeforeMethod
10 | public void clearManagerAndPrintMethod(Method method) {
11 | SimonManager.clear();
12 | SimonManager.enable();
13 | System.out.println("TEST METHOD: " + getClass().getSimpleName() + '.' + method.getName());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/jdbc41/src/main/java/org/javasimon/jdbc4/RegexBasedNormalizerFactory.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jdbc4;
2 |
3 | import java.util.List;
4 |
5 | public class RegexBasedNormalizerFactory implements SqlNormalizerFactory {
6 | @Override
7 | public SqlNormalizer getNormalizer(String sql) {
8 | return new RegexBasedSqlNormalizer(sql);
9 | }
10 |
11 | @Override
12 | public SqlNormalizer getNormalizer(List batch) {
13 | return new RegexBasedSqlNormalizer(batch);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java Simon supporting utilities and tools. Main utility class is {@link org.javasimon.utils.SimonUtils},
3 | * the rest is used either internally ({@link org.javasimon.utils.Replacer}) or they are supporting tools
4 | * for various tasks ({@link org.javasimon.utils.BenchmarkUtils} to support (micro)benchmarking
5 | * or {@link org.javasimon.utils.GoogleChartImageGenerator} to draw charts on the web).
6 | */
7 | package org.javasimon.utils;
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/ActionException.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console;
2 |
3 | /**
4 | * Exception raised during action execution
5 | *
6 | * @author gquintana
7 | */
8 | public class ActionException extends Exception {
9 | public static final long serialVersionUID=1;
10 | public ActionException(String message, Throwable cause) {
11 | super(message, cause);
12 | }
13 |
14 | public ActionException(String message) {
15 | super(message);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/demoapp/src/main/java/org/javasimon/demoapp/dao/ToDoItemDao.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.demoapp.dao;
2 |
3 | import org.javasimon.demoapp.model.ToDoItem;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author Ivan Mushketyk (ivan.mushketyk@gmail.com)
9 | */
10 | public interface ToDoItemDao {
11 | List getAll();
12 |
13 | void create(ToDoItem toDoItem);
14 |
15 | void delete(long id);
16 |
17 | void update(ToDoItem toDoItem);
18 |
19 | ToDoItem getById(long id);
20 |
21 | void deleteAll();
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/MustBeInSynchronized.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Marker annotation for a method that should be called within a synchronized block. Annotation
10 | * does not ensure anything, it is a mere documentation.
11 | */
12 | @Target(ElementType.METHOD)
13 | @Retention(RetentionPolicy.SOURCE)
14 | public @interface MustBeInSynchronized {
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ConvertException.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Thrown in case of conversion errors.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ConvertException extends RuntimeException {
9 |
10 | public ConvertException(String msg) {
11 | super(msg);
12 | }
13 |
14 | public ConvertException(Throwable cause) {
15 | super(cause);
16 | }
17 |
18 | public ConvertException(String msg, Throwable cause) {
19 | super(msg, cause);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/test/resources/org/javasimon/utils/SampleHtmlGeneratorTest-1sample.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Name
4 |
Active
5 |
Counter
6 |
Min
7 |
Max
8 |
Mean
9 |
Total
10 |
11 |
12 |
sample1
13 |
1
14 |
2
15 |
5.00 us
16 |
15.0 us
17 |
10.0 us
18 |
20.0 us
19 |
20 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/BeanUtilsException.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Exception thrown by SimonBeanUtils class.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class BeanUtilsException extends RuntimeException {
9 |
10 | public BeanUtilsException(String msg) {
11 | super(msg);
12 | }
13 |
14 | public BeanUtilsException(Throwable cause) {
15 | super(cause);
16 | }
17 |
18 | public BeanUtilsException(String msg, Throwable cause) {
19 | super(msg, cause);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/demoapp/src/main/java/org/javasimon/demoapp/dao/DaoException.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.demoapp.dao;
2 |
3 | /**
4 | * @author Ivan Mushketyk (ivan.mushketyk@gmail.com)
5 | */
6 | public class DaoException extends RuntimeException {
7 | public DaoException() {
8 | super();
9 | }
10 |
11 | public DaoException(String msg) {
12 | super(msg);
13 | }
14 |
15 | public DaoException(Throwable cause) {
16 | super(cause);
17 | }
18 |
19 | public DaoException(String msg, Throwable cause) {
20 | super(msg, cause);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/javaee/src/main/java/org/javasimon/javaee/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Java EE support for Simons contains Java EE components (servlet filter and EJB/CDI interceptor) that can be used or extended.
3 | * Package contains following components:
4 | *
5 | *
{@link org.javasimon.javaee.SimonServletFilter} is Servlet Filter for monitoring HTTP requests.
6 | *
{@link org.javasimon.javaee.SimonInterceptor} is EJB/CDI Interceptor for monitoring business method invocations.
7 | *
8 | * Consult class javadocs for usage information.
9 | */
10 | package org.javasimon.javaee;
--------------------------------------------------------------------------------
/console-embed/src/test/java/org/javasimon/console/plugin/DummyOtherPlugin.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.plugin;
2 |
3 | import org.javasimon.console.SimonConsolePlugin;
4 | import org.javasimon.console.html.HtmlResourceType;
5 |
6 | /**
7 | * Plugin for testing purpose.
8 | *
9 | * @author gquintana
10 | */
11 | public class DummyOtherPlugin extends SimonConsolePlugin {
12 |
13 | public DummyOtherPlugin() {
14 | super("other", "Other Plugin");
15 | addResource("js/other.js", HtmlResourceType.JS);
16 | addResource("js/other.css", HtmlResourceType.CSS);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToCharConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | *
5 | * @author Ivan Mushketyk
6 | */
7 | public class ToCharConverter implements Converter {
8 | @Override
9 | public Character convert(Class> targetClass, String strVal) throws ConvertException {
10 | if (strVal == null) {
11 | return null;
12 | }
13 |
14 | if (strVal.length() == 1) {
15 | return strVal.charAt(0);
16 | }
17 |
18 | throw new ConvertException(String.format("Failed to convert '%s' to character", strVal));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/console-embed/src/main/resources/org/javasimon/console/resource/js/javasimon-dummyPlugin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * Plugin for example/demonstration purpose
4 | */
5 | (function(domUtil, viewPluginMgr) {
6 | console.log("Loaded JavaSimon Dummy Plugin");
7 | // "dummy" is the plugin identifier (see DummyDetailPlugin Java class)
8 | viewPluginMgr.fnAddPluginRenderer("dummy",function(eTableBody, oDummy) {
9 | var row=this.fnAppendRow(eTableBody);
10 | // oDummy={message:"Hello World!"}
11 | this.fnAppendLabelValueCell(row,"Message", oDummy.message, 3);
12 | });
13 | }(javasimon.DOMUtil, javasimon.ViewPluginManager));
14 |
15 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/logging/DisabledLogTemplate.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.logging;
2 |
3 | /**
4 | * @author gquintana
5 | */
6 | public final class DisabledLogTemplate extends LogTemplate {
7 |
8 | protected boolean isEnabled(C context) {
9 | return false;
10 | }
11 |
12 | protected void log(String message) {
13 | // Do nothing
14 | }
15 |
16 | private static final DisabledLogTemplate INSTANCE = new DisabledLogTemplate();
17 |
18 | public static DisabledLogTemplate getInstance() {
19 | //noinspection unchecked
20 | return INSTANCE;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/SimonState.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | /**
4 | * Status of monitor. While effective state can be either enabled or disabled, inner
5 | * state of monitor accepts one additional state - INHERIT, which means that effective
6 | * state will be inherited recursively from the parent.
7 | *
8 | * @author Richard "Virgo" Richter
9 | */
10 | public enum SimonState {
11 |
12 | /** Enabled. */
13 | ENABLED,
14 |
15 | /** Disabled. */
16 | DISABLED,
17 |
18 | /** Effective state (enabled/disabled) is going to be derived from the parent. */
19 | INHERIT,
20 | }
21 |
--------------------------------------------------------------------------------
/examples/testapp.db.sql:
--------------------------------------------------------------------------------
1 |
2 | drop table if exists tuple;
3 |
4 | create table tuple (
5 | unique1 integer not null,
6 | idx integer not null,
7 | one integer not null,
8 | ten integer not null,
9 | twenty integer not null,
10 | twentyfive integer not null,
11 | fifty integer not null,
12 | evenonepercent integer not null,
13 | oddonepercent integer not null,
14 | stringu1 varchar(24) not null,
15 | stringu2 varchar(24) not null,
16 | string4 varchar(24) not null,
17 | created date
18 | )
19 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/UnknownSample.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | /**
4 | * Sample produced by {@link UnknownSimon}s.
5 | *
6 | * @author gquintana
7 | * @since 3.2
8 | */
9 | public class UnknownSample extends Sample {
10 |
11 | /**
12 | * Returns readable representation of the sample object.
13 | *
14 | * @return string with readable representation of the sample
15 | */
16 | @Override
17 | public String toString() {
18 | return "UnknownSample" + "{name=" + getName() + ", note=" + getNote() + '}';
19 | }
20 |
21 | @Override
22 | public String simonToString() {
23 | return null;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToLongConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Long.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToLongConverter implements Converter {
9 |
10 | @Override
11 | public Long convert(Class> targetClass, String strVal) {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | try {
17 | return Long.parseLong(strVal);
18 | } catch (NumberFormatException ex) {
19 | throw new ConvertException(
20 | String.format("Cannot convert string '%s' to Long", strVal));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/jmx/custom/CustomStopwatchMXBean.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.examples.jmx.custom;
2 |
3 | import org.javasimon.jmx.StopwatchMXBean;
4 |
5 | /**
6 | * Custom extension to Stopwatch MX bean interface to provide values in millis.
7 | *
8 | * @author gquintana
9 | */
10 | public interface CustomStopwatchMXBean extends StopwatchMXBean {
11 |
12 | long getCounter();
13 |
14 | long getLastInMillis();
15 |
16 | long getMaxInMillis();
17 |
18 | double getMeanInMillis();
19 |
20 | long getMinInMillis();
21 |
22 | double getStandardDeviationInMillis();
23 |
24 | long getTotalInMillis();
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToFloatConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Float.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToFloatConverter implements Converter {
9 |
10 | @Override
11 | public Float convert(Class> targetClass, String strVal) throws ConvertException {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | try {
17 | return Float.parseFloat(strVal);
18 | } catch (NumberFormatException ex) {
19 | throw new ConvertException(String.format("Failed to parse '%s' to Float", strVal));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/test/resources/org/javasimon/test-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 5000 and split < 10us
8 | ]]>
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToByteConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Byte.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToByteConverter implements Converter {
9 |
10 | @Override
11 | public Byte convert(Class> targetClass, String strVal) throws ConvertException {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | try {
17 | return Byte.parseByte(strVal);
18 | } catch (NumberFormatException ex) {
19 | throw new ConvertException(
20 | String.format("Cannot convert string '%s' to Byte", strVal));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToDoubleConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Double.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToDoubleConverter implements Converter {
9 |
10 | @Override
11 | public Double convert(Class> targetClass, String strVal) throws ConvertException {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | try {
17 | return Double.parseDouble(strVal);
18 | } catch (NumberFormatException ex) {
19 | throw new ConvertException(String.format("Failed to parse '%s' to Double", strVal));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToShortConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Short.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToShortConverter implements Converter {
9 |
10 | @Override
11 | public Short convert(Class> targetClass, String strVal) throws ConvertException {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | try {
17 | return Short.parseShort(strVal);
18 | } catch (NumberFormatException ex) {
19 | throw new ConvertException(
20 | String.format("Cannot convert string '%s' to Short", strVal));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/Converter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Interface for converting string values to a values of a property in Java bean.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public interface Converter {
9 | /**
10 | * Converts string values to an object of a bean property.
11 | *
12 | * @param targetClass type of property
13 | * @param strVal value to convert
14 | * @return conversion result
15 | * @throws ConvertException in case if string value cannot be converted a target class
16 | */
17 | Object convert(Class> targetClass, String strVal) throws ConvertException;
18 | }
19 |
--------------------------------------------------------------------------------
/jdbc41/src/main/java/org/javasimon/jdbc4/SqlNormalizerFactory.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jdbc4;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Factory to create objects that provide simon key by SQL query
7 | */
8 | public interface SqlNormalizerFactory {
9 | /**
10 | * Create normalizer for single SQL query
11 | * @param sql query
12 | * @return normalizer
13 | */
14 | SqlNormalizer getNormalizer(String sql);
15 |
16 | /**
17 | * Create normalizer for batch query. Typically it should store "batch" in sql and type properties
18 | * @param batch list of batch queries
19 | * @return normalizer for batch queries
20 | */
21 | SqlNormalizer getNormalizer(List batch);
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToIntegerConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Integer.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToIntegerConverter implements Converter {
9 |
10 | @Override
11 | public Integer convert(Class> targetClass, String strVal) throws ConvertException {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | try {
17 | return Integer.parseInt(strVal);
18 | } catch (NumberFormatException ex) {
19 | throw new ConvertException(
20 | String.format("Cannot convert string '%s' to Integer", strVal));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/SimonFilter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | /**
4 | * Generic filter useful whenever Simons are filtered for some operation.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public interface SimonFilter {
9 |
10 | /** Filter accepting all Simons. */
11 | SimonFilter ACCEPT_ALL_FILTER = new SimonFilter() {
12 | @Override
13 | public boolean accept(Simon simon) {
14 | return true;
15 | }
16 | };
17 |
18 | /**
19 | * Checks whether current Simon should be used/considered.
20 | *
21 | * @param simon Simon to check
22 | * @return true if current Simon should be used, false otherwise
23 | */
24 | boolean accept(Simon simon);
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/async/Executor.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.async;
2 |
3 | import java.util.concurrent.Callable;
4 |
5 | /**
6 | * Executor is similar to {@link java.util.concurrent.Executor}
7 | * or {@link java.util.concurrent.ExecutorService} but simpler (only one method to implement).
8 | *
9 | * @param
10 | * @author gerald
11 | * @see Executors Implementations
12 | */
13 | public interface Executor {
14 |
15 | /**
16 | * Main method of the executor.
17 | *
18 | * @param callable Piece of code to execute
19 | * @return Result of the execution
20 | * @throws Throwable Raised when execution failed
21 | */
22 | T execute(Callable callable) throws Throwable;
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/timeline/TimelineSample.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.timeline;
2 |
3 | /**
4 | * Snapshot of timeline state
5 | *
6 | * @author gerald
7 | */
8 | public class TimelineSample
{
9 | private final int capacity;
10 | private final long width;
11 | private final TR[] timeRanges;
12 |
13 | public TimelineSample(int capacity, long width, TR[] timeRanges) {
14 | this.capacity = capacity;
15 | this.width = width;
16 | this.timeRanges = timeRanges;
17 | }
18 |
19 | public int getCapacity() {
20 | return capacity;
21 | }
22 |
23 | public long getWidth() {
24 | return width;
25 | }
26 |
27 | public TR[] getTimeRanges() {
28 | return timeRanges;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToBooleanConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Converter from String to Boolean.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToBooleanConverter implements Converter {
9 |
10 | @Override
11 | public Boolean convert(Class> targetClass, String strVal) throws ConvertException {
12 | if (strVal == null) {
13 | return null;
14 | }
15 |
16 | strVal = strVal.toLowerCase();
17 | if (strVal.equals("true")) {
18 | return true;
19 | } else if (strVal.equals("false")) {
20 | return false;
21 | } else {
22 | throw new ConvertException(String.format("Failed to parse '%s' as Boolean", strVal));
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/jdbc41/src/main/java/org/javasimon/jdbc4/SqlNormalizer.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jdbc4;
2 |
3 | /**
4 | * Interface that declares a normalizer: an object that accepts a query and returns a key that
5 | * can be used to treat same queries with different parameters as same query
6 | *
7 | * @author Anton Rybochkin
8 | * @since 4.2.0
9 | */
10 | public interface SqlNormalizer {
11 | /**
12 | * Get type of provided SQL query (SELECT, UPDATE, etc), "batch" for batch queries
13 | * @return SQL query type
14 | */
15 | String getType();
16 |
17 | /**
18 | * Get source SQL query
19 | * @return the query
20 | */
21 | String getSql();
22 |
23 | /**
24 | * Get preprocessed query
25 | * @return simon key
26 | */
27 | String getNormalizedSql();
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/source/CachedStopwatchSource.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.source;
2 |
3 | import org.javasimon.Split;
4 | import org.javasimon.Stopwatch;
5 |
6 | /**
7 | * Cached sources using {@link org.javasimon.Stopwatch} as monitors.
8 | *
9 | * @author Richard "Virgo" Richter
10 | * @since 3.4
11 | */
12 | public abstract class CachedStopwatchSource extends CachedMonitorSource implements StopwatchSource {
13 | public CachedStopwatchSource(StopwatchSource delegate) {
14 | super(delegate);
15 | }
16 |
17 | @Override
18 | public Split start(L location) {
19 | if (isMonitored(location)) {
20 | return getMonitor(location).start();
21 | }
22 | return Split.DISABLED;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/utils/bean/ToEnumConverter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | /**
4 | * Class for converting String values to an instance of an enum of the specified type.
5 | *
6 | * @author Ivan Mushketyk
7 | */
8 | public class ToEnumConverter implements Converter {
9 | @Override
10 | public Object convert(Class> tClass, String strVal) throws ConvertException {
11 | try {
12 | //noinspection unchecked,UnnecessaryLocalVariable
13 | Class uncheckedClass = tClass;
14 | return Enum.valueOf(uncheckedClass, strVal);
15 | } catch (IllegalArgumentException e) {
16 | throw new ConvertException(String.format("Failed to convert %s value to %s class", strVal, tClass.toString()), e);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/TimeFormatType.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console;
2 |
3 | /**
4 | * Strategies used to to display times.
5 | *
6 | * @author gquintana
7 | */
8 | // TODO reuse SimonUnit as possible
9 | public enum TimeFormatType {
10 |
11 | NANOSECOND(1L),
12 | MICROSECOND(1000L),
13 | MILLISECOND(1000000L),
14 | SECOND(1000000000L),
15 | AUTO(0L),;
16 |
17 | private final long longFactor;
18 | private final double doubleFactor;
19 |
20 | private TimeFormatType(long longFactor) {
21 | this.longFactor = longFactor;
22 | this.doubleFactor = (double) longFactor;
23 | }
24 |
25 | public double convert(double value) {
26 | return value / doubleFactor;
27 | }
28 |
29 | public long convert(long value) {
30 | return value / longFactor;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/quantiles/BucketsType.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.quantiles;
2 |
3 | import org.javasimon.Stopwatch;
4 |
5 | /** Enumeration of buckets types, used for configuration purposes. */
6 | public enum BucketsType {
7 | LINEAR() {
8 | public Buckets createBuckets(Stopwatch stopwatch, long min, long max, int bucketNb) {
9 | return new LinearBuckets(min, max, bucketNb);
10 | }
11 | },
12 | EXPONENTIAL() {
13 | public Buckets createBuckets(Stopwatch stopwatch, long min, long max, int bucketNb) {
14 | return new ExponentialBuckets(min, max, bucketNb);
15 | }
16 | };
17 |
18 | /** Factory method to create {@link Buckets}. */
19 | public abstract Buckets createBuckets(Stopwatch stopwatch, long min, long max, int bucketNb);
20 | }
21 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/source/StopwatchSource.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.source;
2 |
3 | import org.javasimon.Split;
4 | import org.javasimon.Stopwatch;
5 |
6 | /**
7 | * Stopwatch source is source that uses {@link org.javasimon.Stopwatch} as the monitor type.
8 | *
9 | * @author Richard "Virgo" Richter
10 | * @since 3.4
11 | */
12 | public interface StopwatchSource extends MonitorSource {
13 | /**
14 | * Convenient method to return split for the location or disabled split, if the location is not monitored.
15 | *
16 | * @param location location to be monitored
17 | * @return {@link Split} for the location or {Split#DISABLED} if the location is not monitored
18 | * @since 3.4
19 | */
20 | Split start(L location);
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/FilterCallback.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback;
2 |
3 | /**
4 | * FilterCallback extends {@link Callback} adding filtering capabilities. {@link FilterRule}s can be added to
5 | * the filter callback, these allow selective event propagation to sub-callback(s).
6 | *
7 | * @author Richard "Virgo" Richter
8 | */
9 | public interface FilterCallback extends Callback {
10 | /**
11 | * Adds the rule to the filter.
12 | *
13 | * @param type rule type (must, suffice, must-not)
14 | * @param condition further conditions of the rule
15 | * @param pattern Simon pattern
16 | * @param events event list (empty applies to all, can be omitted)
17 | */
18 | void addRule(FilterRule.Type type, String condition, String pattern, Event... events);
19 | }
20 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/action/ClearAction.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.action;
2 |
3 | import org.javasimon.console.Action;
4 | import org.javasimon.console.ActionContext;
5 | import org.javasimon.console.ActionException;
6 |
7 | import java.io.IOException;
8 |
9 | import javax.servlet.ServletException;
10 |
11 | /**
12 | * Action to clear the Simon manager and remove all Simons.
13 | *
14 | * @author gquintana
15 | */
16 | public class ClearAction extends Action {
17 |
18 | /** URI for clear action. */
19 | public static final String PATH = "/data/clear";
20 |
21 | public ClearAction(ActionContext context) {
22 | super(context);
23 | }
24 |
25 | @Override
26 | public void execute() throws ServletException, IOException, ActionException {
27 | getContext().getManager().clear();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/spring/src/main/java/org/javasimon/spring/SimonWebConfigurationBean.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.spring;
2 |
3 | import javax.servlet.ServletContext;
4 |
5 | import org.javasimon.utils.SimonUtils;
6 |
7 | import org.springframework.web.context.ServletContextAware;
8 |
9 | /**
10 | * {@link SimonConfigurationBean} with extended function - just pushes configured manager to the {@link ServletContext} attribute
11 | * {@link SimonUtils#MANAGER_SERVLET_CTX_ATTRIBUTE}.
12 | *
13 | * @author Richard "Virgo" Richter
14 | */
15 | public class SimonWebConfigurationBean extends SimonConfigurationBean implements ServletContextAware {
16 | @Override
17 | public void setServletContext(ServletContext servletContext) {
18 | servletContext.setAttribute(SimonUtils.MANAGER_SERVLET_CTX_ATTRIBUTE, getSimonManager());
19 | }
20 | }
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/ActionBinding.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console;
2 |
3 | /**
4 | * Interface describing the binding between an HTTP Request and an {@link Action}
5 | * @author gquintana
6 | */
7 | public interface ActionBinding {
8 | /**
9 | * Indicates whether this action binding is applicable for this action
10 | * context (=HTTP Request)
11 | * @param actionContext Action context
12 | * @return true if this binding is in charge of this request
13 | */
14 | public boolean supports(ActionContext actionContext);
15 | /**
16 | * Create an action of this action context, this method will be
17 | * called only if this binding {@link #supports} this context.
18 | * @param actionContext Action context
19 | * @return New instance of an action
20 | */
21 | public T create(ActionContext actionContext);
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/clock/SimonUnit.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.clock;
2 |
3 | /**
4 | * Units typically used in Java Simon with amount of nanoseconds they contain.
5 | */
6 | public enum SimonUnit {
7 |
8 | NANOSECOND("ns", 1),
9 | MICROSECOND("μs", 1000),
10 | MILLISECOND("ms", 1000_000),
11 | SECOND("s", 1000_000_000);
12 |
13 | private String symbol;
14 | private int divisor;
15 |
16 | SimonUnit(String symbol, int divisor) {
17 | this.symbol = symbol;
18 | this.divisor = divisor;
19 | }
20 |
21 | /**
22 | * Returns the symbol of time unit.
23 | *
24 | * @return symbol of time unit
25 | */
26 | public String getSymbol() {
27 | return symbol;
28 | }
29 |
30 | /**
31 | * Returns number of nanoseconds in this unit.
32 | *
33 | * @return number of nanoseconds in this unit
34 | */
35 | public int getDivisor() {
36 | return divisor;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/utils/bean/ToStringConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | import org.javasimon.SimonUnitTest;
4 | import org.testng.Assert;
5 | import org.testng.annotations.DataProvider;
6 | import org.testng.annotations.Test;
7 |
8 | /**
9 | * @author Ivan Mushketyk
10 | */
11 | public class ToStringConverterTest extends SimonUnitTest {
12 |
13 | private ToStringConverter toStringConverter = new ToStringConverter();
14 |
15 | @DataProvider(name = "stringConverter")
16 | public Object[][] stringConverterProvider() {
17 | return new Object[][]{
18 | {"str", "str"},
19 | {null, null}
20 | };
21 | }
22 |
23 | @Test(dataProvider = "stringConverter")
24 | public void testToStringConverter(String src, String expectedStr) {
25 | Assert.assertEquals(toStringConverter.convert(String.class, src), expectedStr);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/LoopingRandomMethod.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.examples;
2 |
3 | import org.javasimon.SimonManager;
4 | import org.javasimon.Split;
5 | import org.javasimon.Stopwatch;
6 |
7 | /**
8 | * Simple example of the measuring a method in a loop. Method takes random time to finish.
9 | */
10 | public final class LoopingRandomMethod {
11 | /**
12 | * Entry point to the Example.
13 | *
14 | * @param args unused
15 | */
16 | public static void main(String[] args) {
17 | Stopwatch stopwatch = SimonManager.getStopwatch("stopwatch");
18 | for (int i = 1; i <= 10; i++) {
19 | try (Split ignored = SimonManager.getStopwatch("stopwatch").start()) {
20 | ExampleUtils.waitRandomlySquared(50);
21 | }
22 | System.out.println("Stopwatch after round " + i + ": " + stopwatch);
23 | }
24 | System.out.println("stopwatch.sample() = " + stopwatch.sample());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/action/CsvStringifierFactory.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.action;
2 |
3 | import org.javasimon.console.text.BaseStringifier;
4 | import org.javasimon.console.text.Stringifier;
5 | import org.javasimon.console.text.StringifierFactory;
6 |
7 | /**
8 | * Value formatter for CSV response format.
9 | *
10 | * @author gquintana
11 | */
12 | public class CsvStringifierFactory extends StringifierFactory {
13 |
14 | @Override
15 | protected Stringifier registerStringStringifier(Stringifier nullStringifier) {
16 | Stringifier stringStringifier = new BaseStringifier(nullStringifier) {
17 | @Override
18 | protected String doToString(String s) {
19 | return "\"" + s.replace("\"", "\"\"") + "\"";
20 | }
21 | };
22 | compositeStringifier.add(String.class, stringStringifier);
23 | return stringStringifier;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/text/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Machinery to convert potentially anything to a String (said differently a configurable toString() API).
3 | * The {@link org.javasimon.console.text.CompositeStringifier} is a dictionary which registers
4 | * a {@link org.javasimon.console.text.Stringifier} implementation for each Java type (String, Long, etc).
5 | * A given Java type can:
6 | *
7 | *
Have different meanings (a long can be
8 | * a duration, a timestamp, a counter, etc): the "sub-type" concept was introduced.
9 | *
Be styled differently (HTML, CSV, XML, JSON, etc): a dictionary factory was introduced
10 | * {@link org.javasimon.console.text.StringifierFactory} and its subclasses
11 | * {@link org.javasimon.console.action.CsvStringifierFactory}, {@link org.javasimon.console.json.JsonStringifierFactory}, etc.
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/logging/LogTemplate.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.logging;
2 |
3 | /**
4 | * Log template class is the root of a hierarchy of implementations with different purposes.
5 | *
6 | * @author gquintana
7 | */
8 | public abstract class LogTemplate {
9 |
10 | /**
11 | * If enabled, logs the message for context.
12 | *
13 | * @param context Context
14 | * @param messageSource Message producer
15 | * @return true if logging is enabled, false otherwise
16 | */
17 | public final boolean log(C context, LogMessageSource messageSource) {
18 | final boolean enabled = isEnabled(context);
19 | if (enabled) {
20 | log(messageSource.getLogMessage(context));
21 | }
22 | return enabled;
23 | }
24 |
25 | /**
26 | * Tells whether logging is enabled.
27 | *
28 | * @return Logging enabled
29 | */
30 | protected abstract boolean isEnabled(C context);
31 |
32 | /** Logs a message. */
33 | protected abstract void log(String message);
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/logging/DelegateLogTemplate.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.logging;
2 |
3 | /**
4 | * Base class for log template which delegates part of the work to a concrete log template.
5 | *
6 | * @author gquintana
7 | */
8 | public abstract class DelegateLogTemplate extends LogTemplate {
9 |
10 | /** Delegate log template. */
11 | private final LogTemplate delegate;
12 |
13 | /**
14 | * Constructor with delegate log template.
15 | *
16 | * @param delegate delegate log template
17 | */
18 | public DelegateLogTemplate(LogTemplate delegate) {
19 | this.delegate = delegate;
20 | }
21 |
22 | /**
23 | * Get delegate log template.
24 | *
25 | * @return Delegate log template
26 | */
27 | public LogTemplate getDelegate() {
28 | return delegate;
29 | }
30 |
31 | protected boolean isEnabled(C context) {
32 | return delegate.isEnabled(context);
33 | }
34 |
35 | protected void log(String message) {
36 | delegate.log(message);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/utils/ReplacerTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils;
2 |
3 | import static org.testng.Assert.*;
4 |
5 | import org.testng.annotations.Test;
6 |
7 | public class ReplacerTest {
8 |
9 | @Test(timeOut = 100)
10 | public void nonRepeatingReplacerMakesSinglePass() {
11 | Replacer replacer = new Replacer("AA", "A");
12 | assertEquals(replacer.process("AAAA"), "AA");
13 | }
14 |
15 | @Test(timeOut = 100)
16 | public void repeatingReplacerReducesStringCompletely() {
17 | Replacer replacer = new Replacer("AA", "A", Replacer.Modificator.REPEAT_UNTIL_UNCHANGED);
18 | assertEquals(replacer.process("AAAA"), "A");
19 | }
20 |
21 | @Test(timeOut = 100)
22 | public void replacerIsCaseSensitiveByDefault() {
23 | Replacer replacer = new Replacer("AA", "A");
24 | assertEquals(replacer.process("aaaa"), "aaaa");
25 | }
26 |
27 | @Test(timeOut = 100)
28 | public void replacerIgnoresCaseWithModificator() {
29 | Replacer replacer = new Replacer("AA", "A", Replacer.Modificator.IGNORE_CASE);
30 | assertEquals(replacer.process("aaaa"), "AA");
31 | }
32 | }
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/text/NoneStringifier.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.text;
2 |
3 | /**
4 | * Stringifier with particular meaning: do not stringify this value.
5 | * @author gquintana
6 | */
7 | public class NoneStringifier implements Stringifier {
8 | private NoneStringifier() {
9 | }
10 | public String toString(T value) {
11 | throw new UnsupportedOperationException("Do not stringify");
12 | }
13 | private static final NoneStringifier INSTANCE=new NoneStringifier();
14 | /**
15 | * Get unique instance of the NoneStringifier
16 | */
17 | public static NoneStringifier getInstance() {
18 | return (NoneStringifier) INSTANCE;
19 | }
20 | /**
21 | * Check whether stringifier is the NoneStringifier
22 | * @param stringifier Stringifier to compare with NoneStringifier
23 | * @return null when stringifier==NoneStringifier, else given stringifier
24 | */
25 | public static Stringifier checkInstance(Stringifier stringifier) {
26 | return INSTANCE==stringifier?null:stringifier;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/SimonException.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | /**
4 | * SimonException is runtime exception thrown in case something goes seriously wrong (class cast or similar).
5 | *
6 | * @author Richard "Virgo" Richter
7 | */
8 | public final class SimonException extends RuntimeException {
9 |
10 | /**
11 | * Creates SimonException with the message.
12 | *
13 | * @param message exception message
14 | */
15 | public SimonException(String message) {
16 | super(message);
17 | }
18 |
19 | /**
20 | * Creates SimonException with the chained exception causing this exception.
21 | *
22 | * @param cause chained exception
23 | */
24 | public SimonException(Throwable cause) {
25 | super(cause);
26 | }
27 |
28 | /**
29 | * Creates SimonException with message and the chained exception causing this exception.
30 | *
31 | * @param message exception message
32 | * @param cause chained exception
33 | */
34 | public SimonException(String message, Throwable cause) {
35 | super(message, cause);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/source/DisabledMonitorSource.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.source;
2 |
3 | import org.javasimon.Manager;
4 | import org.javasimon.Simon;
5 |
6 | /**
7 | * Disabled monitor source.
8 | *
9 | * @author gquintana
10 | */
11 | public class DisabledMonitorSource implements MonitorSource {
12 | /**
13 | * Singleton instance.
14 | */
15 | private static final DisabledMonitorSource INSTANCE = new DisabledMonitorSource();
16 |
17 | /**
18 | * Returns a singleton instance.
19 | */
20 | @SuppressWarnings("unchecked")
21 | public static DisabledMonitorSource get() {
22 | return (DisabledMonitorSource) INSTANCE;
23 | }
24 |
25 | /**
26 | * Always returns null.
27 | */
28 | public M getMonitor(L location) {
29 | return null;
30 | }
31 |
32 | /**
33 | * Always returns false.
34 | */
35 | public boolean isMonitored(L location) {
36 | return false;
37 | }
38 |
39 | @Override
40 | public Manager getManager() {
41 | return null;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/clock/TestClock.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.clock;
2 |
3 | /**
4 | * TestClock allows setting any arbitrary values for millis and nanos.
5 | * Available for non-test code too, if for nothing else then it's easier to use in tests in other modules too.
6 | *
7 | * @since 3.5
8 | */
9 | public final class TestClock implements SimonClock {
10 |
11 | private long millis;
12 | private long nanos;
13 |
14 | @Override
15 | public long nanoTime() {
16 | return nanos;
17 | }
18 |
19 | @Override
20 | public long milliTime() {
21 | return millis;
22 | }
23 |
24 | /** Here millis are simply nanos divided by {@link SimonClock#NANOS_IN_MILLIS}. */
25 | @Override
26 | public long millisForNano(long nanos) {
27 | return nanos / NANOS_IN_MILLIS;
28 | }
29 |
30 | public void setMillis(long millis) {
31 | this.millis = millis;
32 | }
33 |
34 | public void setNanos(long nanos) {
35 | this.nanos = nanos;
36 | }
37 |
38 | public void setMillisNanosFollow(long millis) {
39 | this.millis = millis;
40 | this.nanos = millis * NANOS_IN_MILLIS;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/demoapp/src/main/webapp/demo.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size:10px;
3 | }
4 |
5 | .error {
6 | color: red;
7 | }
8 |
9 | .sidebar {
10 | position: absolute;
11 | width: 10%;
12 | font: 14px 'Helvetica';
13 | }
14 |
15 | .sidebar h2 {
16 | font-size: 20px;
17 | }
18 |
19 | .content {
20 | width: 60%;
21 | margin-left: 20%;
22 | }
23 |
24 | .content h1 {
25 | font-size: 25px;
26 | }
27 |
28 | #toDoTable {
29 | border-collapse: collapse;
30 | margin: 10px;
31 | }
32 |
33 | .col {
34 | color: #000088;
35 | font-size: 14px;
36 | font-weight: normal;
37 | padding: 15px 10px 10px;
38 | }
39 |
40 | #toDoTable tbody {
41 | background: none repeat scroll 0 0 #E8EDFF;
42 | }
43 |
44 | #toDoTable th {
45 | border-bottom: 2px solid #4433FF;
46 | color: #000088;
47 | font-size: 14px;
48 | font-weight: normal;
49 | padding: 10px 8px;
50 | }
51 |
52 | #toDoList tr:hover {
53 | background: none repeat scroll 0 0 #D6DBEE;
54 | }
55 |
56 | #toDoTable td {
57 | border-top: 1px solid #3727e8;
58 | padding: 10px;
59 | }
60 |
61 |
62 |
--------------------------------------------------------------------------------
/javaee/src/main/java/org/javasimon/javaee/reqreporter/ReporterStopwatchInfo.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.javaee.reqreporter;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.javasimon.Split;
7 | import org.javasimon.Stopwatch;
8 |
9 | /**
10 | * Contains cummulated information about about single {@link Stopwatch} with all its reported {@link Split}s.
11 | * Naturally comparable by total time descending.
12 | */
13 | public class ReporterStopwatchInfo implements Comparable {
14 | Stopwatch stopwatch;
15 | List splits = new ArrayList<>();
16 | Split maxSplit;
17 | long total;
18 |
19 | ReporterStopwatchInfo(Stopwatch stopwatch) {
20 | this.stopwatch = stopwatch;
21 | }
22 |
23 | @Override
24 | public int compareTo(ReporterStopwatchInfo o) {
25 | return total < o.total ? 1 : total == o.total ? 0 : -1;
26 | }
27 |
28 | public void addSplit(Split split) {
29 | splits.add(split);
30 | long runningFor = split.runningFor();
31 | if (maxSplit == null || runningFor > maxSplit.runningFor()) {
32 | maxSplit = split;
33 | }
34 | total += runningFor;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/SimonType.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console;
2 |
3 | import org.javasimon.Counter;
4 | import org.javasimon.CounterSample;
5 | import org.javasimon.Sample;
6 | import org.javasimon.Simon;
7 | import org.javasimon.Stopwatch;
8 | import org.javasimon.StopwatchSample;
9 | import org.javasimon.UnknownSample;
10 |
11 | /**
12 | * Simon type enumeration
13 | *
14 | * @author gquintana
15 | */
16 | public enum SimonType {
17 |
18 | STOPWATCH(Stopwatch.class, StopwatchSample.class), COUNTER(Counter.class, CounterSample.class), UNKNOWN(Simon.class, UnknownSample.class);
19 | /**
20 | * Simon Interface
21 | */
22 | private final Class extends Simon> type;
23 | /**
24 | * Sample interface
25 | */
26 | private final Class extends Sample> sampleType;
27 |
28 | private SimonType(Class extends Simon> type, Class extends Sample> sampleType) {
29 | this.type = type;
30 | this.sampleType = sampleType;
31 | }
32 |
33 | public Class extends Simon> getType() {
34 | return type;
35 | }
36 |
37 | public Class extends Sample> getSampleType() {
38 | return sampleType;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/action/RedirectAction.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.action;
2 |
3 | import org.javasimon.console.Action;
4 | import org.javasimon.console.ActionContext;
5 | import org.javasimon.console.ActionException;
6 |
7 | import java.io.IOException;
8 |
9 | import javax.servlet.ServletException;
10 |
11 | /**
12 | * Action to send a redirect instruction to the browser.
13 | *
14 | * @author gquintana
15 | */
16 | public class RedirectAction extends Action {
17 |
18 | /** Target URL. */
19 | private String target;
20 |
21 | public RedirectAction(ActionContext context) {
22 | super(context);
23 | }
24 |
25 | public RedirectAction(String target, ActionContext context) {
26 | super(context);
27 | this.target = target;
28 | }
29 |
30 | public String getTarget() {
31 | return target;
32 | }
33 |
34 | public void setTarget(String target) {
35 | this.target = target;
36 | }
37 |
38 | @Override
39 | public void execute() throws ServletException, IOException, ActionException {
40 | getContext().getResponse().sendRedirect(target);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/jdbc41/src/main/java/org/javasimon/jdbc4/WrapperSupport.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jdbc4;
2 |
3 | import java.sql.SQLException;
4 | import java.sql.Wrapper;
5 |
6 | /**
7 | * Helper class for implementing {@link Wrapper} on wrappers.
8 | *
9 | * @param delegate type
10 | * @author gquintana
11 | */
12 | public final class WrapperSupport implements Wrapper {
13 | /**
14 | * Delegate instance.
15 | */
16 | private final D delegate;
17 |
18 | /**
19 | * Interface implemented by delegate.
20 | */
21 | private final Class delegateType;
22 |
23 | public WrapperSupport(D delegate, Class delegateType) {
24 | this.delegate = delegate;
25 | this.delegateType = delegateType;
26 | }
27 |
28 | public boolean isWrapperFor(Class> iface) throws SQLException {
29 | return delegateType.equals(iface) || delegate.isWrapperFor(iface);
30 | }
31 |
32 | public T unwrap(Class iface) throws SQLException {
33 | if (delegateType.equals(iface)) {
34 | return delegate.isWrapperFor(iface) ? delegate.unwrap(iface) : iface.cast(delegate);
35 | } else {
36 | return delegate.unwrap(iface);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javaee/src/main/java/org/javasimon/javaee/reqreporter/RequestReporter.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.javaee.reqreporter;
2 |
3 | import java.util.List;
4 | import javax.servlet.http.HttpServletRequest;
5 |
6 | import org.javasimon.Split;
7 | import org.javasimon.javaee.SimonServletFilter;
8 |
9 | /**
10 | * RequestReporter interface .
11 | *
12 | * @author Richard "Virgo" Richter
13 | */
14 | public interface RequestReporter {
15 | /**
16 | * Reports request that exceeds the threshold.
17 | *
18 | * @param request offending HTTP request
19 | * @param requestSplit split measuring the offending request
20 | * @param splits list of all splits started for this request
21 | */
22 | void reportRequest(HttpServletRequest request, Split requestSplit, List splits);
23 |
24 | /**
25 | * Called by initialization after the instance creation. Useful when {@link org.javasimon.Manager} is needed
26 | * ({@link org.javasimon.javaee.SimonServletFilter#getManager()}) and possibly for other scenarios.
27 | */
28 | void setSimonServletFilter(SimonServletFilter simonServletFilter);
29 | }
30 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/source/DisabledStopwatchSource.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.source;
2 |
3 | import org.javasimon.Manager;
4 | import org.javasimon.Split;
5 | import org.javasimon.Stopwatch;
6 |
7 | /**
8 | * Disabled stopwatch source.
9 | *
10 | * @author Richard "Virgo" Richter
11 | * @since 3.4
12 | */
13 | public class DisabledStopwatchSource implements StopwatchSource {
14 | /**
15 | * Singleton instance.
16 | */
17 | private static final DisabledStopwatchSource INSTANCE = new DisabledStopwatchSource();
18 |
19 | /**
20 | * Returns a singleton instance.
21 | */
22 | @SuppressWarnings("unchecked")
23 | public static DisabledStopwatchSource get() {
24 | return (DisabledStopwatchSource) INSTANCE;
25 | }
26 |
27 | @Override
28 | public Split start(L location) {
29 | return Split.DISABLED;
30 | }
31 |
32 | @Override
33 | public boolean isMonitored(L location) {
34 | return false;
35 | }
36 |
37 | @Override
38 | public Stopwatch getMonitor(L location) {
39 | return null;
40 | }
41 |
42 | @Override
43 | public Manager getManager() {
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/source/MonitorSource.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.source;
2 |
3 | import org.javasimon.Manager;
4 | import org.javasimon.Simon;
5 |
6 | /**
7 | * Monitor source provides monitors (Simons) for a specific "location" name. This mechanism enables
8 | * caching of monitors for "locations" that do not change but may be expensive to transform to
9 | * Simon names, for instance.
10 | *
11 | * @param Location/invocation context/name
12 | * @param Simon type
13 | * @author gquintana
14 | */
15 | public interface MonitorSource {
16 | /**
17 | * Indicates whether given location should be monitored or not.
18 | *
19 | * @param location Location
20 | * @return true means monitored
21 | */
22 | boolean isMonitored(L location);
23 |
24 | /**
25 | * Returns the monitor for given location.
26 | *
27 | * @param location Location
28 | * @return Monitor
29 | */
30 | M getMonitor(L location);
31 |
32 | /**
33 | * Returns the {@link Manager} used as a real source of monitors.
34 | *
35 | * @return Manager to get the monitors from
36 | */
37 | Manager getManager();
38 | }
39 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/SimonConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | /**
4 | * Stores configuration for the particular Simon or the set of Simons.
5 | * Currently it holds only the state of the Simon.
6 | *
7 | * @author Richard "Virgo" Richter
8 | */
9 | public final class SimonConfiguration {
10 | private SimonState state;
11 |
12 | /**
13 | * Creates SimonConfiguration item.
14 | *
15 | * @param state preferred state - SimonManager sets inherit if null is specified here
16 | */
17 | SimonConfiguration(SimonState state) {
18 | this.state = state;
19 | }
20 |
21 | /**
22 | * Returns Simon state for this configuration item.
23 | *
24 | * @return configured Simon state or null if nothing was specified
25 | */
26 | public SimonState getState() {
27 | return state;
28 | }
29 |
30 | /**
31 | * Returns configuration information about Simon (stat processor type and state) as a human readable string.
32 | *
33 | * @return configuration information about Simon as string
34 | */
35 | @Override
36 | public String toString() {
37 | return "SimonConfiguration {\n" +
38 | " state=" + state + "\n" +
39 | "}";
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/demoapp/src/main/resources/org/javasimon/console/resource/js/javasimon-customization.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var javasimon=window.javasimon||{};
3 | window.javasimon=javasimon;
4 |
5 | $.getScript("resource/js/javasimon-util.js", function(data, textStatus, jqxhr) {
6 | console.log("javasimon-utils were loaded");
7 | });
8 |
9 | javasimon.onTableData = function(json, timeUnit) {
10 | $.each(json, function(index, sample) {
11 | var $sampleRow = javasimon.DOMUtil.fnGetSampleRow(sample.name);
12 | var maxTime = javasimon.TimeUtils.toMillis(sample.max, timeUnit);
13 | if (maxTime > 20) {
14 | $sampleRow.css('background-color','#ff8888');
15 | }
16 | });
17 | };
18 |
19 | function isLeaf(treeElement) {
20 | return treeElement.bHasChildren === false;
21 | }
22 |
23 | javasimon.onTreeElementDrawn = function(treeElement, timeUnit) {
24 | if (isLeaf(treeElement)) {
25 | var $sampleRow = javasimon.DOMUtil.fnGetSampleRow(treeElement.oData.name);
26 | var maxTime = javasimon.TimeUtils.toMillis(treeElement.oData.max, timeUnit);
27 | if (maxTime > 20) {
28 | $sampleRow.css('background-color','#ff8888');
29 | }
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/utils/bean/ToEnumCoverterTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | import org.javasimon.SimonUnitTest;
4 | import org.testng.Assert;
5 | import org.testng.annotations.DataProvider;
6 | import org.testng.annotations.Test;
7 |
8 | /**
9 | * @author Ivan Mushketyk
10 | */
11 | public class ToEnumCoverterTest extends SimonUnitTest {
12 |
13 | private ToEnumConverter enumCoverter = new ToEnumConverter();
14 |
15 | private static enum TestEnum {
16 | VAL1,
17 | VAL2,
18 | VAL3
19 | }
20 |
21 | @DataProvider(name = "enumConversion")
22 | Object[][] enumConversionDataProvider() {
23 | return new Object[][]{
24 | {"VAL1", TestEnum.VAL1},
25 | {"VAL2", TestEnum.VAL2},
26 | {"VAL3", TestEnum.VAL3},
27 | };
28 | }
29 |
30 | @Test(dataProvider = "enumConversion")
31 | public void testEnumConversion(String valStr, TestEnum enumVal) {
32 | Assert.assertEquals(enumCoverter.convert(TestEnum.class, valStr), enumVal);
33 | }
34 |
35 | @Test(expectedExceptions = ConvertException.class)
36 | public void testNonExistingEnumValConversion() {
37 | enumCoverter.convert(TestEnum.class, "SOME_NON_EXISTING_ENUM_VAL");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/callback/quantiles/BucketSample.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.callback.quantiles;
2 |
3 | /**
4 | * {@link Bucket} sample.
5 | *
6 | * @author gquintana
7 | * @since 3.3
8 | */
9 | public final class BucketSample {
10 |
11 | /** Minimal value. */
12 | private final long min;
13 | /** Maximal value. */
14 | private final long max;
15 | /** Number of values in the range min-max. */
16 | private final int count;
17 |
18 | /**
19 | * Constructor with min/max value specified.
20 | *
21 | * @param min min value
22 | * @param max max value
23 | */
24 | public BucketSample(long min, long max, int count) {
25 | this.min = min;
26 | this.max = max;
27 | this.count = count;
28 | }
29 |
30 | /**
31 | * Get number of values in the range.
32 | *
33 | * @return number of value in the range
34 | */
35 | public int getCount() {
36 | return count;
37 | }
38 |
39 | /**
40 | * Get upper bound of the range.
41 | *
42 | * @return max value
43 | */
44 | public long getMax() {
45 | return max;
46 | }
47 |
48 | /**
49 | * Get lower bound of the range.
50 | *
51 | * @return min value
52 | */
53 | public long getMin() {
54 | return min;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/spring/src/main/java/org/javasimon/spring/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Support classes to automatically monitor Spring beans with the {@link org.javasimon.aop.Monitored} annotation.
3 | *
4 | *
Usage instructions:
5 | *
6 | *
Step -1- Make sure the Spring configuration file {@code org/javasimon/spring/monitoring.xml} is loaded as one
7 | * of the first configuration files.
8 | *
9 | *
For example, if you use the {@code org.springframework.web.context.ContextLoaderListener} in your
10 | * {@code web.xml}, the {@code contextConfigLocation} context parameter will look something like this:
11 | *
11 | * Callback tree has no correlation with Simon tree in the {@link org.javasimon.Manager}).
12 | *
13 | * @author Richard "Virgo" Richter
14 | * @since 3.2
15 | */
16 | public interface CompositeCallback extends Callback {
17 |
18 | /**
19 | * Returns the list of all child-callbacks.
20 | *
21 | * @return children list
22 | */
23 | List callbacks();
24 |
25 | /**
26 | * Adds another callback as a child to this callback.
27 | *
28 | * @param callback added callback
29 | */
30 | void addCallback(Callback callback);
31 |
32 | /**
33 | * Removes specified callback from this callback.
34 | *
35 | * @param callback removed child-callback
36 | */
37 | void removeCallback(Callback callback);
38 |
39 | /** Removes all callbacks from this callback. */
40 | void removeAllCallbacks();
41 | }
42 |
--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/jmx/custom/CustomJmxRegisterCallback.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.examples.jmx.custom;
2 |
3 | import javax.management.MBeanServer;
4 |
5 | import org.javasimon.Simon;
6 | import org.javasimon.Stopwatch;
7 | import org.javasimon.jmx.JmxRegisterCallback;
8 | import org.javasimon.jmx.SimonSuperMXBean;
9 |
10 | /**
11 | * Customized JMX register callback.
12 | * Register CustomStopwatchMXBeanImpl instead of usual StopwatchMXBeanImpl.
13 | *
14 | * @author Gerald Quintana
15 | */
16 | public class CustomJmxRegisterCallback extends JmxRegisterCallback {
17 | private static final String DOMAIN = "com.mycompany.myapp";
18 |
19 | public CustomJmxRegisterCallback(MBeanServer mBeanServer) {
20 | super(mBeanServer, "com.mycompany.myapp");
21 | }
22 |
23 | public CustomJmxRegisterCallback() {
24 | super(DOMAIN);
25 | }
26 |
27 | @Override
28 | protected SimonSuperMXBean constructObject(Simon simon) {
29 | if (simon instanceof Stopwatch) {
30 | return new CustomStopwatchMXBeanImpl((Stopwatch) simon);
31 | } else {
32 | return super.constructObject(simon);
33 | }
34 | }
35 |
36 | @Override
37 | protected String constructObjectName(Simon simon) {
38 | return domain + ":type=Simon,kind=" + simonType(simon) + ",name=" + simon.getName();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/source/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * {@link org.javasimon.source.MonitorSource} is the interface used as function to transform execution context (method invocation,
3 | * HTTP request...) into a Simon. Following subtypes are provided:
4 | *
5 | *
{@link org.javasimon.source.CachedMonitorSource} - abstract implementation which acts as a cache for excutation context to Simon conversion.
6 | *
{@link org.javasimon.source.DisabledMonitorSource} - implementation to disable monitoring at interceptor level (produces null Simons).
7 | *
{@code org.javasimon.javaee.HttpStopwatchSource} (in javaee module) - used by servlet filter to get the Simon associated with a HTTP request.
8 | *
{@link org.javasimon.source.AbstractMethodStopwatchSource} - abstract used for method invocation contexts:
9 | *
10 | *
{@code org.javasimon.spring.SpringStopwatchSource} (in spring module) - used by the Spring AOP interceptor to get Stopwatch names from
11 | * {@link org.javasimon.aop.Monitored} interfaces;
12 | *
{@code org.javasimon.source.MethodStopwatchSource} (in javee module) - used by the JavaEE interceptor to get Stopwatch names
13 | * from EJBs/CDI beans;
14 | *
{@link org.javasimon.proxy.ProxyStopwatchSource} - used by the Proxy to get Stopwatch names.
15 | *
16 | *
17 | */
18 | package org.javasimon.source;
--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/ClockExample.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.examples;
2 |
3 | import org.javasimon.SimonManager;
4 | import org.javasimon.Split;
5 | import org.javasimon.clock.SimonClock;
6 |
7 | /**
8 | * This example shows how different Clock sources for Splits affect the measured values.
9 | * Using {@link Split} with {@link SimonClock#CPU} is quick way to measure real CPU time (as real as it is for JVM).
10 | * Obviously - one should not stop such a split in different thread than it was started, because
11 | * it may be based on timers/counters valid for a single thread.
12 | */
13 | public class ClockExample {
14 |
15 | public static void main(String[] args) throws InterruptedException {
16 | String stopwatchName = "stopwatch";
17 |
18 | Split cpuSplit = Split.start(SimonClock.CPU);
19 | Split systemSplit = Split.start();
20 |
21 | System.out.println("cpuSplit = " + cpuSplit);
22 | System.out.println("systemSplit = " + systemSplit);
23 |
24 | for (int loop = 0; loop < 10; loop++) {
25 | for (int i = 0; i < 1000000; i++) {
26 | SimonManager.getStopwatch(stopwatchName);
27 | }
28 | Thread.sleep(200); // this should cause roughly 200 ms difference on each loop
29 | System.out.println("\nAfter iteration #" + loop);
30 | System.out.println("cpuSplit = " + cpuSplit);
31 | System.out.println("systemSplit = " + systemSplit);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/perf/CircularListAddPerfromance.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.examples.perf;
2 |
3 | import org.javasimon.SimonManager;
4 | import org.javasimon.Split;
5 | import org.javasimon.Stopwatch;
6 | import org.javasimon.callback.lastsplits.CircularList;
7 |
8 | import java.util.LinkedList;
9 | import java.util.List;
10 |
11 | /**
12 | *
13 | * @author gquintana
14 | * @author Ivan Mushketyk
15 | */
16 | public class CircularListAddPerfromance {
17 |
18 | public static final int ITERATIONS = 1000000;
19 |
20 | public static void main(String... args) {
21 | List circularList = new CircularList<>(10);
22 | Stopwatch stopwatch = SimonManager.getStopwatch(CircularListAddPerfromance.class.getName() + ".testAddPerformance");
23 | Split split = stopwatch.start();
24 | for (int i = 0; i < ITERATIONS; i++) {
25 | circularList.add(i);
26 | }
27 | long circular = split.stop().runningFor();
28 | LinkedList linkedList = new LinkedList<>();
29 | split = stopwatch.start();
30 | for (int i = 0; i < ITERATIONS; i++) {
31 | linkedList.add(i);
32 | if (linkedList.size() > 10) {
33 | linkedList.removeFirst();
34 | }
35 | }
36 | long linked = split.stop().runningFor();
37 | System.out.println("Circular " + circular + " /Linked " + linked + " " + ((linked - circular) * 100 / circular) + "%");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/text/BaseStringifier.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.text;
2 |
3 | /**
4 | * Basic value formatter.
5 | * Handles null value delegating to a null Stringifier.
6 | *
7 | * @param Input type
8 | * @author gquintana
9 | */
10 | public class BaseStringifier implements Stringifier {
11 |
12 | /** Stringifier to handle null values. */
13 | private final Stringifier nullStringifier;
14 |
15 | /**
16 | * Constructor.
17 | *
18 | * @param nullStringifier Stringifier to handle null values
19 | */
20 | public BaseStringifier(Stringifier nullStringifier) {
21 | this.nullStringifier = nullStringifier;
22 | }
23 |
24 | /**
25 | * Check whether input value should be considered as null
26 | *
27 | * @param object Input value
28 | * @return Null-style
29 | */
30 | protected boolean isValid(T object) {
31 | return object != null;
32 | }
33 |
34 | @Override
35 | public final String toString(T object) {
36 | return isValid(object) ? doToString(object) : nullToString();
37 | }
38 |
39 | /** Converts null input value to string. */
40 | @SuppressWarnings("unchecked")
41 | protected final String nullToString() {
42 | return nullStringifier.toString(null);
43 | }
44 |
45 | /** Converts not null input value to string. */
46 | protected String doToString(T object) {
47 | return object.toString();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/utils/bean/ToDoubleConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.utils.bean;
2 |
3 | import org.javasimon.SimonUnitTest;
4 | import org.testng.Assert;
5 | import org.testng.annotations.DataProvider;
6 | import org.testng.annotations.Test;
7 |
8 | /**
9 | * @author Ivan Mushketyk
10 | */
11 | public class ToDoubleConverterTest extends SimonUnitTest {
12 |
13 | private ToDoubleConverter toDoubleConverter = new ToDoubleConverter();
14 |
15 | @DataProvider(name = "validValues")
16 | public Object[][] validValues() {
17 | return new Object[][]{
18 | {"123.456", 123.456},
19 | {"12", 12.0}
20 | };
21 | }
22 |
23 | @Test(dataProvider = "validValues")
24 | public void testConvertValidValues(String from, Double expectedDouble) {
25 | Assert.assertEquals(toDoubleConverter.convert(Double.class, from), expectedDouble, 0.00001);
26 | }
27 |
28 | @Test
29 | public void testNullConvertedToNull() {
30 | Assert.assertEquals(toDoubleConverter.convert(Double.class, null), null);
31 | }
32 |
33 | @DataProvider(name = "invalidValues")
34 | public Object[][] invalidValues() {
35 | return new Object[][]{
36 | {"str"}
37 | };
38 | }
39 |
40 | @Test(dataProvider = "invalidValues", expectedExceptions = {ConvertException.class})
41 | public void testConvertInvalidValues(String invalidVal) {
42 | toDoubleConverter.convert(Double.class, invalidVal);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/examples/src/main/java/org/javasimon/examples/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.examples;
2 |
3 | import org.javasimon.SimonManager;
4 | import org.javasimon.Split;
5 | import org.javasimon.Stopwatch;
6 |
7 | /**
8 | * HelloWorld is the most basic example of Stopwatch usage. You can show this
9 | * even to managers - it's that easy. :-) Hello world line shows that stopwatch
10 | * doesn't contain any results yet, these are added after the split is stopped.
11 | *
12 | * You can experiment with this example, try to put start/stop into the loop and
13 | * check total time, or whatever.
14 | *
15 | * @author Richard "Virgo" Richter
16 | * @since 1.0
17 | */
18 | public final class HelloWorld {
19 |
20 | private HelloWorld() {
21 | }
22 |
23 | /**
24 | * Entry point of the demo application.
25 | *
26 | * @param args command line arguments
27 | */
28 | public static void main(String[] args) {
29 | Stopwatch stopwatch = SimonManager.getStopwatch("org.javasimon.examples.HelloWorld-stopwatch");
30 |
31 | Split split = stopwatch.start();
32 | System.out.println("Hello world, " + stopwatch);
33 | split.stop();
34 |
35 | // or this way using try-with-resource construction
36 | try (Split ignored = stopwatch.start()){
37 | System.out.println("Hello world (try-with-resource), " + stopwatch);
38 | }
39 |
40 | System.out.println("Result: " + stopwatch);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/UnknownSimon.java:
--------------------------------------------------------------------------------
1 | package org.javasimon;
2 |
3 | /**
4 | * UnknownSimon represents Simon node in the hierarchy without known type. It may be replaced
5 | * in the hierarchy for real Simon in the future.
6 | *
7 | * @author Richard "Virgo" Richter
8 | */
9 | final class UnknownSimon extends AbstractSimon {
10 |
11 | /**
12 | * Constructs unknown Simon with a specified name and for the specified manager.
13 | *
14 | * @param name Simon's name
15 | * @param manager owning manager
16 | */
17 | UnknownSimon(String name, Manager manager) {
18 | super(name, manager);
19 | }
20 |
21 | @Override
22 | public synchronized Sample sample() {
23 | UnknownSample sample = new UnknownSample();
24 | sampleCommon(sample);
25 | return sample;
26 |
27 | }
28 |
29 | @Override
30 | public Sample sampleIncrement(Object key) {
31 | return sample();
32 | }
33 |
34 | @Override
35 | public Sample sampleIncrementNoReset(Object key) {
36 | return sample();
37 | }
38 |
39 | @Override
40 | public boolean stopIncrementalSampling(Object key) {
41 | return false;
42 | }
43 |
44 | /**
45 | * Returns the label {@code Unknown Simon} and basic information for the Simon as a human readable string.
46 | *
47 | * @return basic information about unknown Simon
48 | * @see AbstractSimon#toString()
49 | */
50 | @Override
51 | public String toString() {
52 | return "Unknown Simon: " + super.toString();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/console-embed/src/main/resources/org/javasimon/console/resource/js/javasimon-autorefresh.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var javasimon = window.javasimon || {};
3 | window.javasimon = javasimon;
4 | /**
5 | * Auto refresh controller
6 | */
7 | javasimon.AutoRefreshController = function (oRefreshTimeSelect, fnOnRefresh) {
8 |
9 | var SECOND = 1000;
10 | var NEVER = "never";
11 |
12 | this.timeoutMap = {
13 | "1 sec": SECOND,
14 | "10 sec": 10 * SECOND,
15 | "30 sec": 30 * SECOND,
16 | "60 sec": 60 * SECOND
17 | };
18 |
19 | this.oRefreshTimeSelect = oRefreshTimeSelect;
20 | this.fnOnRefresh = fnOnRefresh;
21 | this.timeoutHandle = null;
22 |
23 | var that = this;
24 | // Disable by default because it may be a burden for server side
25 | this.oRefreshTimeSelect.val("never");
26 | this.oRefreshTimeSelect.change(function () {
27 |
28 | if (that.timeoutHandle) {
29 | clearInterval(that.timeoutHandle);
30 | }
31 |
32 | that.restartTimer();
33 | });
34 | this.restartTimer();
35 | };
36 |
37 | javasimon.AutoRefreshController.prototype = {
38 | restartTimer: function () {
39 | var sRefreshVal = this.oRefreshTimeSelect.val();
40 | var iTimeoutVal = this.getTimeoutVal(sRefreshVal);
41 |
42 | if (iTimeoutVal) {
43 | var that = this;
44 |
45 | this.timeoutHandle = setTimeout(function () {
46 | that.fnOnRefresh();
47 | that.restartTimer();
48 | }, iTimeoutVal);
49 |
50 | }
51 | },
52 |
53 | getTimeoutVal: function (sRefreshVal) {
54 | return this.timeoutMap[sRefreshVal];
55 | }
56 | };
--------------------------------------------------------------------------------
/console-embed/src/test/java/org/javasimon/console/action/ResourceActionTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.action;
2 |
3 | import static org.mockito.Mockito.verify;
4 | import static org.testng.Assert.assertEquals;
5 | import static org.testng.Assert.assertTrue;
6 |
7 | import org.javasimon.console.ActionException;
8 | import org.javasimon.console.TestActionContext;
9 | import org.testng.annotations.Test;
10 |
11 | import javax.servlet.http.HttpServletResponse;
12 |
13 | /**
14 | * Unit test for {@link ResourceAction}
15 | *
16 | * @author gquintana
17 | */
18 | public class ResourceActionTest {
19 |
20 | @Test
21 | public void testExecute() throws Exception {
22 | TestActionContext context = new TestActionContext("/resource/index.html");
23 | ResourceAction action = new ResourceAction(context, "/index.html");
24 | action.execute();
25 | assertEquals(context.getContentType(), "text/html");
26 | assertTrue(context.toByteArray().length > 128);
27 | }
28 |
29 | @Test(expectedExceptions = ActionException.class)
30 | public void test4xxErrorWhenResourceDoesNotExists() throws Exception {
31 | TestActionContext context = new TestActionContext("/resource/non/existing");
32 |
33 | try {
34 | ResourceAction action = new ResourceAction(context, "/non/existing");
35 | action.execute();
36 | } finally {
37 | HttpServletResponse response = context.getResponse();
38 | verify(response).setStatus(HttpServletResponse.SC_NOT_FOUND);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/jmx/CounterMXBeanImplTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jmx;
2 |
3 | import org.javasimon.Counter;
4 | import org.javasimon.CounterSample;
5 | import org.testng.Assert;
6 | import org.testng.annotations.BeforeMethod;
7 | import org.testng.annotations.Test;
8 |
9 | import static org.mockito.Mockito.mock;
10 | import static org.mockito.Mockito.verify;
11 | import static org.mockito.Mockito.when;
12 |
13 | /**
14 | * @author Ivan Mushketyk
15 | */
16 | public class CounterMXBeanImplTest {
17 |
18 | private CounterMXBeanImpl counterMXBean;
19 | private Counter counter;
20 |
21 | @BeforeMethod
22 | public void beforeMethod() {
23 | counter = mock(Counter.class);
24 | counterMXBean = new CounterMXBeanImpl(counter);
25 | }
26 |
27 | @Test
28 | public void testSampleIncrement() {
29 | String key = "key";
30 | org.javasimon.CounterSample sample = new CounterSample();
31 | sample.setCounter(1);
32 | when(counter.sampleIncrement(key)).thenReturn(sample);
33 |
34 | CounterSample actualSample = counterMXBean.sampleIncrement(key);
35 | Assert.assertEquals(actualSample.getCounter(), 1);
36 |
37 | verify(counter).sampleIncrement(key);
38 | }
39 |
40 | @Test
41 | public void testStopIncrementSampling() {
42 | String key = "key";
43 | when(counter.stopIncrementalSampling(key)).thenReturn(true);
44 | boolean actual = counterMXBean.stopIncrementalSampling(key);
45 | Assert.assertTrue(actual);
46 |
47 | verify(counter).stopIncrementalSampling(key);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/jdbc41/src/main/java/org/javasimon/jdbcx4/SimonXAConnection.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jdbcx4;
2 |
3 | import java.sql.SQLException;
4 | import javax.sql.StatementEventListener;
5 | import javax.sql.XAConnection;
6 | import javax.transaction.xa.XAResource;
7 |
8 | /**
9 | * Simon implementation of XAConnection, needed for
10 | * Simon XADataSource implementation.
11 | *
12 | * All method invokes its real implementation.
13 | *
14 | * See the {@link org.javasimon.jdbcx4 package description} for more
15 | * information.
16 | *
17 | * @author Radovan Sninsky
18 | * @author Richard "Virgo" Richter
19 | * @since 2.4
20 | */
21 | public final class SimonXAConnection extends SimonPooledConnection implements XAConnection {
22 | private final XAConnection realConn;
23 |
24 | /**
25 | * Class constructor.
26 | *
27 | * @param connection real xa connection
28 | * @param prefix Simon prefix
29 | */
30 | public SimonXAConnection(XAConnection connection, String prefix) {
31 | super(connection, prefix);
32 |
33 | this.realConn = connection;
34 | }
35 |
36 | @Override
37 | public XAResource getXAResource() throws SQLException {
38 | return realConn.getXAResource();
39 | }
40 |
41 | @Override
42 | public void addStatementEventListener(StatementEventListener listener) {
43 | realConn.addStatementEventListener(listener);
44 | }
45 |
46 | @Override
47 | public void removeStatementEventListener(StatementEventListener listener) {
48 | realConn.removeStatementEventListener(listener);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014, Java Simon project
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/console-embed/src/main/resources/org/javasimon/console/resource/js/javasimon-callTreePlugin.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var javasimon=window.javasimon;
3 | if (javasimon) {
4 | (function(domUtil, viewPluginMgr) {
5 | viewPluginMgr.fnAddPluginRenderer("callTree",function(eTableBody, oCallTree) {
6 | var row, eTreeTable,oDataTreeTable;
7 | if (oCallTree.message) {
8 | row=this.fnAppendRow(eTableBody);
9 | this.fnAppendLabelValueCell(row,"Message", oCallTree.message, 3);
10 | }
11 | if (oCallTree.logThreshold) {
12 | row=this.fnAppendRow(eTableBody);
13 | this.fnAppendLabelValueCell(row, "Threshold", oCallTree.logThreshold);
14 | }
15 | if (oCallTree.rootNode) {
16 | row=this.fnAppendRow(eTableBody);
17 | this.fnAppendLabelCell(row,"Tree");
18 | eTreeTable=domUtil.fnAppendChildElement(
19 | this.fnAppendValueCell(row, null, 1),
20 | "table",
21 | {id:"callDataTreeTable", style:"width:auto","class":"dataTreeTable"}
22 | );
23 | oDataTreeTable=new javasimon.DataTreeTable(
24 | eTreeTable,{
25 | aoColumns:[
26 | {sTitle:"Name", sField:"name", sClass:'string headCell'},
27 | {sTitle:"Percent", sField:"percent", sClass:"number"},
28 | {sTitle:"Total", sField:"total", sClass:"number"},
29 | {sTitle:"Count", sField:"splitCount",sClass:"number"}
30 | ]
31 | }
32 | );
33 | oDataTreeTable.fnSetRootData(oCallTree.rootNode);
34 | oDataTreeTable.fnDrawHeader();
35 | oDataTreeTable.fnDraw();
36 | }
37 | });
38 | }(javasimon.DOMUtil, javasimon.ViewPluginManager));
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/core/src/test/java/org/javasimon/jmx/StopwatchMXBeanImplTest.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.jmx;
2 |
3 | import org.javasimon.Stopwatch;
4 | import org.javasimon.StopwatchSample;
5 |
6 | import org.testng.Assert;
7 | import org.testng.annotations.BeforeMethod;
8 | import org.testng.annotations.Test;
9 |
10 | import static org.mockito.Mockito.mock;
11 | import static org.mockito.Mockito.verify;
12 | import static org.mockito.Mockito.when;
13 |
14 | /**
15 | * @author Ivan Mushketyk
16 | */
17 | public class StopwatchMXBeanImplTest {
18 | private StopwatchMXBeanImpl stopwatchMXBean;
19 | private Stopwatch stopwatch;
20 |
21 | @BeforeMethod
22 | public void beforeMethod() {
23 | stopwatch = mock(Stopwatch.class);
24 | stopwatchMXBean = new StopwatchMXBeanImpl(stopwatch);
25 | }
26 |
27 | @Test
28 | public void testSampleIncrement() {
29 | String key = "key";
30 | StopwatchSample sample = new StopwatchSample();
31 | sample.setCounter(1);
32 | when(stopwatch.sampleIncrement(key)).thenReturn(sample);
33 |
34 | StopwatchSample actualSample = stopwatchMXBean.sampleIncrement(key);
35 | Assert.assertEquals(actualSample.getCounter(), 1);
36 |
37 | verify(stopwatch).sampleIncrement(key);
38 | }
39 |
40 | @Test
41 | public void testStopIncrementSampling() {
42 | String key = "key";
43 | when(stopwatch.stopIncrementalSampling(key)).thenReturn(true);
44 | boolean actual = stopwatchMXBean.stopIncrementalSampling(key);
45 | Assert.assertTrue(actual);
46 |
47 | verify(stopwatch).stopIncrementalSampling(key);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/console-embed/src/main/java/org/javasimon/console/action/TreeXmlAction.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.console.action;
2 |
3 | import org.javasimon.Simon;
4 | import org.javasimon.console.ActionContext;
5 | import org.w3c.dom.Document;
6 | import org.w3c.dom.Element;
7 |
8 | /**
9 | * Export Simons as a hierarchical XML document.
10 | * All attributes of simons are exported.
11 | *
12 | * @author gquintana
13 | */
14 | public class TreeXmlAction extends AbstractXmlAction {
15 |
16 | public static final String PATH = "/data/tree.xml";
17 |
18 | /**
19 | * Name of the simon from where to start.
20 | * {@code null} means root.
21 | */
22 | private String name;
23 |
24 | public TreeXmlAction(ActionContext context) {
25 | super(context);
26 | }
27 |
28 | @Override
29 | public void readParameters() {
30 | super.readParameters();
31 | name = getContext().getParameterAsString("name", null);
32 | }
33 |
34 | @Override
35 | protected Element createElement(Document document, Simon simon) {
36 | Element element = super.createElement(document, simon);
37 | for (Simon child : simon.getChildren()) {
38 | Element childElement = createElement(document, child);
39 | element.appendChild(childElement);
40 | }
41 | return element;
42 | }
43 |
44 | @Override
45 | protected void fillDocument(Document document) {
46 | Simon simon = name == null ? getContext().getManager().getRootSimon() : findSimonByName(name);
47 | Element rootElement = createElement(document, simon);
48 | document.appendChild(rootElement);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/core/src/main/java/org/javasimon/clock/CpuClock.java:
--------------------------------------------------------------------------------
1 | package org.javasimon.clock;
2 |
3 | import java.lang.management.ManagementFactory;
4 | import java.lang.management.ThreadMXBean;
5 |
6 | /**
7 | * Clock that should measure nanoseconds of CPU usage time.
8 | * Uses {@link java.lang.management.ThreadMXBean#getCurrentThreadCpuTime()} internally.
9 | * This Clock checks if CPU time is supported, but does not enable it, if it is disabled. User has to do this
10 | * externally calling {@code ManagementFactory.getThreadMXBean().setThreadCpuTimeEnabled(true)}.
11 | *
18 | Java Simon provides a few ways how to monitor your web-requests out of the box:
19 |
20 |
21 |
Simon Serlvet Filter - is mandatory and perfoms the measuring itself. It comes
22 | with simple plain text "console" - check it here
23 | (or "help" page)
24 |
25 |
Embedded Console comes in two ways - as a filter
26 | or as a servlet. Functionally they are the same,
27 | but filter is easier to set-up so it is not monitored - just put it before the Simon Servlet Filter.
28 |
29 |
30 |
31 | In case you want to create some statistics by using a test monitored web appliction, click this link.
32 |
6 | * Non-composite callbacks are used to perform expected actions for particular events.
7 | * {@link org.javasimon.callback.CallbackSkeleton} can be extended if only selected events are desired to be
8 | * implemented instead of implementating the whole {@link org.javasimon.callback.Callback} interface.
9 | *
10 | * Composite callbacks are used to organize other callbacks in trees and then to delegate all events to them.
11 | * It is not recommended to mix composite callbacks with functionality, generally it should not be necessary to implement
12 | * composite callbacks in addition to the following two provided implementations:
13 | *
14 | *
{@link org.javasimon.callback.CompositeCallbackImpl} delegates all events to all sub-callbacks
15 | * (used in {@link org.javasimon.EnabledManager} for instance);
16 | *
{@link org.javasimon.callback.CompositeFilterCallback} allows to filter events that should be propagated to the sub-callbacks,
17 | * filter rules can be added using
18 | * {@link org.javasimon.callback.FilterCallback#addRule(org.javasimon.callback.FilterRule.Type, String, String, org.javasimon.callback.Callback.Event...)}.