├── jdbc41 ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── java.sql.Driver │ │ └── java │ │ └── org │ │ └── javasimon │ │ ├── jdbc4 │ │ ├── jmx │ │ │ └── package-info.java │ │ ├── RegexBasedNormalizerFactory.java │ │ ├── SqlNormalizerFactory.java │ │ ├── SqlNormalizer.java │ │ └── WrapperSupport.java │ │ └── jdbcx4 │ │ ├── SimonXAConnection.java │ │ ├── SimonXADataSource.java │ │ └── SimonConnectionPoolDataSource.java └── pom.xml ├── docs └── api │ └── resources │ └── simonlogo120.png ├── demoapp └── src │ └── main │ ├── webapp │ ├── simonlogo120.png │ ├── static │ │ └── js │ │ │ └── conf.js │ ├── demo.css │ ├── index.html │ └── style.css │ ├── resources │ ├── db.create.sql │ ├── jetty-logging.properties │ ├── log4j.properties │ ├── org │ │ └── javasimon │ │ │ └── console │ │ │ └── resource │ │ │ └── js │ │ │ └── javasimon-customization.js │ └── servlet-context.xml │ └── java │ └── org │ └── javasimon │ └── demoapp │ ├── dao │ ├── ToDoItemDao.java │ ├── DaoException.java │ └── ApplicationStartupListener.java │ ├── Start.java │ └── model │ └── ToDoItem.java ├── spring ├── src │ ├── test │ │ └── java │ │ │ └── org │ │ │ └── javasimon │ │ │ └── spring │ │ │ ├── ServiceOne.java │ │ │ ├── ServiceTwo.java │ │ │ ├── AbstractService.java │ │ │ ├── MonitoredService.java │ │ │ └── MonitoredPointcutStopwatchNameConfig.java │ └── main │ │ └── java │ │ └── org │ │ └── javasimon │ │ └── spring │ │ ├── webmvc │ │ ├── HandlerStep.java │ │ ├── package-info.java │ │ ├── HandlerStopwatchSource.java │ │ └── HandlerLocation.java │ │ ├── SimonWebConfigurationBean.java │ │ └── package-info.java └── doc │ └── monitoring.xml ├── console-embed ├── src │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── javasimon │ │ │ │ └── console │ │ │ │ ├── html │ │ │ │ ├── package-info.java │ │ │ │ ├── HtmlResourceType.java │ │ │ │ └── HtmlResource.java │ │ │ │ ├── json │ │ │ │ ├── package-info.java │ │ │ │ ├── SimpleJS.java │ │ │ │ └── AnyJS.java │ │ │ │ ├── reflect │ │ │ │ └── package-info.java │ │ │ │ ├── action │ │ │ │ ├── package-info.java │ │ │ │ ├── ClearAction.java │ │ │ │ ├── CsvStringifierFactory.java │ │ │ │ ├── RedirectAction.java │ │ │ │ ├── ErrorAction.java │ │ │ │ ├── TreeXmlAction.java │ │ │ │ ├── TableCsvAction.java │ │ │ │ ├── DetailPlugin.java │ │ │ │ └── TreeJsonAction.java │ │ │ │ ├── package-info.java │ │ │ │ ├── SimonVisitor.java │ │ │ │ ├── text │ │ │ │ ├── Stringifier.java │ │ │ │ ├── package-info.java │ │ │ │ ├── NoneStringifier.java │ │ │ │ └── BaseStringifier.java │ │ │ │ ├── ActionException.java │ │ │ │ ├── TimeFormatType.java │ │ │ │ ├── ActionBinding.java │ │ │ │ ├── SimonType.java │ │ │ │ ├── Action.java │ │ │ │ └── SimonCallbacks.java │ │ └── resources │ │ │ └── org │ │ │ └── javasimon │ │ │ └── console │ │ │ └── resource │ │ │ ├── images │ │ │ ├── Reset.png │ │ │ ├── ToDo.png │ │ │ ├── logo.png │ │ │ ├── sort_asc.png │ │ │ ├── sort_both.png │ │ │ ├── sort_desc.png │ │ │ ├── TypeCounter.png │ │ │ ├── TypeUnknown.png │ │ │ ├── back_enabled.jpg │ │ │ ├── TreeTableLeaf.gif │ │ │ ├── TreeTableNode.gif │ │ │ ├── TreeTableSpacer.gif │ │ │ ├── TypeStopwatch.png │ │ │ ├── back_disabled.jpg │ │ │ ├── forward_enabled.jpg │ │ │ ├── TreeTableLastLeaf.gif │ │ │ ├── TreeTableLastNode.gif │ │ │ ├── forward_disabled.jpg │ │ │ ├── sort_asc_disabled.png │ │ │ ├── TreeTableLastSpacer.gif │ │ │ ├── sort_desc_disabled.png │ │ │ ├── TreeTableNodeCollapsed.gif │ │ │ ├── TreeTableNodeExpanded.gif │ │ │ ├── TreeTableLastNodeExpanded.gif │ │ │ └── TreeTableLastNodeCollapsed.gif │ │ │ ├── css │ │ │ └── start │ │ │ │ └── images │ │ │ │ ├── ui-icons_0078ae_256x240.png │ │ │ │ ├── ui-icons_056b93_256x240.png │ │ │ │ ├── ui-icons_d8e7f3_256x240.png │ │ │ │ ├── ui-icons_e0fdff_256x240.png │ │ │ │ ├── ui-icons_f5e175_256x240.png │ │ │ │ ├── ui-icons_f7a50d_256x240.png │ │ │ │ ├── ui-icons_fcd113_256x240.png │ │ │ │ ├── ui-bg_flat_55_999999_40x100.png │ │ │ │ ├── ui-bg_flat_75_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_glass_45_0078ae_1x400.png │ │ │ │ ├── ui-bg_glass_55_f8da4e_1x400.png │ │ │ │ ├── ui-bg_glass_75_79c9ec_1x400.png │ │ │ │ ├── ui-bg_gloss-wave_45_e14f1c_500x100.png │ │ │ │ ├── ui-bg_gloss-wave_50_6eac2c_500x100.png │ │ │ │ ├── ui-bg_gloss-wave_75_2191c0_500x100.png │ │ │ │ └── ui-bg_inset-hard_100_fcfdfd_1x100.png │ │ │ └── js │ │ │ ├── javasimon-dummyPlugin.js │ │ │ ├── javasimon-autorefresh.js │ │ │ ├── javasimon-callTreePlugin.js │ │ │ └── jquery-dataTables-reloadAjax.js │ └── test │ │ └── java │ │ └── org │ │ └── javasimon │ │ └── console │ │ ├── plugin │ │ ├── DummyOtherPlugin.java │ │ └── DummyDetailPlugin.java │ │ ├── SimonData.java │ │ ├── action │ │ ├── ResourceActionTest.java │ │ └── ListJsonActionTest.java │ │ └── json │ │ └── ObjectJSTest.java └── pom.xml ├── .gitignore ├── core ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── javasimon │ │ │ ├── aop │ │ │ └── package-info.java │ │ │ ├── callback │ │ │ ├── lastsplits │ │ │ │ └── package-info.java │ │ │ ├── calltree │ │ │ │ └── package-info.java │ │ │ ├── quantiles │ │ │ │ ├── package-info.java │ │ │ │ ├── BucketsType.java │ │ │ │ ├── BucketSample.java │ │ │ │ ├── BucketsSample.java │ │ │ │ └── FixedQuantilesCallback.java │ │ │ ├── logging │ │ │ │ ├── LogMessageSource.java │ │ │ │ ├── DisabledLogTemplate.java │ │ │ │ ├── SplitThresholdLogTemplate.java │ │ │ │ ├── LogTemplate.java │ │ │ │ ├── DelegateLogTemplate.java │ │ │ │ ├── package-info.java │ │ │ │ ├── CounterLogTemplate.java │ │ │ │ └── JULLogTemplate.java │ │ │ ├── async │ │ │ │ ├── Executor.java │ │ │ │ └── ExecutorProxyFactory.java │ │ │ ├── timeline │ │ │ │ ├── TimelineSample.java │ │ │ │ └── TimeRange.java │ │ │ ├── FilterCallback.java │ │ │ ├── CompositeCallback.java │ │ │ ├── package-info.java │ │ │ └── CallbackSkeleton.java │ │ │ ├── proxy │ │ │ ├── package-info.java │ │ │ ├── Delegating.java │ │ │ ├── ProxyStopwatchSource.java │ │ │ ├── DelegatingMethodInvocation.java │ │ │ └── StopwatchProxyFactory.java │ │ │ ├── utils │ │ │ ├── bean │ │ │ │ ├── ToStringConverter.java │ │ │ │ ├── ConvertException.java │ │ │ │ ├── BeanUtilsException.java │ │ │ │ ├── ToCharConverter.java │ │ │ │ ├── ToLongConverter.java │ │ │ │ ├── ToFloatConverter.java │ │ │ │ ├── ToByteConverter.java │ │ │ │ ├── ToDoubleConverter.java │ │ │ │ ├── ToShortConverter.java │ │ │ │ ├── Converter.java │ │ │ │ ├── ToIntegerConverter.java │ │ │ │ ├── ToBooleanConverter.java │ │ │ │ └── ToEnumConverter.java │ │ │ └── package-info.java │ │ │ ├── MustBeInSynchronized.java │ │ │ ├── SimonState.java │ │ │ ├── UnknownSample.java │ │ │ ├── SimonFilter.java │ │ │ ├── source │ │ │ ├── CachedStopwatchSource.java │ │ │ ├── StopwatchSource.java │ │ │ ├── DisabledMonitorSource.java │ │ │ ├── DisabledStopwatchSource.java │ │ │ ├── MonitorSource.java │ │ │ ├── package-info.java │ │ │ ├── AbstractStopwatchSource.java │ │ │ └── AbstractMethodStopwatchSource.java │ │ │ ├── clock │ │ │ ├── SimonUnit.java │ │ │ ├── TestClock.java │ │ │ └── CpuClock.java │ │ │ ├── SimonException.java │ │ │ ├── SimonConfiguration.java │ │ │ ├── UnknownSimon.java │ │ │ └── AttributesSupport.java │ └── test │ │ ├── resources │ │ └── org │ │ │ └── javasimon │ │ │ ├── utils │ │ │ ├── SampleHtmlGeneratorTest-0sample.html │ │ │ ├── SampleHtmlGeneratorTest-1sample.html │ │ │ └── SampleHtmlGeneratorTest-3sample.html │ │ │ ├── callback │ │ │ └── quantiles │ │ │ │ └── quantiles.properties │ │ │ └── test-config.xml │ │ └── java │ │ └── org │ │ └── javasimon │ │ ├── SimonUnitTest.java │ │ ├── utils │ │ ├── bean │ │ │ ├── ToStringConverterTest.java │ │ │ ├── ToEnumCoverterTest.java │ │ │ ├── ToCharConverterTest.java │ │ │ ├── ToBooleanConverterTest.java │ │ │ ├── ToLongConverterTest.java │ │ │ └── ToDoubleConverterTest.java │ │ ├── ReplacerTest.java │ │ └── SimonUtilsTest.java │ │ ├── jmx │ │ ├── CounterMXBeanImplTest.java │ │ └── StopwatchMXBeanImplTest.java │ │ ├── callback │ │ ├── timeline │ │ │ └── TimeUtil.java │ │ └── lastsplits │ │ │ └── LastSplitsCallbackTest.java │ │ └── SimonTest.java └── pom.xml ├── console-webapp ├── src │ └── main │ │ └── webapp │ │ ├── META-INF │ │ └── context.xml │ │ ├── WEB-INF │ │ ├── jboss-web.xml │ │ ├── glassfish-web.xml │ │ └── web.xml │ │ └── index.html └── pom.xml ├── .travis.yml ├── javaee └── src │ └── main │ └── java │ └── org │ └── javasimon │ └── javaee │ ├── reqreporter │ ├── package-info.java │ ├── StandardRequestReporter.java │ ├── ReporterStopwatchInfo.java │ └── RequestReporter.java │ └── package-info.java ├── examples ├── src │ └── main │ │ ├── resources │ │ └── log4j.properties │ │ └── java │ │ └── org │ │ └── javasimon │ │ └── examples │ │ ├── package-info.java │ │ ├── jmx │ │ ├── package-info.java │ │ ├── custom │ │ │ ├── CustomStopwatchMXBean.java │ │ │ ├── CustomJmxRegisterCallback.java │ │ │ └── CustomStopwatchMXBeanImpl.java │ │ └── JmxCallbackExample.java │ │ ├── LoopingRandomMethod.java │ │ ├── ClockExample.java │ │ ├── perf │ │ └── CircularListAddPerfromance.java │ │ ├── HelloWorld.java │ │ ├── CallbackExample.java │ │ └── SamplingExample.java └── testapp.db.sql ├── development └── readme.txt ├── mvn-manual-release.bat └── license.txt /jdbc41/src/main/resources/META-INF/services/java.sql.Driver: -------------------------------------------------------------------------------- 1 | org.javasimon.jdbc4.Driver -------------------------------------------------------------------------------- /docs/api/resources/simonlogo120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/docs/api/resources/simonlogo120.png -------------------------------------------------------------------------------- /demoapp/src/main/webapp/simonlogo120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/demoapp/src/main/webapp/simonlogo120.png -------------------------------------------------------------------------------- /demoapp/src/main/webapp/static/js/conf.js: -------------------------------------------------------------------------------- 1 | var ToDoDemo = window.ToDoDemo || {} 2 | 3 | ToDoDemo.serverRoot = "http://localhost:8080/app"; -------------------------------------------------------------------------------- /spring/src/test/java/org/javasimon/spring/ServiceOne.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring; 2 | 3 | public class ServiceOne extends AbstractService { 4 | } 5 | -------------------------------------------------------------------------------- /spring/src/test/java/org/javasimon/spring/ServiceTwo.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring; 2 | 3 | public class ServiceTwo extends AbstractService { 4 | } 5 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/html/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * HTML generation helper classes. 3 | */ 4 | package org.javasimon.console.html; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Maven output files 2 | target/ 3 | 4 | # Ignore IDEA files 5 | .idea/ 6 | *.iml 7 | *.ipr 8 | *.iws 9 | 10 | # Other 11 | *.h2.db 12 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/aop/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains AOP related annotation {@link org.javasimon.aop.Monitored}. 3 | */ 4 | package org.javasimon.aop; -------------------------------------------------------------------------------- /console-webapp/src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/json/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Simplified JSON serializer used for Ajax communication and the REST API 3 | */ 4 | package org.javasimon.console.json; -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/reflect/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Reflection tools to dynamically extract information from Simons. 3 | */ 4 | package org.javasimon.console.reflect; -------------------------------------------------------------------------------- /demoapp/src/main/resources/db.create.sql: -------------------------------------------------------------------------------- 1 | create table toDoItem ( 2 | id integer auto_increment primary key, 3 | name varchar(128), 4 | description varchar(640), 5 | isDone boolean 6 | ); 7 | -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/Reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/Reset.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/ToDo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/ToDo.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/logo.png -------------------------------------------------------------------------------- /console-webapp/src/main/webapp/WEB-INF/jboss-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /javasimon-console 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: openjdk8 3 | 4 | branches: 5 | only: 6 | - master 7 | install: 8 | - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V 9 | script: 10 | - mvn test -B -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/action/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * All controllers (aka Action beans in Struts world) are located in this package. 3 | */ 4 | package org.javasimon.console.action; -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/sort_asc.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/sort_both.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/sort_desc.png -------------------------------------------------------------------------------- /spring/src/test/java/org/javasimon/spring/AbstractService.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring; 2 | 3 | public class AbstractService implements MonitoredService { 4 | 5 | @Override 6 | public void run() { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TypeCounter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TypeCounter.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TypeUnknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TypeUnknown.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/back_enabled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/back_enabled.jpg -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLeaf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLeaf.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableNode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableNode.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableSpacer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableSpacer.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TypeStopwatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TypeStopwatch.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/back_disabled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/back_disabled.jpg -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/forward_enabled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/forward_enabled.jpg -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastLeaf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastLeaf.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastNode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastNode.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/forward_disabled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/forward_disabled.jpg -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastSpacer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastSpacer.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /spring/src/test/java/org/javasimon/spring/MonitoredService.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring; 2 | 3 | import org.javasimon.aop.Monitored; 4 | 5 | public interface MonitoredService { 6 | 7 | @Monitored 8 | void run(); 9 | } 10 | -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableNodeCollapsed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableNodeCollapsed.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableNodeExpanded.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableNodeExpanded.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastNodeExpanded.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastNodeExpanded.gif -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/html/HtmlResourceType.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.html; 2 | 3 | /** 4 | * Resources types. 5 | * 6 | * @author gquintana 7 | */ 8 | public enum HtmlResourceType { 9 | JS, CSS 10 | } 11 | -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastNodeCollapsed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/images/TreeTableLastNodeCollapsed.gif -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_0078ae_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_0078ae_256x240.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_056b93_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_056b93_256x240.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_d8e7f3_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_d8e7f3_256x240.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_e0fdff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_e0fdff_256x240.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_f5e175_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_f5e175_256x240.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_f7a50d_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_f7a50d_256x240.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_fcd113_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-icons_fcd113_256x240.png -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/lastsplits/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * {@link org.javasimon.callback.lastsplits.LastSplitsCallback} retains last 3 | * splits in a ring a buffer (fixed size FIFO queue). 4 | */ 5 | package org.javasimon.callback.lastsplits; -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_flat_55_999999_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_flat_55_999999_40x100.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_flat_75_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_flat_75_aaaaaa_40x100.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_glass_45_0078ae_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_glass_45_0078ae_1x400.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_glass_55_f8da4e_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_glass_55_f8da4e_1x400.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_glass_75_79c9ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_glass_75_79c9ec_1x400.png -------------------------------------------------------------------------------- /console-webapp/src/main/webapp/WEB-INF/glassfish-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /javasimon-console 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring/src/main/java/org/javasimon/spring/webmvc/HandlerStep.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring.webmvc; 2 | 3 | /** 4 | * Spring MVC request processing step. 5 | * 6 | * @author gquintana 7 | */ 8 | public enum HandlerStep { 9 | CONTROLLER, 10 | VIEW 11 | } 12 | -------------------------------------------------------------------------------- /demoapp/src/main/resources/jetty-logging.properties: -------------------------------------------------------------------------------- 1 | # Set up logging implementation 2 | org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog 3 | org.eclipse.jetty.LEVEL=INFO 4 | # Make websocket more verbose for testing 5 | org.eclipse.jetty.websocket.LEVEL=DEBUG -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/calltree/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * {@link org.javasimon.callback.calltree.CallTreeCallback} gathers information 3 | * for current thread and displays it subsequent calls like a tree. 4 | */ 5 | package org.javasimon.callback.calltree; -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/virgo47/javasimon/HEAD/console-embed/src/main/resources/org/javasimon/console/resource/css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/proxy/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Provides everything to wrap any class a Proxy generated with java.lang.reflect. 3 | * The main class of this package is {@link org.javasimon.proxy.StopwatchProxyFactory}. 4 | */ 5 | package org.javasimon.proxy; 6 | -------------------------------------------------------------------------------- /javaee/src/main/java/org/javasimon/javaee/reqreporter/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Package contains classes reporting slow HTTP requests - interface {@link org.javasimon.javaee.reqreporter.RequestReporter} and various (default) implementations. 3 | */ 4 | package org.javasimon.javaee.reqreporter; -------------------------------------------------------------------------------- /examples/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, STDOUT 2 | log4j.logger.deng=INFO 3 | log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender 4 | log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n 6 | -------------------------------------------------------------------------------- /examples/src/main/java/org/javasimon/examples/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Basic examples of Java Simon usage - mostly for {@link org.javasimon.Stopwatch}, {@link org.javasimon.callback.Callback}, 3 | * {@link org.javasimon.Sample}, some multithreading, benchmarks. 4 | */ 5 | package org.javasimon.examples; -------------------------------------------------------------------------------- /spring/src/main/java/org/javasimon/spring/webmvc/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * {@link org.javasimon.spring.webmvc.MonitoringHandlerInterceptor} is a Spring MVC interceptor which can be used to monitor 3 | * time spent in Controller and View. Spring 3.1 is required for this feature. 4 | */ 5 | package org.javasimon.spring.webmvc; -------------------------------------------------------------------------------- /demoapp/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.Stdout=org.apache.log4j.ConsoleAppender 2 | log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout 3 | log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n 4 | 5 | log4j.rootLogger=DEBUG,Stdout 6 | 7 | 8 | org.springframework=DEBUG,Stdout 9 | 10 | 11 | -------------------------------------------------------------------------------- /core/src/test/resources/org/javasimon/utils/SampleHtmlGeneratorTest-0sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
NameActiveCounterMinMaxMeanTotal
-------------------------------------------------------------------------------- /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 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
NameActiveCounterMinMaxMeanTotal
sample1125.00 us15.0 us10.0 us20.0 us
-------------------------------------------------------------------------------- /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 | *

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.
  • 12 | *
13 | */ 14 | package org.javasimon.console.text; -------------------------------------------------------------------------------- /console-webapp/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SimonConsoleServlet 7 | org.javasimon.console.SimonConsoleServlet 8 | 9 | url-prefix 10 | 11 | 12 | 13 | 14 | SimonConsoleServlet 15 | /* 16 | 17 | 18 | 30 19 | 20 | 21 | index.html 22 | 23 | 24 | -------------------------------------------------------------------------------- /mvn-manual-release.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | set /P VERSION="Enter new version: " 3 | set /P GPGPP="Enter GPG pass-phrase: " 4 | 5 | set JAVA_HOME=%JAVA8_HOME% 6 | 7 | call mvn versions:set -DnewVersion=%VERSION% 8 | call mvn versions:commit 9 | call mvn clean deploy -P sonatype-oss-release -Dgpg.passphrase=%GPGPP% 10 | 11 | goto :eof 12 | 13 | REM DISTRIBUTION ZIP (rename as needed) - skipped, not needed anymore 14 | call mvn javadoc:aggregate-jar 15 | call mvn source:aggregate 16 | 17 | if exist dist.zip del dist.zip 18 | zip -j dist.zip console-embed\target\javasimon-console-embed-%VERSION%.jar ^ 19 | console-webapp\target\javasimon-console-webapp.war ^ 20 | core\target\javasimon-core-%VERSION%.jar ^ 21 | examples\target\javasimon-examples-%VERSION%.jar ^ 22 | javaee\target\javasimon-javaee-%VERSION%.jar ^ 23 | jdbc41\target\javasimon-jdbc41-%VERSION%.jar ^ 24 | spring\target\javasimon-spring-%VERSION%.jar ^ 25 | target\javasimon*.jar 26 | -------------------------------------------------------------------------------- /demoapp/src/main/java/org/javasimon/demoapp/dao/ApplicationStartupListener.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.demoapp.dao; 2 | 3 | import org.javasimon.demoapp.model.ToDoItem; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | 6 | import javax.annotation.PostConstruct; 7 | 8 | /** 9 | * @author Ivan Mushketyk (ivan.mushketyk@gmail.com) 10 | */ 11 | public class ApplicationStartupListener { 12 | @Autowired 13 | private ToDoItemDao toDoItemDao; 14 | 15 | @PostConstruct 16 | public void onApplicationStartup() { 17 | ToDoItem item1 = new ToDoItem(); 18 | item1.setName("Try new awesome Javasimon feature"); 19 | 20 | ToDoItem item2 = new ToDoItem(); 21 | item2.setName("Write a post in my blog"); 22 | item2.setDescription("How to use Javasimon for monitoring web applications"); 23 | 24 | toDoItemDao.create(item1); 25 | toDoItemDao.create(item2); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/json/SimpleJS.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.json; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | 6 | import org.javasimon.console.text.Stringifier; 7 | 8 | /** 9 | * JavaScript simple type. 10 | * 11 | * @author gquintana 12 | */ 13 | public class SimpleJS extends AnyJS { 14 | 15 | /** Simple value. */ 16 | protected final T value; 17 | 18 | /** Value formatter. */ 19 | private final Stringifier valueStringifier; 20 | 21 | /** Hidden constructor use factory methods instead. */ 22 | public SimpleJS(T value, Stringifier valueStringifier) { 23 | this.value = value; 24 | this.valueStringifier = valueStringifier; 25 | } 26 | 27 | public T getValue() { 28 | return value; 29 | } 30 | 31 | @Override 32 | public void write(Writer writer) throws IOException { 33 | writer.write(valueStringifier.toString(value)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/json/AnyJS.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.json; 2 | 3 | import java.io.IOException; 4 | import java.io.StringWriter; 5 | import java.io.Writer; 6 | 7 | /** 8 | * Base class for all JavaScript things. 9 | * 10 | * @author gquintana 11 | */ 12 | public abstract class AnyJS { 13 | 14 | /** Renders the response. */ 15 | public abstract void write(Writer writer) throws IOException; 16 | 17 | final void writeString(Writer writer, String string) throws IOException { 18 | writer.write("\""); 19 | writer.write(string); 20 | writer.write("\""); 21 | } 22 | 23 | /** Renders the response in a String. */ 24 | @Override 25 | public String toString() { 26 | try { 27 | StringWriter writer = new StringWriter(); 28 | write(writer); 29 | return writer.toString(); 30 | } catch (IOException iOException) { 31 | return iOException.getMessage(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /javaee/src/main/java/org/javasimon/javaee/reqreporter/StandardRequestReporter.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.javaee.reqreporter; 2 | 3 | /** 4 | * Reports request to standard output (instead of Manager's message method) and omits less specific Simons from 5 | * output (for instance JDBC's next). 6 | * 7 | * @author Richard "Virgo" Richter 8 | */ 9 | @SuppressWarnings("UnusedDeclaration") 10 | public class StandardRequestReporter extends DefaultRequestReporter { 11 | @Override 12 | protected void reportMessage(String message) { 13 | System.out.println(message); 14 | } 15 | 16 | @Override 17 | protected boolean shouldBeAddedStopwatchInfo(ReporterStopwatchInfo info) { 18 | return !(isJdbcResultSetNextSimon(info)); 19 | } 20 | 21 | private boolean isJdbcResultSetNextSimon(ReporterStopwatchInfo info) { 22 | return info.stopwatch.getName().contains(".sql.") && info.stopwatch.getName().endsWith(".next"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/logging/SplitThresholdLogTemplate.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.logging; 2 | 3 | import org.javasimon.Split; 4 | 5 | /** 6 | * Log template which awakes only when split is longer than given threshold. 7 | * 8 | * @author gquintana 9 | */ 10 | public class SplitThresholdLogTemplate extends DelegateLogTemplate { 11 | 12 | /** Split duration theshold. */ 13 | private final long threshold; 14 | 15 | /** 16 | * Constructor. 17 | * 18 | * @param delegate Concreate log template 19 | * @param threshold Theshold 20 | */ 21 | public SplitThresholdLogTemplate(LogTemplate delegate, long threshold) { 22 | super(delegate); 23 | this.threshold = threshold; 24 | } 25 | 26 | @Override 27 | protected boolean isEnabled(Split split) { 28 | return split.runningFor() > threshold && super.isEnabled(split); 29 | } 30 | 31 | protected long getThreshold() { 32 | return threshold; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | javasimon-core 6 | jar 7 | JavaSimon Core 8 | 9 | 10 | org.javasimon 11 | javasimon-parent 12 | 4.2.1-SNAPSHOT 13 | 14 | 15 | 16 | 17 | org.testng 18 | testng 19 | 20 | 21 | org.slf4j 22 | slf4j-api 23 | 24 | 25 | org.mockito 26 | mockito-core 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /demoapp/src/main/java/org/javasimon/demoapp/Start.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.demoapp; 2 | 3 | import org.eclipse.jetty.server.Server; 4 | import org.eclipse.jetty.webapp.WebAppContext; 5 | 6 | /** 7 | * Run this directly in your IDE with "demoapp" as working directory. 8 | */ 9 | public class Start { 10 | 11 | public static void main(String[] args) { 12 | Server server = new Server(8080); 13 | 14 | WebAppContext bb = new WebAppContext(); 15 | bb.setServer(server); 16 | bb.setContextPath("/"); 17 | bb.setWar("src/main/webapp"); 18 | 19 | server.setHandler(bb); 20 | 21 | try { 22 | System.out.println(">>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP"); 23 | server.start(); 24 | //noinspection ResultOfMethodCallIgnored 25 | System.in.read(); 26 | System.out.println(">>> STOPPING EMBEDDED JETTY SERVER"); 27 | server.stop(); 28 | server.join(); 29 | } catch (Exception e) { 30 | e.printStackTrace(); 31 | System.exit(1); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/src/test/resources/org/javasimon/utils/SampleHtmlGeneratorTest-3sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
NameActiveCounterMinMaxMeanTotal
sample1125.00 us15.0 us10.0 us20.0 us
counter2-555undef600-+1000/-13
sample33615.0 us45.0 us30.0 us60.0 us
-------------------------------------------------------------------------------- /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 type; 23 | /** 24 | * Sample interface 25 | */ 26 | private final Class sampleType; 27 | 28 | private SimonType(Class type, Class sampleType) { 29 | this.type = type; 30 | this.sampleType = sampleType; 31 | } 32 | 33 | public Class getType() { 34 | return type; 35 | } 36 | 37 | public Class 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 | *

{@code
12 | 
13 | contextConfigLocation
14 | 
15 | classpath:org/javasimon/spring/monitoring.xml
16 | classpath:context/services.xml
17 | classpath:context/data-access-layer.xml
18 | /WEB-INF/applicationContext.xml
19 | 
20 | }
21 | * 22 | *

Step -2- Annotate all classes and/or methods you want to monitor (see {@link org.javasimon.aop.Monitored} for 23 | * more details). As step 1 configured annotation detection only for spring beans, make sure these classes are 24 | * instantiated through Spring (i.e. declare them as a bean in a Spring configuration file). 25 | */ 26 | package org.javasimon.spring; 27 | -------------------------------------------------------------------------------- /jdbc41/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | javasimon-jdbc41 6 | jar 7 | JavaSimon JDBC 4.1 Support 8 | Java Simon JDBC 4.1 (Java SE 7) proxy driver - must be compiled with JDK 1.7 9 | 10 | 11 | org.javasimon 12 | javasimon-parent 13 | 4.2.1-SNAPSHOT 14 | 15 | 16 | 17 | 18 | org.javasimon 19 | javasimon-core 20 | ${project.version} 21 | 22 | 23 | org.testng 24 | testng 25 | 26 | 27 | org.mockito 28 | mockito-core 29 | 30 | 31 | com.h2database 32 | h2 33 | test 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/utils/bean/ToCharConverterTest.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.utils.bean; 2 | 3 | import org.testng.Assert; 4 | import org.testng.annotations.DataProvider; 5 | import org.testng.annotations.Test; 6 | 7 | /** 8 | * @author Ivan Mushketyk 9 | */ 10 | public class ToCharConverterTest { 11 | 12 | private ToCharConverter toCharConverter = new ToCharConverter(); 13 | 14 | @DataProvider(name = "validInput") 15 | public Object[][] validInputProvider() { 16 | return new Object[][] { 17 | {"a", 'a'}, 18 | {"b", 'b'}, 19 | {"\n", '\n'}, 20 | {null, null} 21 | }; 22 | } 23 | 24 | @Test(dataProvider = "validInput") 25 | public void testValidInputConversion(String input, Character expectedChar) { 26 | Character actualChar = toCharConverter.convert(Character.class, input); 27 | Assert.assertEquals(actualChar, expectedChar); 28 | } 29 | 30 | @DataProvider(name = "invalidInput") 31 | public Object[][] invalidInputProvider() { 32 | return new Object[][] { 33 | {"abc"}, 34 | {"ab"}, 35 | {""} 36 | }; 37 | } 38 | 39 | @Test(dataProvider = "invalidInput", expectedExceptions = {ConvertException.class}) 40 | public void testInvalidInputConversion(String input) { 41 | toCharConverter.convert(Character.class, input); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/action/ErrorAction.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 | import java.io.PrintWriter; 9 | 10 | import javax.servlet.ServletException; 11 | 12 | /** 13 | * Action used when an exception occurs: exception stack trace is dumped into the response. 14 | * 15 | * @author gquintana 16 | */ 17 | public class ErrorAction extends Action { 18 | 19 | /** Exception to render. */ 20 | private ActionException error; 21 | 22 | public ErrorAction(ActionContext context) { 23 | super(context); 24 | } 25 | 26 | public ActionException getError() { 27 | return error; 28 | } 29 | 30 | public void setError(ActionException error) { 31 | this.error = error; 32 | } 33 | 34 | @Override 35 | public void execute() throws ServletException, IOException, ActionException { 36 | PrintWriter writer = null; 37 | try { 38 | getContext().setContentType("text/plain"); 39 | writer = getContext().getWriter(); 40 | error.printStackTrace(getContext().getWriter()); 41 | } finally { 42 | if (writer != null) { 43 | writer.flush(); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/utils/bean/ToBooleanConverterTest.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 ToBooleanConverterTest extends SimonUnitTest { 12 | 13 | private ToBooleanConverter toBooleanConverter = new ToBooleanConverter(); 14 | 15 | @DataProvider(name = "validValues") 16 | public Object[][] validValues() { 17 | return new Object[][]{ 18 | {"true", true}, 19 | {"false", false}, 20 | {"True", true}, 21 | {"False", false} 22 | }; 23 | } 24 | 25 | @Test(dataProvider = "validValues") 26 | public void testConvertingValidValues(String from, Boolean expected) { 27 | Assert.assertEquals(toBooleanConverter.convert(Boolean.class, from), expected); 28 | } 29 | 30 | @DataProvider(name = "invalidValues") 31 | public Object[][] invalidValues() { 32 | return new Object[][]{ 33 | {"12345"} 34 | }; 35 | } 36 | 37 | @Test(dataProvider = "invalidValues", expectedExceptions = {ConvertException.class}) 38 | public void testConvertingValidValues(String invalidVal) { 39 | toBooleanConverter.convert(Boolean.class, invalidVal); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/utils/bean/ToLongConverterTest.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 ToLongConverterTest extends SimonUnitTest { 12 | 13 | private ToLongConverter toLongConverter = new ToLongConverter(); 14 | 15 | @DataProvider(name = "toLongConverter") 16 | public Object[][] toLongConverter() { 17 | return new Object[][]{ 18 | {"0", 0L}, 19 | {"123", 123L}, 20 | {null, null} 21 | }; 22 | } 23 | 24 | @Test(dataProvider = "toLongConverter") 25 | public void testToIntegerConverter(String from, Long expectedLong) throws Exception { 26 | Assert.assertEquals(toLongConverter.convert(Long.class, from), expectedLong); 27 | } 28 | 29 | @DataProvider(name = "unconvertableValues") 30 | public Object[][] unconvertableValues() { 31 | return new Object[][]{ 32 | {"someStr"}, 33 | {"123?456"} 34 | }; 35 | } 36 | 37 | @Test(dataProvider = "unconvertableValues", expectedExceptions = {ConvertException.class}) 38 | public void testUnconvertableValues(String val) throws ConvertException { 39 | toLongConverter.convert(Long.class, val); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/html/HtmlResource.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.html; 2 | 3 | import org.javasimon.console.json.ArrayJS; 4 | import org.javasimon.console.json.ObjectJS; 5 | import org.javasimon.console.text.StringifierFactory; 6 | 7 | /** 8 | * JavaScript or CSS resource used by a plugin. 9 | * 10 | * @author gquintana 11 | */ 12 | public final class HtmlResource { 13 | 14 | /** Path/location of the resource. */ 15 | private final String path; 16 | /** Resource type: either JavaScript or CSS. */ 17 | private final HtmlResourceType type; 18 | 19 | public HtmlResource(String path, HtmlResourceType type) { 20 | this.path = path; 21 | this.type = type; 22 | } 23 | 24 | public String getPath() { 25 | return path; 26 | } 27 | 28 | public HtmlResourceType getType() { 29 | return type; 30 | } 31 | 32 | public ObjectJS toJson(StringifierFactory jsonStringifierFactory) { 33 | return ObjectJS.create(this, jsonStringifierFactory); 34 | } 35 | 36 | public static ArrayJS toJson(Iterable resources, StringifierFactory jsonStringifierFactory) { 37 | ArrayJS resourcesJS = new ArrayJS(); 38 | for (HtmlResource resource : resources) { 39 | resourcesJS.addElement(resource.toJson(jsonStringifierFactory)); 40 | } 41 | return resourcesJS; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /console-embed/src/test/java/org/javasimon/console/plugin/DummyDetailPlugin.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.plugin; 2 | 3 | import java.io.IOException; 4 | 5 | import org.javasimon.Simon; 6 | import org.javasimon.console.ActionContext; 7 | import org.javasimon.console.action.DetailHtmlBuilder; 8 | import org.javasimon.console.action.DetailPlugin; 9 | import org.javasimon.console.json.ObjectJS; 10 | import org.javasimon.console.text.StringifierFactory; 11 | 12 | /** 13 | * Detail plugin for testing purpose 14 | * 15 | * @author gquintana 16 | */ 17 | public class DummyDetailPlugin extends DetailPlugin { 18 | 19 | public DummyDetailPlugin() { 20 | super("dummy", "Dummy Plugin"); 21 | } 22 | 23 | @Override 24 | public DetailHtmlBuilder executeHtml(ActionContext context, DetailHtmlBuilder htmlBuilder, StringifierFactory htmlStringifierFactory, Simon simon) throws IOException { 25 | return htmlBuilder.beginRow() 26 | .labelCell("Message") 27 | .valueCell("Hello world!") 28 | .endRow(); 29 | } 30 | 31 | @Override 32 | public ObjectJS executeJson(ActionContext context, StringifierFactory jsonStringifierFactory, Simon simon) { 33 | ObjectJS pluginDataJS = new ObjectJS(); 34 | pluginDataJS.setSimpleAttribute("message", "Hello world!", jsonStringifierFactory.getStringifier(String.class)); 35 | return pluginDataJS; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /console-embed/src/test/java/org/javasimon/console/SimonData.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console; 2 | 3 | import org.javasimon.Counter; 4 | import org.javasimon.SimonManager; 5 | import org.javasimon.Split; 6 | import org.javasimon.Stopwatch; 7 | import org.javasimon.clock.SimonClock; 8 | 9 | /** 10 | * Generates Simon Data for unit testing 11 | * 12 | * @author gquintana 13 | */ 14 | public class SimonData { 15 | 16 | @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) 17 | private static boolean initialized = false; 18 | 19 | private static void addTime(String name, long sleep) { 20 | Stopwatch stopwatch = SimonManager.manager().getStopwatch(name); 21 | stopwatch.addSplit(Split.create(sleep * SimonClock.NANOS_IN_MILLIS)); 22 | } 23 | 24 | private static void initStopwatches() { 25 | addTime("A", 100); 26 | addTime("B", 200); 27 | addTime("C", 300); 28 | addTime("A", 200); 29 | addTime("A", 300); 30 | addTime("B", 100); 31 | addCounter("X", 1L); 32 | addCounter("X", 4L); 33 | addCounter("X", 2L); 34 | } 35 | 36 | private static void addCounter(String name, long value) { 37 | Counter counter = SimonManager.manager().getCounter(name); 38 | counter.set(value); 39 | } 40 | 41 | public static void initialize() { 42 | initialized = true; 43 | SimonManager.clear(); 44 | initStopwatches(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/CompositeCallback.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Composite {@link Callback} can hold more callbacks which allows to form callback trees where events are passed to 7 | * sub-callbacks. Events can be filtered using {@link FilterCallback} which may be set up to pass only specific 8 | * events under certain circumstances. 9 | * This can be configured via Manager configuration facility. (Configuration part is still rather WIP.) 10 | *

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 | *

12 | * If CPU time is not supported, 0 is returned. If it is disabled, -1 should be returned (check Javadoc for 13 | * {@link java.lang.management.ThreadMXBean#getCurrentThreadCpuTime()}). 14 | * 15 | * @since 3.5 16 | */ 17 | final class CpuClock implements SimonClock { 18 | 19 | private final ThreadMXBean threadMXBean; 20 | 21 | CpuClock() { 22 | ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); 23 | if (mxBean.isCurrentThreadCpuTimeSupported()) { 24 | threadMXBean = mxBean; 25 | } else { 26 | threadMXBean = null; 27 | } 28 | } 29 | 30 | 31 | @Override 32 | public long nanoTime() { 33 | if (threadMXBean == null) { 34 | return 0; 35 | } 36 | return threadMXBean.getCurrentThreadCpuTime(); 37 | } 38 | 39 | @Override 40 | public long milliTime() { 41 | return millisForNano(nanoTime()); 42 | } 43 | 44 | /** Here millis are simply nanos divided by {@link SimonClock#NANOS_IN_MILLIS}. */ 45 | @Override 46 | public long millisForNano(long nanos) { 47 | return nanos / NANOS_IN_MILLIS; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/action/TableCsvAction.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.action; 2 | 3 | import org.javasimon.Sample; 4 | import org.javasimon.console.ActionContext; 5 | 6 | import java.io.IOException; 7 | import java.io.PrintWriter; 8 | 9 | /** 10 | * Export Simons as a flat CSV table. 11 | * 12 | * @author gquintana 13 | */ 14 | public class TableCsvAction extends AbstractTableAction { 15 | 16 | public static final String PATH = "/data/table.csv"; 17 | 18 | /** 19 | * Column separator (defaults to comma). 20 | */ 21 | private static final String columnSeparator = ","; 22 | 23 | /** 24 | * Row separator (defaults to CRLF). 25 | */ 26 | private static final String rowSeparator = "\r\n"; 27 | 28 | public TableCsvAction(ActionContext context) { 29 | super(context, "text/csv"); 30 | stringifierFactory = new CsvStringifierFactory(); 31 | } 32 | 33 | @Override 34 | protected void printHeaderRow(PrintWriter writer) throws IOException { 35 | super.printHeaderRow(writer); 36 | printEndOfLine(writer); 37 | } 38 | 39 | @Override 40 | protected void printBodyRow(Sample sample, PrintWriter writer) throws IOException { 41 | super.printBodyRow(sample, writer); 42 | printEndOfLine(writer); 43 | } 44 | 45 | @Override 46 | protected void printCell(Column column, String s, PrintWriter writer) throws IOException { 47 | super.printCell(column, s, writer); 48 | writer.write(columnSeparator); 49 | } 50 | 51 | private void printEndOfLine(PrintWriter writer) { 52 | writer.write(rowSeparator); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/async/ExecutorProxyFactory.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.async; 2 | 3 | import org.javasimon.proxy.DelegatingMethodInvocation; 4 | import org.javasimon.proxy.DelegatingProxyFactory; 5 | 6 | /** 7 | * Proxy factory which can be used make any class asynchronous. 8 | * 9 | * @param 10 | * @author gerald 11 | */ 12 | public class ExecutorProxyFactory extends DelegatingProxyFactory { 13 | 14 | /** Executor used for invoking methods on delegate object. */ 15 | private Executor executor; 16 | 17 | /** 18 | * Constructor. 19 | * 20 | * @param delegate Delegate object 21 | */ 22 | public ExecutorProxyFactory(T delegate) { 23 | this(delegate, Executors.async()); 24 | } 25 | 26 | /** 27 | * Constructor. 28 | * 29 | * @param delegate Delegate object 30 | * @param executor Executor used, see {@link Executors} 31 | */ 32 | public ExecutorProxyFactory(T delegate, Executor executor) { 33 | super(delegate); 34 | this.executor = executor; 35 | } 36 | 37 | /** 38 | * Returns used executor. 39 | * 40 | * @return Executor 41 | */ 42 | public Executor getExecutor() { 43 | return executor; 44 | } 45 | 46 | /** 47 | * Sets used executor. 48 | * 49 | * @param executor Executor 50 | */ 51 | public void setExecutor(Executor executor) { 52 | this.executor = executor; 53 | } 54 | 55 | @Override 56 | protected Object invoke(DelegatingMethodInvocation delegatingMethodInvocation) throws Throwable { 57 | return executor.execute(delegatingMethodInvocation); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/proxy/ProxyStopwatchSource.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.proxy; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.javasimon.Manager; 6 | import org.javasimon.SimonManager; 7 | import org.javasimon.source.AbstractMethodStopwatchSource; 8 | 9 | /** 10 | * Stopwatch source for use with proxy. 11 | * 12 | * @author gquintana 13 | */ 14 | public class ProxyStopwatchSource extends AbstractMethodStopwatchSource> { 15 | 16 | /** Prefix used for simon name. */ 17 | private String prefix = "org.javasimon.proxy"; 18 | 19 | public ProxyStopwatchSource() { 20 | super(SimonManager.manager()); 21 | } 22 | 23 | public ProxyStopwatchSource(Manager manager) { 24 | super(manager); 25 | } 26 | 27 | public String getPrefix() { 28 | return prefix; 29 | } 30 | 31 | public void setPrefix(String prefix) { 32 | this.prefix = prefix; 33 | } 34 | 35 | @Override 36 | protected String getMonitorName(DelegatingMethodInvocation location) { 37 | final String className = getTargetClass(location).getSimpleName(); 38 | final String methodName = location.getMethod().getName(); 39 | return prefix + Manager.HIERARCHY_DELIMITER + className + Manager.HIERARCHY_DELIMITER + methodName; 40 | } 41 | 42 | @Override 43 | protected final Class getTargetClass(DelegatingMethodInvocation location) { 44 | return location.getDelegate().getClass(); 45 | } 46 | 47 | @Override 48 | protected final Method getTargetMethod(DelegatingMethodInvocation location) { 49 | return location.getMethod(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /demoapp/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Simon Demo Application 6 | 7 | 8 | 9 |

10 | 13 |
14 |
15 |

Java Simon Demo Web Application

16 | 17 |

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 |

33 | 38 |
39 |
40 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/quantiles/BucketsSample.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.quantiles; 2 | 3 | /** 4 | * Snapshot of {@link Buckets} 5 | * 6 | * @author gquintana 7 | */ 8 | public class BucketsSample { 9 | private final BucketSample[] buckets; 10 | /** 11 | * Median (50% percentile) 12 | */ 13 | private final Double median; 14 | /** 15 | * 90% percentile 16 | */ 17 | private final Double percentile90; 18 | 19 | public BucketsSample(BucketSample[] buckets, Double median, Double quantile90) { 20 | this.buckets = buckets; 21 | this.median = median; 22 | this.percentile90 = quantile90; 23 | } 24 | 25 | public BucketSample[] getBuckets() { 26 | return buckets; 27 | } 28 | 29 | public Double getMedian() { 30 | return median; 31 | } 32 | 33 | public Double getPercentile90() { 34 | return percentile90; 35 | } 36 | 37 | private boolean hasNoBuckets() { 38 | return buckets == null || buckets.length == 0; 39 | } 40 | 41 | public Integer getMaxCount() { 42 | Integer maxCount; 43 | if (hasNoBuckets()) { 44 | return null; 45 | } else { 46 | maxCount = 0; 47 | for (BucketSample bucket : buckets) { 48 | maxCount = Math.max(bucket.getCount(), maxCount); 49 | } 50 | } 51 | return maxCount; 52 | } 53 | 54 | public Integer getTotalCount() { 55 | Integer totalCount; 56 | if (hasNoBuckets()) { 57 | return null; 58 | } else { 59 | totalCount = 0; 60 | for (BucketSample bucket : buckets) { 61 | totalCount += bucket.getCount(); 62 | } 63 | } 64 | return totalCount; 65 | } 66 | } -------------------------------------------------------------------------------- /jdbc41/src/main/java/org/javasimon/jdbcx4/SimonXADataSource.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.jdbcx4; 2 | 3 | import java.sql.SQLException; 4 | import java.sql.SQLFeatureNotSupportedException; 5 | import java.util.logging.Logger; 6 | import javax.sql.XAConnection; 7 | import javax.sql.XADataSource; 8 | 9 | /** 10 | * Wrapper class for real XADataSource implementation, produces xa 11 | * {@link javax.sql.XAConnection} object. 12 | *

13 | * See the {@link SimonDataSource} for more information. 14 | * 15 | * @author Radovan Sninsky 16 | * @author Richard "Virgo" Richter 17 | * @since 2.4 18 | */ 19 | public final class SimonXADataSource extends AbstractSimonDataSource implements XADataSource { 20 | private XADataSource ds; 21 | 22 | private XADataSource datasource() throws SQLException { 23 | if (ds == null) { 24 | ds = createDataSource(XADataSource.class); 25 | } 26 | return ds; 27 | } 28 | 29 | @Override 30 | public XAConnection getXAConnection() throws SQLException { 31 | return new SimonXAConnection(datasource().getXAConnection(), getPrefix()); 32 | } 33 | 34 | @Override 35 | public XAConnection getXAConnection(String user, String password) throws SQLException { 36 | return new SimonXAConnection(datasource().getXAConnection(user, password), getPrefix()); 37 | } 38 | 39 | @Override 40 | protected String doGetRealDataSourceClassName() { 41 | return this.configuration.getRealXADataSourceName(); 42 | } 43 | 44 | @Override 45 | public Logger getParentLogger() throws SQLFeatureNotSupportedException { 46 | return ds.getParentLogger(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /console-embed/src/main/resources/org/javasimon/console/resource/js/jquery-dataTables-reloadAjax.js: -------------------------------------------------------------------------------- 1 | $.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw ) 2 | { 3 | if ( typeof sNewSource != 'undefined' && sNewSource != null ) 4 | { 5 | oSettings.sAjaxSource = sNewSource; 6 | } 7 | this.oApi._fnProcessingDisplay( oSettings, true ); 8 | var that = this; 9 | var iStart = oSettings._iDisplayStart; 10 | 11 | oSettings.fnServerData( oSettings.sAjaxSource, [], function(json) { 12 | /* Clear the old information from the table */ 13 | that.oApi._fnClearTable( oSettings ); 14 | 15 | /* Got the data - add it to the table */ 16 | var aData = (oSettings.sAjaxDataProp !== "") ? 17 | that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json; 18 | 19 | for ( var i=0 ; i 2 | 3 | 4 | 4.0.0 5 | javasimon-console-webapp 6 | war 7 | JavaSimon Web Console Application 8 | 9 | 10 | org.javasimon 11 | javasimon-parent 12 | 4.2.1-SNAPSHOT 13 | 14 | 15 | 16 | 17 | org.javasimon 18 | javasimon-console-embed 19 | ${project.version} 20 | 21 | 22 | org.javasimon 23 | javasimon-core 24 | 25 | 26 | 27 | 28 | org.javasimon 29 | javasimon-core 30 | ${project.version} 31 | provided 32 | 33 | 34 | 35 | 36 | ${project.artifactId} 37 | 38 | 39 | org.apache.maven.plugins 40 | maven-war-plugin 41 | 42 | false 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /spring/src/test/java/org/javasimon/spring/MonitoredPointcutStopwatchNameConfig.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring; 2 | 3 | import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 4 | import org.springframework.aop.support.DefaultPointcutAdvisor; 5 | import org.springframework.beans.factory.config.BeanPostProcessor; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * Configuration must be separated from {@link MonitoredPointcutStopwatchNameTest}, 11 | * because otherwise beans autowired there would not be post-processed by 12 | * {@link BeanPostProcessor}s, e.g. {@link DefaultAdvisorAutoProxyCreator} - and monitoring aspect 13 | * would not work. 14 | * 15 | * Both 16 | */ 17 | @Configuration 18 | public class MonitoredPointcutStopwatchNameConfig { 19 | 20 | @Bean 21 | public MonitoredService serviceOne() { 22 | return new ServiceOne(); 23 | } 24 | 25 | @Bean 26 | public MonitoredService serviceTwo() { 27 | return new ServiceTwo(); 28 | } 29 | 30 | @Bean 31 | public MonitoringInterceptor monitoringInterceptor() { 32 | return new MonitoringInterceptor(); 33 | } 34 | 35 | @Bean 36 | public DefaultPointcutAdvisor monitoringAdvisor(MonitoringInterceptor monitoringInterceptor) { 37 | DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(monitoringInterceptor); 38 | advisor.setPointcut(new MonitoredMeasuringPointcut()); 39 | return advisor; 40 | } 41 | 42 | @Bean 43 | public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { 44 | return new DefaultAdvisorAutoProxyCreator(); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /demoapp/src/main/webapp/style.css: -------------------------------------------------------------------------------- 1 | body, p, li, a { font-family: georgia, times, serif;font-size:13pt;} 2 | h1, h2, h3 { font-family: 'Yanone Kaffeesatz', arial, serif; } 3 | body { margin:0;padding:0;} 4 | #hd { 5 | width : 100%; 6 | height : 70px; 7 | background-color : #eef; 8 | margin-top : 0; 9 | padding-top : 15px; 10 | border-bottom : 1px solid #888; 11 | z-index : 0; 12 | } 13 | #ft { 14 | position : absolute; 15 | bottom : 0; 16 | width : 100%; 17 | height : 99px; 18 | background-color : #fed; 19 | border-top : 1px solid #888; 20 | z-index : 0; 21 | } 22 | #logo,#bd { 23 | width : 750px; 24 | margin: 0 auto; 25 | padding: 25px 50px 0 50px; 26 | } 27 | #logo h1 { 28 | color : black; 29 | font-size: 20pt; 30 | display: inline; 31 | } 32 | #logo img { 33 | display:inline; 34 | vertical-align: bottom; 35 | margin-left : 50px; 36 | margin-right : 5px; 37 | } 38 | body { margin-top : 0; padding-top : 0;} 39 | #logo, #logo h1 { margin-top : 0; padding-top : 0;} 40 | #bd { 41 | position : absolute; 42 | top : 70px; 43 | bottom : 75px; 44 | left : 50%; 45 | margin-left : -325px; 46 | z-index : 1; 47 | overflow: auto; 48 | background-color : #fff; 49 | -webkit-border-radius: 10px; 50 | -moz-border-radius: 10px; 51 | border-radius: 10px; 52 | -moz-box-shadow: 0px 0px 10px #888; 53 | -webkit-box-shadow: 0px 0px 10px #888; 54 | box-shadow: 0px 0px 10px #888; 55 | } 56 | a, a:visited, a:hover, a:active { 57 | color : #6493D2; 58 | } 59 | h2 { 60 | padding : 0; margin:0; 61 | font-size:20pt; 62 | color: #008; 63 | } 64 | h3 { 65 | padding : 0; margin:0; 66 | font-size:24pt; 67 | color:#092E67; 68 | } 69 | li { 70 | margin: 20px; 71 | } -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * {@link org.javasimon.callback.Callback} is an event listener registered with the {@link org.javasimon.Manager}, 3 | * listening for manager or Simon events. Any number of callbacks can be registered on a manager using 4 | * {@link org.javasimon.Manager#callback()} and {@link org.javasimon.callback.CompositeCallback#addCallback(Callback)}. 5 | *

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...)}.
  • 19 | *
20 | */ 21 | package org.javasimon.callback; 22 | -------------------------------------------------------------------------------- /console-embed/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | javasimon-console-embed 6 | jar 7 | JavaSimon Web Console Embedded 8 | 9 | 10 | org.javasimon 11 | javasimon-parent 12 | 4.2.1-SNAPSHOT 13 | 14 | 15 | 16 | 17 | org.javasimon 18 | javasimon-core 19 | ${project.version} 20 | 21 | 22 | javax.servlet 23 | servlet-api 24 | 2.5 25 | provided 26 | 27 | 28 | org.testng 29 | testng 30 | 31 | 32 | org.mockito 33 | mockito-core 34 | test 35 | 36 | 37 | org.json 38 | json 39 | 20090211 40 | test 41 | 42 | 43 | org.slf4j 44 | slf4j-jdk14 45 | 1.6.5 46 | test 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/utils/SimonUtilsTest.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.utils; 2 | 3 | 4 | import org.javasimon.SimonUnitTest; 5 | import org.testng.Assert; 6 | import org.testng.annotations.DataProvider; 7 | import org.testng.annotations.Test; 8 | 9 | 10 | /** 11 | * OtherTestNG. 12 | * 13 | * @author Richard "Virgo" Richter 14 | */ 15 | public final class SimonUtilsTest extends SimonUnitTest { 16 | 17 | @DataProvider(name = "test-data-utils") 18 | public Object[][] testDataUtilsProvider() { 19 | return new Object[][]{ 20 | {1, "1 ns"}, 21 | {47, "47 ns"}, 22 | {999, "999 ns"}, 23 | {1047, "1.05 us"}, 24 | {11047, "11.0 us"}, 25 | {11000, "11.0 us"}, 26 | {141047, "141 us"}, 27 | {942141047, "942 ms"}, 28 | {942141047666L, "942 s"}, 29 | {10942141047666L, "10942 s"}, 30 | }; 31 | } 32 | 33 | @Test(dataProvider = "test-data-utils") 34 | public void testUtilPresentNanoTime(long ns, String nsString) throws InterruptedException { 35 | Assert.assertEquals(SimonUtils.presentNanoTime(ns), nsString); 36 | } 37 | 38 | @Test 39 | public void testStringCompact() { 40 | Assert.assertEquals(SimonUtils.compact("asdfadfasd;a 345tw", 4), "as...w"); 41 | Assert.assertEquals(SimonUtils.compact("asdfadfasd;a 345tw", 7), "asd...w"); 42 | Assert.assertEquals(SimonUtils.compact("asdfadfasd;a 345tw", 12), "asdfad...5tw"); 43 | Assert.assertEquals(SimonUtils.compact("asdfadfasd;a 345tw", 17), "asdfadfa... 345tw"); 44 | Assert.assertEquals(SimonUtils.compact("asdfadfasd;a 345tw", 18), "asdfadfasd;a 345tw"); 45 | Assert.assertEquals(SimonUtils.compact("asdfadfasd;a 345tw", 30), "asdfadfasd;a 345tw"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/action/DetailPlugin.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.action; 2 | 3 | import org.javasimon.Simon; 4 | import org.javasimon.console.ActionContext; 5 | import org.javasimon.console.SimonConsolePlugin; 6 | import org.javasimon.console.json.ObjectJS; 7 | import org.javasimon.console.text.StringifierFactory; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * Base class for Detail plugins. 13 | * 14 | * @author gquintana 15 | */ 16 | public abstract class DetailPlugin extends SimonConsolePlugin { 17 | 18 | protected DetailPlugin(String id, String label) { 19 | super(id, label); 20 | } 21 | 22 | /** 23 | * Indicates this plugin applies to this kind of Simon. 24 | * 25 | * @param simon Simon 26 | * @return {@code true} if plugin can be executed 27 | */ 28 | public boolean supports(Simon simon) { 29 | return true; 30 | } 31 | 32 | /** 33 | * Callback for flat HTML rendering. 34 | * 35 | * @param context Context (Request, parameters...) 36 | * @param htmlBuilder HTML Builder (Response generation helper) 37 | * @param simon Simon to render. 38 | */ 39 | public DetailHtmlBuilder executeHtml(ActionContext context, DetailHtmlBuilder htmlBuilder, StringifierFactory htmlStringifierFactory, Simon simon) throws IOException { 40 | return htmlBuilder; 41 | } 42 | 43 | /** 44 | * Callback for flat JSON rendering. 45 | * 46 | * @param context Context (Request, parameters...) 47 | * @param simon Simon to render 48 | */ 49 | public ObjectJS executeJson(ActionContext context, StringifierFactory jsonStringifierFactory, Simon simon) { 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/logging/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * {@link org.javasimon.callback.logging.LoggingCallback} is able to log stopwatch splits and statistics once 3 | * in a while (N per millisecond, every N split, when split is longer than N ms, etc.) 4 | * and to various outputs (SLF4J, JUL). 5 | * These logging strategies are called log templates inherit from {@link org.javasimon.callback.logging.LogTemplate} and 6 | * are produced by {@link org.javasimon.callback.logging.LogTemplates} (factory class): 7 | *
    8 | *
  • {@link org.javasimon.callback.logging.SLF4JLogTemplate}: where → in SLF4J {@link org.slf4j.Logger}
  • 9 | *
  • {@link org.javasimon.callback.logging.JULLogTemplate}: where → in JUL {@link java.util.logging.Logger}
  • 10 | *
  • {@link org.javasimon.callback.logging.DisabledLogTemplate}: where → in /dev/null
  • 11 | *
  • {@link org.javasimon.callback.logging.DelegateLogTemplate}: abstract log template delegating to a concrete log template 12 | *
      13 | *
    • {@link org.javasimon.callback.logging.PeriodicLogTemplate}: when → every N milliseconds
    • 14 | *
    • {@link org.javasimon.callback.logging.CounterLogTemplate}: when → every N splits
    • 15 | *
    • {@link org.javasimon.callback.logging.SplitThresholdLogTemplate}: when → splits lasts longer than N milliseconds
    • 16 | *
    17 | *
  • 18 | *
19 | * Then {@link org.javasimon.callback.logging.LogMessageSource} is called back by 20 | * the LogTemplate to get the message (a String) to log: what. 21 | */ 22 | package org.javasimon.callback.logging; -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/source/AbstractStopwatchSource.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 | * Base implementation for {@link MonitorSource} producings stopwatches. 9 | * 10 | * @author gquintana 11 | */ 12 | public abstract class AbstractStopwatchSource implements StopwatchSource { 13 | /** 14 | * Simon manager used for producing Stopwatches. 15 | */ 16 | private final Manager manager; 17 | 18 | /** 19 | * Constructor with {@link Manager}. 20 | * 21 | * @param manager Simon manager used for producing Stopwatches 22 | */ 23 | public AbstractStopwatchSource(Manager manager) { 24 | this.manager = manager; 25 | } 26 | 27 | @Override 28 | public Manager getManager() { 29 | return manager; 30 | } 31 | 32 | /** 33 | * Default implementation returns always true. 34 | * 35 | * @return always true 36 | */ 37 | @Override 38 | public boolean isMonitored(T location) { 39 | return true; 40 | } 41 | 42 | /** 43 | * Get monitor name for the given location. 44 | */ 45 | protected abstract String getMonitorName(T location); 46 | 47 | /** 48 | * Provide a Stopwatch for given location. 49 | * 50 | * @param location Location 51 | * @return Stopwatch 52 | */ 53 | @Override 54 | public Stopwatch getMonitor(T location) { 55 | return manager.getStopwatch(getMonitorName(location)); 56 | } 57 | 58 | @Override 59 | public Split start(T location) { 60 | if (isMonitored(location)) { 61 | return getMonitor(location).start(); 62 | } 63 | return Split.DISABLED; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/AttributesSupport.java: -------------------------------------------------------------------------------- 1 | package org.javasimon; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.Map; 7 | import java.util.TreeMap; 8 | 9 | /** 10 | * Attributes implementation that creates attributes map lazily. Is synchronized to ensure thread-safety. 11 | * 12 | * @author Richard "Virgo" Richter 13 | * @since 3.4 14 | */ 15 | final class AttributesSupport implements HasAttributes { 16 | private Map attributes; 17 | 18 | @Override 19 | public synchronized void setAttribute(String name, Object value) { 20 | if (attributes == null) { 21 | attributes = new HashMap<>(); 22 | } 23 | attributes.put(name, value); 24 | } 25 | 26 | @Override 27 | public synchronized Object getAttribute(String name) { 28 | if (attributes == null) { 29 | return null; 30 | } 31 | return attributes.get(name); 32 | } 33 | 34 | @SuppressWarnings("unchecked") 35 | @Override 36 | public T getAttribute(String name, Class clazz) { 37 | return (T) getAttribute(name); 38 | } 39 | 40 | @Override 41 | public synchronized void removeAttribute(String name) { 42 | if (attributes != null) { 43 | attributes.remove(name); 44 | } 45 | } 46 | 47 | @Override 48 | public synchronized Iterator getAttributeNames() { 49 | if (attributes == null) { 50 | return Collections.emptySet().iterator(); 51 | } 52 | return attributes.keySet().iterator(); 53 | } 54 | 55 | @Override 56 | public Map getCopyAsSortedMap() { 57 | return new TreeMap<>(attributes); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/logging/CounterLogTemplate.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.logging; 2 | 3 | /** 4 | * Log template that logs something every N invocations of the {@link #isEnabled(Object)} method. 5 | * 6 | * @author gquintana 7 | */ 8 | public class CounterLogTemplate extends DelegateLogTemplate { 9 | 10 | /** Counter max value corresponds to N value. */ 11 | private final int counterMax; 12 | /** Counter value. */ 13 | private int counter; 14 | 15 | /** 16 | * Constructor. 17 | * 18 | * @param delegate Concrete log template 19 | * @param counterMax Logging period 20 | */ 21 | public CounterLogTemplate(LogTemplate delegate, int counterMax) { 22 | super(delegate); 23 | this.counterMax = counterMax; 24 | this.counter = 1; 25 | } 26 | 27 | /** 28 | * Returns counter max value, corresponding to logging period. 29 | * 30 | * @return Counter max 31 | */ 32 | public int getCounterMax() { 33 | return counterMax; 34 | } 35 | 36 | /** 37 | * Returns counter value. 38 | * 39 | * @return counter value 40 | */ 41 | public int getCounter() { 42 | return counter; 43 | } 44 | 45 | /** 46 | * Increments counter. 47 | * 48 | * @return true if counter looped and returned to 0 49 | */ 50 | private boolean incrementCounter() { 51 | boolean loop = (counter >= counterMax); 52 | counter = loop ? 1 : counter + 1; 53 | return loop; 54 | } 55 | 56 | @Override 57 | protected boolean isEnabled(C context) { 58 | return super.isEnabled(context) && incrementCounter(); 59 | } 60 | 61 | @Override 62 | protected void log(String message) { 63 | super.log(message); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /examples/src/main/java/org/javasimon/examples/jmx/custom/CustomStopwatchMXBeanImpl.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.examples.jmx.custom; 2 | 3 | import org.javasimon.Stopwatch; 4 | import org.javasimon.clock.SimonClock; 5 | import org.javasimon.jmx.StopwatchMXBeanImpl; 6 | 7 | /** 8 | * Customized Stopwatch JMX bean displaying values in milliseconds. 9 | * 10 | * @author Gerald Quintana 11 | */ 12 | public class CustomStopwatchMXBeanImpl extends StopwatchMXBeanImpl implements CustomStopwatchMXBean { 13 | public CustomStopwatchMXBeanImpl(Stopwatch stopwatch) { 14 | super(stopwatch); 15 | } 16 | 17 | private double nanosToMillis(double nanos) { 18 | return nanos / SimonClock.NANOS_IN_MILLIS; 19 | } 20 | 21 | private long nanosToMillis(long nanos) { 22 | return nanos / SimonClock.NANOS_IN_MILLIS; 23 | } 24 | 25 | @Override 26 | public double getMeanInMillis() { 27 | return nanosToMillis(stopwatch.getMean()); 28 | } 29 | 30 | @Override 31 | public long getMinInMillis() { 32 | return nanosToMillis(stopwatch.getMin()); 33 | } 34 | 35 | @Override 36 | public long getMaxInMillis() { 37 | return nanosToMillis(stopwatch.getMax()); 38 | } 39 | 40 | @Override 41 | public long getTotalInMillis() { 42 | return nanosToMillis(stopwatch.getTotal()); 43 | } 44 | 45 | @Override 46 | public long getLastInMillis() { 47 | return nanosToMillis(stopwatch.getLast()); 48 | } 49 | 50 | @Override 51 | public long getCounter() { 52 | return stopwatch.getCounter(); 53 | } 54 | 55 | @Override 56 | public double getStandardDeviationInMillis() { 57 | return nanosToMillis(stopwatch.getStandardDeviation()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /spring/doc/monitoring.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 40 | 41 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/Action.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console; 2 | 3 | import java.io.IOException; 4 | import java.io.UnsupportedEncodingException; 5 | import java.net.URLDecoder; 6 | import javax.servlet.ServletException; 7 | 8 | import org.javasimon.Simon; 9 | 10 | /** 11 | * Base class for actions (controller+model) 12 | * 13 | * @author gquintana 14 | */ 15 | public abstract class Action { 16 | 17 | /** 18 | * Action context (request, response & more) 19 | */ 20 | private final ActionContext context; 21 | 22 | public Action(ActionContext context) { 23 | this.context = context; 24 | } 25 | 26 | public ActionContext getContext() { 27 | return context; 28 | } 29 | 30 | /** 31 | * Parse HTTP Request parameters and store them locally 32 | */ 33 | public void readParameters() { 34 | } 35 | 36 | /** 37 | * Execute action 38 | */ 39 | public abstract void execute() throws ServletException, IOException, ActionException; 40 | 41 | // mainly for IE8 42 | protected void dontCache() { 43 | getContext().getResponse().setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate"); 44 | getContext().getResponse().setHeader("Pragma", "no-cache"); 45 | } 46 | 47 | protected Simon findSimonByName(String name) { 48 | Simon simon = context.getManager().getSimon(name); 49 | if (simon == null) { 50 | try { 51 | final String nameDecoded = URLDecoder.decode(name, context.getCharacterEncoding()); 52 | if (!name.equals(nameDecoded)) { 53 | simon = context.getManager().getSimon(nameDecoded); 54 | } 55 | } catch (UnsupportedEncodingException e) { 56 | // pass 57 | } 58 | } 59 | return simon; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/timeline/TimeRange.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.timeline; 2 | 3 | import org.javasimon.utils.SimonUtils; 4 | 5 | /** 6 | * Time range and associated data. 7 | * 8 | * @author gerald 9 | */ 10 | public class TimeRange { 11 | /** 12 | * Beginning of the time range 13 | */ 14 | private final long startTimestamp; 15 | 16 | /** 17 | * Ending of the time range 18 | */ 19 | private final long endTimestamp; 20 | 21 | /** 22 | * Timestamp of last change 23 | */ 24 | protected long lastTimestamp; 25 | 26 | /** 27 | * Main constructor. 28 | * 29 | * @param startTimestamp Beginning of the time range 30 | * @param endTimestamp Ending of the time range 31 | */ 32 | protected TimeRange(long startTimestamp, long endTimestamp) { 33 | this.startTimestamp = startTimestamp; 34 | this.endTimestamp = endTimestamp; 35 | } 36 | 37 | public long getStartTimestamp() { 38 | return startTimestamp; 39 | } 40 | 41 | public long getEndTimestamp() { 42 | return endTimestamp; 43 | } 44 | 45 | /** 46 | * Indicates whether this time range contains given timestamp. 47 | * 48 | * @param timestampInMs Timestamp express in milliseconds 49 | */ 50 | public boolean containsTimestamp(long timestampInMs) { 51 | return timestampInMs >= startTimestamp && timestampInMs <= endTimestamp; 52 | } 53 | 54 | protected StringBuilder toStringBuilder(StringBuilder stringBuilder) { 55 | return stringBuilder.append(getClass().getSimpleName()) 56 | .append(" start=").append(SimonUtils.presentTimestamp(startTimestamp)) 57 | .append(" end=").append(SimonUtils.presentTimestamp(endTimestamp)); 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return toStringBuilder(new StringBuilder()).toString(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /examples/src/main/java/org/javasimon/examples/CallbackExample.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.examples; 2 | 3 | import org.javasimon.SimonManager; 4 | import org.javasimon.Split; 5 | import org.javasimon.Stopwatch; 6 | import org.javasimon.StopwatchSample; 7 | import org.javasimon.callback.CallbackSkeleton; 8 | import org.javasimon.utils.SimonUtils; 9 | 10 | /** 11 | * CallbackExample shows how to implement callback that prints out some information on the specific events. 12 | * 13 | * @author Richard "Virgo" Richter 14 | */ 15 | public final class CallbackExample { 16 | /** 17 | * Entry point to the Callback Example. 18 | * 19 | * @param args unused 20 | */ 21 | public static void main(String[] args) { 22 | SimonManager.callback().addCallback(new CallbackSkeleton() { 23 | @Override 24 | public void onStopwatchStart(Split split) { 25 | System.out.println("\nStopwatch " + split.getStopwatch().getName() + " has just been started."); 26 | } 27 | 28 | @Override 29 | public void onStopwatchStop(Split split, StopwatchSample sample) { 30 | System.out.println("Stopwatch " + split.getStopwatch().getName() 31 | + " has just been stopped (" + SimonUtils.presentNanoTime(split.runningFor()) + ")."); 32 | } 33 | }); 34 | 35 | Stopwatch sw = SimonManager.getStopwatch(SimonUtils.generateName()); 36 | sw.start().stop(); 37 | 38 | Split split = sw.start(); 39 | //noinspection StatementWithEmptyBody 40 | for (int i = 0; i < 1000000; i++) { 41 | // what does JVM do with empty loop? :-))) 42 | } 43 | split.stop(); 44 | 45 | sw.start().stop(); 46 | 47 | System.out.println("\nAdditional stop() does nothing, Split state is preserved."); 48 | split.stop(); 49 | System.out.println("split = " + split); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/proxy/DelegatingMethodInvocation.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.proxy; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.concurrent.Callable; 5 | 6 | /** 7 | * Proxy method invocation. 8 | * 9 | * @author gquintana 10 | */ 11 | public class DelegatingMethodInvocation implements Delegating, Runnable, Callable { 12 | 13 | /** Target (real) object. */ 14 | private final T delegate; 15 | 16 | /** Proxy. */ 17 | private final Object proxy; 18 | 19 | /** Method. */ 20 | private final Method method; 21 | 22 | /** Invocation arguments. */ 23 | private final Object[] args; 24 | 25 | public DelegatingMethodInvocation(T target, Object proxy, Method method, Object... args) { 26 | this.delegate = target; 27 | this.proxy = proxy; 28 | this.method = method; 29 | this.args = args; 30 | } 31 | 32 | public Object[] getArgs() { 33 | return args; 34 | } 35 | 36 | public Method getMethod() { 37 | return method; 38 | } 39 | 40 | public Object getProxy() { 41 | return proxy; 42 | } 43 | 44 | public T getDelegate() { 45 | return delegate; 46 | } 47 | 48 | public Method getTargetMethod() throws NoSuchMethodException { 49 | return delegate.getClass().getMethod(method.getName(), method.getParameterTypes()); 50 | } 51 | 52 | public Object proceed() throws Throwable { 53 | return method.invoke(delegate, args); 54 | } 55 | 56 | public void run() { 57 | try { 58 | proceed(); 59 | } catch (Throwable throwable) { 60 | // Forget exception 61 | } 62 | } 63 | 64 | public Object call() throws Exception { 65 | try { 66 | return proceed(); 67 | } catch (Exception exception) { 68 | throw exception; 69 | } catch (Throwable throwable) { 70 | throw new IllegalStateException(throwable); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/callback/timeline/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.timeline; 2 | 3 | import org.javasimon.Split; 4 | import org.javasimon.clock.SimonClock; 5 | import org.javasimon.clock.SimonClockUtils; 6 | 7 | import java.lang.reflect.Field; 8 | import java.util.Calendar; 9 | 10 | /** 11 | * @author gerald 12 | */ 13 | public final class TimeUtil { 14 | 15 | public static long createTimestamp(int year, int month, int day, int hour, int minutes, int seconds) { 16 | Calendar calendar = Calendar.getInstance(); 17 | calendar.clear(); 18 | calendar.set(Calendar.YEAR, year); 19 | calendar.set(Calendar.MONTH, month - 1); 20 | calendar.set(Calendar.DAY_OF_MONTH, day); 21 | calendar.set(Calendar.HOUR_OF_DAY, hour); 22 | calendar.set(Calendar.MINUTE, minutes); 23 | calendar.set(Calendar.SECOND, seconds); 24 | return calendar.getTimeInMillis(); 25 | } 26 | 27 | public static long millisToNano(long millis) { 28 | return SimonClockUtils.INIT_NANOS + (millis - SimonClockUtils.INIT_MILLIS) * SimonClock.NANOS_IN_MILLIS; 29 | } 30 | 31 | private static void setField(Object object, String fieldName, Object fieldValue) { 32 | try { 33 | Field field = object.getClass().getDeclaredField(fieldName); 34 | field.setAccessible(true); 35 | field.set(object, fieldValue); 36 | } catch (Exception ex) { 37 | throw new IllegalStateException(ex); 38 | } 39 | } 40 | 41 | public static void addSplit(StopwatchTimeRange timeRange, long start, long total) { 42 | timeRange.addSplit(start, total); 43 | } 44 | 45 | public static Split createSplit(long start, long total) { 46 | Split split = Split.start(); 47 | setField(split, "start", millisToNano(start)); 48 | setField(split, "running", false); 49 | setField(split, "total", total); 50 | return split; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/source/AbstractMethodStopwatchSource.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.source; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.javasimon.Manager; 6 | 7 | /** 8 | * Base class for Stopwatch sources working on method locations. 9 | * 10 | * @author gquintana 11 | */ 12 | public abstract class AbstractMethodStopwatchSource extends AbstractStopwatchSource { 13 | 14 | /** 15 | * Constructor using specific simon manager. 16 | * 17 | * @param manager Simon manager 18 | */ 19 | public AbstractMethodStopwatchSource(Manager manager) { 20 | super(manager); 21 | } 22 | 23 | /** 24 | * Get target class from location. 25 | * 26 | * @param location Location 27 | * @return Target class 28 | */ 29 | protected abstract Class getTargetClass(T location); 30 | 31 | /** 32 | * Get target method from location. 33 | * 34 | * @param location Location 35 | * @return Target method 36 | */ 37 | protected abstract Method getTargetMethod(T location); 38 | 39 | /** 40 | * Wraps this data source in a cache. 41 | * 42 | * @return Cache monitor source 43 | */ 44 | public CachedStopwatchSource cache() { 45 | return newCacheStopwatchSource(this); 46 | } 47 | 48 | /** 49 | * Wraps given stopwatch source in a cache. 50 | * 51 | * @param stopwatchSource Stopwatch source 52 | * @return Cached stopwatch source 53 | */ 54 | private static CachedStopwatchSource newCacheStopwatchSource(final AbstractMethodStopwatchSource stopwatchSource) { 55 | return new CachedStopwatchSource(stopwatchSource) { 56 | @Override 57 | protected Method getLocationKey(T location) { 58 | return stopwatchSource.getTargetMethod(location); 59 | } 60 | }; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /examples/src/main/java/org/javasimon/examples/SamplingExample.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 | * SamplingExample uses one stopwatch to measure one method (random duration) and this stopwatch is sampled 9 | * with 10s period. 10 | * 11 | * @author Richard "Virgo" Richter 12 | */ 13 | @SuppressWarnings({"InfiniteLoopStatement"}) 14 | public final class SamplingExample { 15 | 16 | private SamplingExample() { 17 | } 18 | 19 | /** 20 | * Entry point of the demo application. 21 | * 22 | * @param args command line arguments 23 | */ 24 | public static void main(String[] args) { 25 | // Starts the sampler 26 | Sampler sampler = new Sampler(); 27 | sampler.setDaemon(true); 28 | sampler.start(); 29 | 30 | // Starts the measuring 31 | while (true) { 32 | try (Split ignored = SimonManager.getStopwatch("sampled-stopwatch").start()) { 33 | ExampleUtils.waitRandomlySquared(50); 34 | } 35 | } 36 | } 37 | 38 | /** 39 | * Prints sampled values from the stopwatch every 10 seconds. 40 | */ 41 | static class Sampler extends Thread { 42 | /** 43 | * Method implementing the code of the thread. 44 | */ 45 | public void run() { 46 | while (true) { 47 | Stopwatch stopwatch = SimonManager.getStopwatch("sampled-stopwatch"); 48 | System.out.println("\nstopwatch = " + stopwatch); 49 | System.out.println("Stopwatch sample: " + stopwatch.sample()); 50 | System.out.println("Stopwatch sample - incremental: " + stopwatch.sampleIncrement("myIncrementalKey")); 51 | try { 52 | Thread.sleep(10000); 53 | } catch (InterruptedException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/logging/JULLogTemplate.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.logging; 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger; 5 | 6 | /** 7 | * Concrete log template using {@link Logger}. 8 | * 9 | * @author gquintana 10 | */ 11 | public class JULLogTemplate extends LogTemplate { 12 | 13 | /** Target log template. */ 14 | private final Logger logger; 15 | /** Logging level. */ 16 | private Level level; 17 | 18 | /** 19 | * Constructor. 20 | * 21 | * @param logger Logger 22 | * @param level Level 23 | */ 24 | public JULLogTemplate(Logger logger, Level level) { 25 | this.logger = logger; 26 | this.level = level; 27 | } 28 | 29 | /** 30 | * Constructor. 31 | * 32 | * @param loggerName Logger name 33 | * @param level Level 34 | */ 35 | public JULLogTemplate(String loggerName, Level level) { 36 | this(Logger.getLogger(loggerName), level); 37 | } 38 | 39 | /** 40 | * Returns log level. 41 | * 42 | * @return log level 43 | */ 44 | public Level getLevel() { 45 | return level; 46 | } 47 | 48 | /** 49 | * Changes log level. 50 | * 51 | * @param level new log level 52 | */ 53 | public void setLevel(Level level) { 54 | this.level = level; 55 | } 56 | 57 | /** 58 | * Get logger 59 | * 60 | * @return Logger 61 | */ 62 | public Logger getLogger() { 63 | return logger; 64 | } 65 | 66 | /** 67 | * {@inheritDoc } 68 | *

69 | * Logger is enabled if underlying logger is {@link Logger#isLoggable} is true for current level. 70 | */ 71 | protected boolean isEnabled(C context) { 72 | return logger.isLoggable(level); 73 | } 74 | 75 | protected void log(String message) { 76 | logger.log(level, message); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/quantiles/FixedQuantilesCallback.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.quantiles; 2 | 3 | import org.javasimon.Stopwatch; 4 | import org.javasimon.clock.SimonClock; 5 | 6 | /** 7 | * Callback which stores data in buckets to compute quantiles. 8 | * Buckets are create using constant configuration. 9 | * 10 | * @author gquintana 11 | */ 12 | public class FixedQuantilesCallback extends QuantilesCallback { 13 | 14 | /** Buckets lower bound in milliseconds. */ 15 | private final long min; 16 | /** Buckets upper bound in milliseconds. */ 17 | private final long max; 18 | /** Number of buckets. */ 19 | private final int bucketNb; 20 | 21 | /** Main constructor. */ 22 | public FixedQuantilesCallback(long min, long max, int bucketNb) { 23 | this.min = min; 24 | this.max = max; 25 | this.bucketNb = bucketNb; 26 | } 27 | 28 | /** 29 | * Constructor with all configuration 30 | * 31 | * @param bucketsType Linear or exponential 32 | * @param min Min 33 | * @param max Max 34 | * @param bucketNb Number of buckets 35 | */ 36 | public FixedQuantilesCallback(BucketsType bucketsType, long min, long max, int bucketNb) { 37 | super(bucketsType); 38 | this.min = min; 39 | this.max = max; 40 | this.bucketNb = bucketNb; 41 | } 42 | 43 | /** 44 | * Create buckets using callback attributes 45 | * 46 | * @param stopwatch Target stopwatch 47 | * @return Created buckets 48 | */ 49 | @Override 50 | protected Buckets createBuckets(Stopwatch stopwatch) { 51 | return createBuckets(stopwatch, min * SimonClock.NANOS_IN_MILLIS, max * SimonClock.NANOS_IN_MILLIS, bucketNb); 52 | } 53 | 54 | public long getMin() { 55 | return min; 56 | } 57 | 58 | public long getMax() { 59 | return max; 60 | } 61 | 62 | public int getBucketNb() { 63 | return bucketNb; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/action/TreeJsonAction.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.action; 2 | 3 | import java.io.IOException; 4 | 5 | import org.javasimon.Simon; 6 | import org.javasimon.console.ActionContext; 7 | import org.javasimon.console.json.ArrayJS; 8 | import org.javasimon.console.json.ObjectJS; 9 | 10 | /** 11 | * Export Simons as a hierarchical JSON object for display in a tree-table. 12 | * All attributes of simons are exported. 13 | * 14 | * @author gquintana 15 | */ 16 | public class TreeJsonAction extends AbstractJsonAction { 17 | 18 | public static final String PATH = "/data/tree.json"; 19 | 20 | /** 21 | * Name of the simon from where to start. 22 | * {@code null} means root. 23 | */ 24 | private String name; 25 | 26 | /** @noinspection WeakerAccess*/ 27 | public TreeJsonAction(ActionContext context) { 28 | super(context); 29 | } 30 | 31 | @Override 32 | public void readParameters() { 33 | super.readParameters(); 34 | name = getContext().getParameterAsString("name", null); 35 | } 36 | 37 | @Override 38 | protected ObjectJS createObjectJS(Simon simon) { 39 | ObjectJS simonJS = super.createObjectJS(simon); 40 | ArrayJS childrenJS = new ArrayJS(); 41 | for (Simon child : simon.getChildren()) { 42 | ObjectJS childJS = createObjectJS(child); 43 | childrenJS.addElement(childJS); 44 | } 45 | simonJS.setAttribute("children", childrenJS); 46 | return simonJS; 47 | } 48 | 49 | @Override 50 | public void execute() throws IOException { 51 | getContext().setContentType("application/json"); 52 | Simon simon = name == null ? getContext().getManager().getRootSimon() : findSimonByName(name); 53 | ObjectJS simonRootJS = createObjectJS(simon); 54 | simonRootJS.write(getContext().getWriter()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /spring/src/main/java/org/javasimon/spring/webmvc/HandlerStopwatchSource.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring.webmvc; 2 | 3 | import org.javasimon.Manager; 4 | import org.javasimon.source.AbstractStopwatchSource; 5 | 6 | import org.springframework.web.method.HandlerMethod; 7 | 8 | /** 9 | * Stopwatch source for Spring MVC handlers. 10 | * 11 | * @author gquintana 12 | */ 13 | public class HandlerStopwatchSource extends AbstractStopwatchSource { 14 | /** 15 | * Prefix used for Simon names. 16 | */ 17 | private static final String PREFIX = "org.javasimon.mvc"; 18 | 19 | /** 20 | * Suffix used for Simon names of Controllers. 21 | */ 22 | private static final String CONTROLLER_SUFFIX = "ctrl"; 23 | 24 | /** 25 | * Suffix used for Simon names of Views. 26 | */ 27 | private static final String VIEW_SUFFIX = "view"; 28 | 29 | public HandlerStopwatchSource(Manager manager) { 30 | super(manager); 31 | } 32 | 33 | @Override 34 | protected String getMonitorName(HandlerLocation t) { 35 | StringBuilder stringBuilder = new StringBuilder(PREFIX).append("."); 36 | // Append controller type 37 | if (t.getHandler() instanceof HandlerMethod) { 38 | HandlerMethod handlerMethod = (HandlerMethod) t.getHandler(); 39 | stringBuilder.append(handlerMethod.getBeanType().getSimpleName()) 40 | .append(".").append(handlerMethod.getMethod().getName()); 41 | } else { 42 | stringBuilder.append(t.getHandler().getClass().getSimpleName()); 43 | } 44 | // Append step 45 | stringBuilder.append("."); 46 | switch (t.getStep()) { 47 | case CONTROLLER: 48 | stringBuilder.append(CONTROLLER_SUFFIX); 49 | break; 50 | case VIEW: 51 | stringBuilder.append(VIEW_SUFFIX); 52 | break; 53 | } 54 | return stringBuilder.toString(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /examples/src/main/java/org/javasimon/examples/jmx/JmxCallbackExample.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.examples.jmx; 2 | 3 | import org.javasimon.Counter; 4 | import org.javasimon.SimonManager; 5 | import org.javasimon.Split; 6 | import org.javasimon.Stopwatch; 7 | import org.javasimon.examples.ExampleUtils; 8 | import org.javasimon.jmx.JmxRegisterCallback; 9 | 10 | /** 11 | * JmxCallbackExample demonstrates {@link JmxRegisterCallback} in action. It creates one Counter 12 | * and one Stopwatch that can be monitored via {@code jconsole} or any other/custom JMX client. 13 | * 14 | * @author Richard "Virgo" Richter 15 | */ 16 | public final class JmxCallbackExample { 17 | /** 18 | * Entry point to the JMX Callback Example. 19 | * 20 | * @param args unused 21 | * @throws Exception whatever may happen in this crazy world 22 | */ 23 | @SuppressWarnings("InfiniteLoopStatement") 24 | public static void main(String[] args) throws Exception { 25 | SimonManager.callback().addCallback(new JmxRegisterCallback("org.javasimon.examples.jmx.JmxCallbackExample")); 26 | 27 | Counter counter = SimonManager.getCounter("org.javasimon.examples.jmx.counter"); 28 | Stopwatch stopwatch = SimonManager.getStopwatch("org.javasimon.examples.jmx.stopwatch"); 29 | // these created just to have more stuff in jconsole 30 | SimonManager.getCounter("org.javasimon.different.counter"); 31 | SimonManager.getStopwatch("org.javasimon.some.other.jmx.stopwatch1"); 32 | SimonManager.getStopwatch("org.javasimon.some.other.jmx.stopwatch2"); 33 | System.out.println("Now open jconsole and check it out...\nWatch org.javasimon.examples.jmx.stopwatch for changes."); 34 | while (true) { 35 | counter.increase(); 36 | try (Split ignored = stopwatch.start()) { 37 | ExampleUtils.waitRandomlySquared(40); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/SimonTest.java: -------------------------------------------------------------------------------- 1 | package org.javasimon; 2 | 3 | import org.testng.Assert; 4 | import org.testng.annotations.Test; 5 | 6 | import java.util.Iterator; 7 | 8 | /** 9 | * Tests for common {@link Simon} interface functionality. 10 | * 11 | * @author Richard "Virgo" Richter 12 | */ 13 | public final class SimonTest extends SimonUnitTest { 14 | 15 | private static final String STOPWATCH_NAME = "org.javasimon.test-stopwatch"; 16 | 17 | @Test 18 | public void attributesTest() { 19 | Simon simon = SimonManager.getStopwatch(STOPWATCH_NAME); 20 | Assert.assertFalse(simon.getAttributeNames().hasNext()); 21 | Assert.assertNull(simon.getAttribute("key")); 22 | simon.setAttribute("key", "value"); 23 | Iterator attributeNamesIterator = simon.getAttributeNames(); 24 | Assert.assertTrue(attributeNamesIterator.hasNext()); 25 | Assert.assertEquals(attributeNamesIterator.next(), "key"); 26 | Assert.assertFalse(attributeNamesIterator.hasNext()); 27 | Assert.assertEquals(simon.getAttribute("key"), "value"); 28 | 29 | // with existing attributes, null Simon should return nothing 30 | SimonManager.disable(); 31 | Simon nullSimon = SimonManager.getStopwatch(STOPWATCH_NAME); 32 | Assert.assertFalse(nullSimon.getAttributeNames().hasNext()); 33 | Assert.assertNull(nullSimon.getAttribute("key")); 34 | SimonManager.enable(); 35 | 36 | // after manager re-enable, it should be ok again 37 | simon = SimonManager.getStopwatch(STOPWATCH_NAME); 38 | Assert.assertTrue(simon.getAttributeNames().hasNext()); 39 | Assert.assertEquals(simon.getAttribute(simon.getAttributeNames().next()), "value"); 40 | 41 | // after removal... 42 | simon.removeAttribute("key"); 43 | Assert.assertFalse(simon.getAttributeNames().hasNext()); 44 | Assert.assertNull(simon.getAttribute("key")); 45 | } 46 | } -------------------------------------------------------------------------------- /jdbc41/src/main/java/org/javasimon/jdbcx4/SimonConnectionPoolDataSource.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.jdbcx4; 2 | 3 | import java.sql.SQLException; 4 | import java.sql.SQLFeatureNotSupportedException; 5 | import java.util.logging.Logger; 6 | import javax.sql.ConnectionPoolDataSource; 7 | import javax.sql.PooledConnection; 8 | 9 | /** 10 | * Wrapper class for real ConnectionPoolDataSource implementation, produces pooled 11 | * {@link javax.sql.PooledConnection} object. 12 | *

13 | * See the {@link SimonDataSource} for more information. 14 | * 15 | * @author Radovan Sninsky 16 | * @author Richard "Virgo" Richter 17 | * @since 2.4 18 | */ 19 | public final class SimonConnectionPoolDataSource extends AbstractSimonDataSource implements ConnectionPoolDataSource { 20 | private ConnectionPoolDataSource ds; 21 | 22 | private ConnectionPoolDataSource datasource() throws SQLException { 23 | if (ds == null) { 24 | ds = createDataSource(ConnectionPoolDataSource.class); 25 | } 26 | return ds; 27 | } 28 | 29 | @Override 30 | public PooledConnection getPooledConnection() throws SQLException { 31 | return new SimonPooledConnection(datasource().getPooledConnection(), getPrefix()).withSqlNormalizerFactory(sqlNormalizerFactory); 32 | } 33 | 34 | @Override 35 | public PooledConnection getPooledConnection(String user, String password) throws SQLException { 36 | return new SimonPooledConnection(datasource().getPooledConnection(user, password), getPrefix()).withSqlNormalizerFactory(sqlNormalizerFactory); 37 | } 38 | 39 | @Override 40 | protected String doGetRealDataSourceClassName() { 41 | return configuration.getRealConnectionPoolDataSourceName(); 42 | } 43 | 44 | @Override 45 | public Logger getParentLogger() throws SQLFeatureNotSupportedException { 46 | return ds.getParentLogger(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/proxy/StopwatchProxyFactory.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.proxy; 2 | 3 | import org.javasimon.Split; 4 | import org.javasimon.source.StopwatchSource; 5 | 6 | /** 7 | * Stopwatch proxy factory can generate a proxy to wrap an existing class and monitor its performance. 8 | * Sample usage: 9 | *

10 |  * MonitoredInterface monitoredProxy=new StopwatchProxyFactory(monitoredImplementation).newProxy(MonitoredInterface.class);
11 | * or 12 | *
13 |  * MonitoredInterface monitoredProxy=new StopwatchProxyFactory(monitoredImplementation, new CustomProxyStopwatchSource<MonitoredInterface>()).newProxy(MonitoredInterface.class);
14 | */ 15 | public final class StopwatchProxyFactory extends DelegatingProxyFactory { 16 | /** 17 | * Stopwatch template. 18 | */ 19 | private final StopwatchSource> stopwatchSource; 20 | 21 | /** 22 | * Constructor 23 | * 24 | * @param delegate Wrapped object 25 | * @param stopwatchSource Stopwatch source (to configure Stopwatch naming) 26 | */ 27 | public StopwatchProxyFactory(T delegate, StopwatchSource> stopwatchSource) { 28 | super(delegate); 29 | this.stopwatchSource = stopwatchSource; 30 | } 31 | 32 | /** 33 | * Constructor. 34 | * 35 | * @param delegate Wrapped object 36 | */ 37 | public StopwatchProxyFactory(T delegate) { 38 | this(delegate, new ProxyStopwatchSource()); 39 | } 40 | 41 | /** 42 | * Invocation handler main method. 43 | */ 44 | @Override 45 | protected Object invoke(DelegatingMethodInvocation methodInvocation) throws Throwable { 46 | final Split split = stopwatchSource.start(methodInvocation); 47 | try { 48 | return methodInvocation.proceed(); 49 | } finally { 50 | split.stop(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /console-embed/src/test/java/org/javasimon/console/json/ObjectJSTest.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.json; 2 | 3 | import org.javasimon.console.TimeFormatType; 4 | 5 | import org.testng.annotations.BeforeMethod; 6 | import org.testng.annotations.Test; 7 | 8 | import static org.testng.Assert.assertEquals; 9 | import static org.testng.Assert.assertNotNull; 10 | 11 | /** 12 | * Unit test for {@link ObjectJS} 13 | * 14 | * @author gquintana 15 | */ 16 | public class ObjectJSTest { 17 | class Foo { 18 | private long bar; 19 | private String baz; 20 | 21 | public Foo(long bar, String baz) { 22 | this.bar = bar; 23 | this.baz = baz; 24 | } 25 | 26 | public long getBar() { 27 | return bar; 28 | } 29 | 30 | public String getBaz() { 31 | return baz; 32 | } 33 | 34 | } 35 | 36 | private JsonStringifierFactory stringifierFactory = new JsonStringifierFactory(); 37 | 38 | @BeforeMethod 39 | public void setUp() { 40 | stringifierFactory.init(TimeFormatType.MILLISECOND, JsonStringifierFactory.READABLE_DATE_PATTERN, JsonStringifierFactory.READABLE_NUMBER_PATTERN); 41 | } 42 | 43 | @Test 44 | public void testCreate() { 45 | Foo foo = new Foo(123L, "Hello"); 46 | ObjectJS fooJS = ObjectJS.create(foo, stringifierFactory); 47 | assertNotNull(fooJS.getAttribute("bar")); 48 | assertEquals(((SimpleJS) fooJS.getAttribute("bar")).getValue(), 123L); 49 | assertNotNull(fooJS.getAttribute("baz")); 50 | assertEquals(((SimpleJS) fooJS.getAttribute("baz")).getValue(), "Hello"); 51 | } 52 | 53 | @Test 54 | public void testWrite() { 55 | Foo foo = new Foo(123L, "Hello"); 56 | ObjectJS fooJS = ObjectJS.create(foo, stringifierFactory); 57 | assertEquals(fooJS.getAttribute("baz").toString(), "\"Hello\""); 58 | assertEquals(Integer.parseInt(fooJS.getAttribute("bar").toString()), 123); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /console-embed/src/test/java/org/javasimon/console/action/ListJsonActionTest.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console.action; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | import static org.testng.Assert.assertTrue; 5 | 6 | import org.javasimon.console.SimonData; 7 | import org.javasimon.console.TestActionContext; 8 | import org.json.JSONArray; 9 | import org.json.JSONObject; 10 | import org.json.JSONTokener; 11 | import org.testng.annotations.BeforeClass; 12 | import org.testng.annotations.Test; 13 | 14 | import java.util.HashSet; 15 | import java.util.Set; 16 | 17 | /** 18 | * Unit test for {@link ListJsonAction} 19 | * 20 | * @author gquintana 21 | */ 22 | public class ListJsonActionTest { 23 | 24 | @BeforeClass 25 | public static void setUpClass() { 26 | SimonData.initialize(); 27 | } 28 | 29 | @Test 30 | public void testExecute() throws Exception { 31 | TestActionContext context = new TestActionContext("/data/table.json"); 32 | ListJsonAction action = new ListJsonAction(context); 33 | action.readParameters(); 34 | action.execute(); 35 | assertEquals(context.getContentType(), "application/json"); 36 | String json = context.toString(); 37 | // Test JSON format with an external library 38 | JSONTokener jsonTokener = new JSONTokener(json); 39 | Set names = new HashSet<>(); 40 | names.add("A"); 41 | names.add("B"); 42 | names.add("C"); 43 | Object object = jsonTokener.nextValue(); 44 | if (object instanceof JSONArray) { 45 | JSONArray jsonArray = (JSONArray) object; 46 | for (int i = 0; i < jsonArray.length(); i++) { 47 | object = jsonArray.get(i); 48 | if (object instanceof JSONObject) { 49 | JSONObject jsonObject = (JSONObject) object; 50 | String name = jsonObject.getString("name"); 51 | names.remove(name); 52 | } 53 | } 54 | } 55 | assertTrue(names.isEmpty()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /core/src/main/java/org/javasimon/callback/CallbackSkeleton.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback; 2 | 3 | import org.javasimon.Counter; 4 | import org.javasimon.CounterSample; 5 | import org.javasimon.Manager; 6 | import org.javasimon.Simon; 7 | import org.javasimon.Split; 8 | import org.javasimon.Stopwatch; 9 | import org.javasimon.StopwatchSample; 10 | 11 | /** 12 | * Implements {@link Callback} interface so that it does nothing - intended for extension by simple (non-composite) 13 | * callbacks. This class is to be subclassed when just a few methods need to be implemented instead of the whole Callback interface. 14 | * 15 | * @author Richard "Virgo" Richter 16 | */ 17 | public class CallbackSkeleton implements Callback { 18 | @Override 19 | public void initialize(Manager manager) { 20 | } 21 | 22 | @Override 23 | public void cleanup() { 24 | } 25 | 26 | @Override 27 | public void onStopwatchAdd(Stopwatch stopwatch, Split split, StopwatchSample sample) { 28 | } 29 | 30 | @Override 31 | public void onStopwatchStart(Split split) { 32 | } 33 | 34 | @Override 35 | public void onStopwatchStop(Split split, StopwatchSample sample) { 36 | } 37 | 38 | @Override 39 | public void onCounterDecrease(Counter counter, long dec, CounterSample sample) { 40 | } 41 | 42 | @Override 43 | public void onCounterIncrease(Counter counter, long inc, CounterSample sample) { 44 | } 45 | 46 | @Override 47 | public void onCounterSet(Counter counter, long val, CounterSample sample) { 48 | } 49 | 50 | @Override 51 | public void onSimonCreated(Simon simon) { 52 | } 53 | 54 | @Override 55 | public void onSimonDestroyed(Simon simon) { 56 | } 57 | 58 | @Override 59 | public void onManagerClear() { 60 | } 61 | 62 | @Override 63 | public void onManagerMessage(String message) { 64 | } 65 | 66 | @Override 67 | public void onManagerWarning(String warning, Exception cause) { 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /spring/src/main/java/org/javasimon/spring/webmvc/HandlerLocation.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.spring.webmvc; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | import org.javasimon.Split; 6 | 7 | import org.springframework.web.servlet.ModelAndView; 8 | 9 | /** 10 | * Location used by stopwatch source for MVC Handler interceptor. 11 | * Basically, represents a Controller method invocation. 12 | * 13 | * @author gquintana 14 | */ 15 | public class HandlerLocation { 16 | /** 17 | * HTTP Servlet Request. 18 | */ 19 | private final HttpServletRequest request; 20 | 21 | /** 22 | * Handler (controller method invocation). 23 | */ 24 | private final Object handler; 25 | 26 | /** 27 | * Request processing step: controller processing org view rendering. 28 | */ 29 | private HandlerStep step; 30 | 31 | /** 32 | * View (and Model, null when step is not VIEW. 33 | */ 34 | private ModelAndView modelAndView; 35 | 36 | /** 37 | * Currently running split. 38 | */ 39 | private Split split; 40 | 41 | public HandlerLocation(HttpServletRequest request, Object handler, HandlerStep step) { 42 | this.request = request; 43 | this.handler = handler; 44 | this.step = step; 45 | } 46 | 47 | public Object getHandler() { 48 | return handler; 49 | } 50 | 51 | public HttpServletRequest getRequest() { 52 | return request; 53 | } 54 | 55 | public ModelAndView getModelAndView() { 56 | return modelAndView; 57 | } 58 | 59 | public void setModelAndView(ModelAndView modelAndView) { 60 | this.modelAndView = modelAndView; 61 | } 62 | 63 | public HandlerStep getStep() { 64 | return step; 65 | } 66 | 67 | public void setStep(HandlerStep step) { 68 | this.step = step; 69 | } 70 | 71 | public Split getSplit() { 72 | return split; 73 | } 74 | 75 | public void setSplit(Split split) { 76 | this.split = split; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /demoapp/src/main/resources/servlet-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /console-embed/src/main/java/org/javasimon/console/SimonCallbacks.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.console; 2 | 3 | import java.util.Iterator; 4 | 5 | import org.javasimon.Manager; 6 | import org.javasimon.callback.Callback; 7 | import org.javasimon.callback.CompositeCallback; 8 | import org.javasimon.proxy.Delegating; 9 | 10 | /** 11 | * Simon callback helper class 12 | * 13 | * @author gquintana 14 | */ 15 | public class SimonCallbacks { 16 | 17 | /** 18 | * Get the first callback of given type in manager 19 | * 20 | * @param manager Simon manager containing callbacks 21 | * @param callbackType Expected callback type 22 | * @return Callback or null if not any 23 | */ 24 | public static T getCallbackByType(Manager manager, Class callbackType) { 25 | return getCallbackByType(manager.callback().callbacks(), callbackType); 26 | } 27 | 28 | /** 29 | * Search callback by type in list of callbacks 30 | * 31 | * @param callbacks List of callback 32 | * @param callbackType Callback type 33 | * @return Callback matching type 34 | */ 35 | private static T getCallbackByType(Iterable callbacks, Class callbackType) { 36 | T foundCallback = null; 37 | Iterator callbackIterator = callbacks.iterator(); 38 | while (foundCallback == null && callbackIterator.hasNext()) { 39 | Callback callback = callbackIterator.next(); 40 | // Remove callback wrappers 41 | while ((callback instanceof Delegating) && (!callbackType.isInstance(callback))) { 42 | callback = ((Delegating) callback).getDelegate(); 43 | } 44 | if (callbackType.isInstance(callback)) { 45 | // Callback found 46 | foundCallback = callbackType.cast(callback); 47 | } else if (callback instanceof CompositeCallback) { 48 | // Visit the composite callback 49 | foundCallback = getCallbackByType(((CompositeCallback) callback).callbacks(), callbackType); 50 | } 51 | } 52 | return foundCallback; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /demoapp/src/main/java/org/javasimon/demoapp/model/ToDoItem.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.demoapp.model; 2 | 3 | /** 4 | * Class that represents an item in a TODO list. 5 | * 6 | * @author Ivan Mushketyk (ivan.mushketyk@gmail.com) 7 | */ 8 | public class ToDoItem { 9 | private long id; 10 | private String name; 11 | private String description; 12 | private boolean done; 13 | 14 | public long getId() { 15 | return id; 16 | } 17 | 18 | public void setId(long id) { 19 | this.id = id; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public String getDescription() { 31 | return description; 32 | } 33 | 34 | public void setDescription(String description) { 35 | this.description = description; 36 | } 37 | 38 | public boolean isDone() { 39 | return done; 40 | } 41 | 42 | public void setDone(boolean done) { 43 | this.done = done; 44 | } 45 | 46 | @Override 47 | public boolean equals(Object o) { 48 | if (this == o) return true; 49 | if (o == null || getClass() != o.getClass()) return false; 50 | 51 | ToDoItem toDoItem = (ToDoItem) o; 52 | 53 | if (id != toDoItem.id) return false; 54 | if (done != toDoItem.done) return false; 55 | if (description != null ? !description.equals(toDoItem.description) : toDoItem.description != null) 56 | return false; 57 | if (name != null ? !name.equals(toDoItem.name) : toDoItem.name != null) return false; 58 | 59 | return true; 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | int result = (int) (id ^ (id >>> 32)); 65 | result = 31 * result + (name != null ? name.hashCode() : 0); 66 | result = 31 * result + (description != null ? description.hashCode() : 0); 67 | result = 31 * result + (done ? 1 : 0); 68 | return result; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /core/src/test/java/org/javasimon/callback/lastsplits/LastSplitsCallbackTest.java: -------------------------------------------------------------------------------- 1 | package org.javasimon.callback.lastsplits; 2 | 3 | import static org.testng.Assert.assertEquals; 4 | import static org.testng.Assert.assertTrue; 5 | 6 | import org.javasimon.EnabledManager; 7 | import org.javasimon.Manager; 8 | import org.javasimon.SimonUnitTest; 9 | import org.javasimon.Split; 10 | import org.javasimon.Stopwatch; 11 | import org.testng.annotations.BeforeMethod; 12 | import org.testng.annotations.Test; 13 | 14 | /** 15 | * @author gquintana 16 | */ 17 | public class LastSplitsCallbackTest extends SimonUnitTest { 18 | 19 | private Manager manager = new EnabledManager(); 20 | 21 | @BeforeMethod 22 | public void resetManager() { 23 | manager.clear(); 24 | manager.callback().addCallback(new LastSplitsCallback(5)); 25 | } 26 | 27 | @Test 28 | public void testAddSplit() { 29 | addSplit(100L); 30 | addSplit(150L); 31 | addSplit(125L); 32 | addSplit(150L); 33 | LastSplits lastSplits = getLastSplits(); 34 | assertEquals(100L, lastSplits.getMin().longValue()); 35 | assertEquals(150L, lastSplits.getMax().longValue()); 36 | assertEquals((150 * 2 + 125 + 100) / 4L, lastSplits.getMean().longValue()); 37 | } 38 | 39 | @Test 40 | public void testTrend() { 41 | addSplit(100L); 42 | addSplit(125L); 43 | addSplit(150L); 44 | LastSplits lastSplits = getLastSplits(); 45 | assertTrue(lastSplits.getTrend() > 0, "Positive trend"); 46 | resetManager(); 47 | addSplit(150L); 48 | addSplit(125L); 49 | addSplit(100L); 50 | lastSplits = getLastSplits(); 51 | assertTrue(lastSplits.getTrend() < 0, "Negative trend"); 52 | } 53 | 54 | private Stopwatch getStopwatch() { 55 | return manager.getStopwatch(getClass().getName() + ".stopwatch"); 56 | } 57 | 58 | private LastSplits getLastSplits() { 59 | return (LastSplits) getStopwatch().getAttribute(LastSplitsCallback.ATTR_NAME_LAST_SPLITS); 60 | } 61 | 62 | private void addSplit(long length) { 63 | getStopwatch().addSplit(Split.create(length, manager)); 64 | } 65 | } 66 | --------------------------------------------------------------------------------