You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by rm...@apache.org on 2013/08/07 09:12:40 UTC
svn commit: r1511196 - in
/commons/sandbox/monitoring/trunk/src/site/markdown: concepts.md plugins.md
Author: rmannibucau
Date: Wed Aug 7 07:12:40 2013
New Revision: 1511196
URL: http://svn.apache.org/r1511196
Log:
completing plugin doc page
Modified:
commons/sandbox/monitoring/trunk/src/site/markdown/concepts.md
commons/sandbox/monitoring/trunk/src/site/markdown/plugins.md
Modified: commons/sandbox/monitoring/trunk/src/site/markdown/concepts.md
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/src/site/markdown/concepts.md?rev=1511196&r1=1511195&r2=1511196&view=diff
==============================================================================
--- commons/sandbox/monitoring/trunk/src/site/markdown/concepts.md (original)
+++ commons/sandbox/monitoring/trunk/src/site/markdown/concepts.md Wed Aug 7 07:12:40 2013
@@ -20,20 +20,74 @@ under the License.
The repository is a singleton for the JVM. It is the entry point to get access to counters and gauges.
+ public interface Repository extends Iterable<Counter> {
+ Counter getCounter(Counter.Key key);
+ void clear();
+ StopWatch start(Counter counter);
+
+ Map<Long, Double> getGaugeValues(long start, long end, Role role);
+ void stopGauge(Role role);
+ }
+
# Counter
-A counter is statistic and concurrency holder. It aggregates the information provided computing
+A counter is a statistic and concurrency holder. It aggregates the information provided computing
the average, min, max, sum of logs, ....
+
+ public interface Counter {
+ Key getKey();
+ void reset();
+
+ void add(double delta);
+
+ AtomicInteger currentConcurrency();
+ int getMaxConcurrency();
+
+ double getMax();
+ double getMin();
+ long getHits();
+ double getSum();
+ double getStandardDeviation();
+ double getVariance();
+ double getMean();
+ double getGeometricMean();
+ double getSumOfLogs();
+ double getSumOfSquares();
+ }
+
# Gauge
A gauge is a way to get a measure. It is intended to get a history of a metric.
+ public interface Gauge {
+ Role role();
+ double value();
+ long period();
+ }
+
# DataStore
Counters and Gauges are saved and queried (in memory by default) through a DataStore. it allows you to plug
behind it any kind of persistence you would like.
+ public interface DataStore {
+ Counter getOrCreateCounter(Counter.Key key);
+ void clearCounters();
+ Collection<Counter> getCounters();
+ void addToCounter(Counter defaultCounter, double delta); // sensitive method which need to be thread safe
+
+ Map<Long,Double> getGaugeValues(long start, long end, Role role);
+ void createOrNoopGauge(Role role);
+ void addToGauge(Gauge gauge, long time, double value);
+ }
+
# StopWatch
A StopWatch is just a handler for a measure with a counter.
+
+ public interface StopWatch {
+ long getElapsedTime();
+
+ StopWatch stop();
+ }
Modified: commons/sandbox/monitoring/trunk/src/site/markdown/plugins.md
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/src/site/markdown/plugins.md?rev=1511196&r1=1511195&r2=1511196&view=diff
==============================================================================
--- commons/sandbox/monitoring/trunk/src/site/markdown/plugins.md (original)
+++ commons/sandbox/monitoring/trunk/src/site/markdown/plugins.md Wed Aug 7 07:12:40 2013
@@ -18,9 +18,117 @@ under the License.
-->
## Plugins
-TODO
+There are several kind of plugins:
-## Write your own plugin
+* `org.apache.commons.monitoring.gauges.Gauge` and `org.apache.commons.monitoring.gauges.GaugeFactory`: you can add your own gauges
+* `org.apache.commons.monitoring.reporting.web.plugin.Plugin`: add feature to the web GUI
-TODO
+## Write your own gauge
+To add your own Gauge you have two main solutions:
+
+* simply implement a `org.apache.commons.monitoring.gauges.Gauge` and register it using ServiceLoader mecanism (META-INF/services/org.apache.commons.monitoring.gauges.Gauge)
+* implement a `org.apache.commons.monitoring.gauges.GaugeFactory` which is registered it using ServiceLoader mecanism (META-INF/services/org.apache.commons.monitoring.gauges.GaugeFactory) and return the gauges you want to register
+
+What is GaugeFactory designed for? Imagine a custom gauge is parameterized. You'll surely want to register it
+several times with different parameters. If you use Gauge SPI you'll need to do N implementations (which makes the parameters useless).
+With GaugeFactory you just need to return the built instances:
+
+ public class MyGaugeFactory implements GaugeFactory {
+ @Override
+ public Gauge[] gauges() {
+ return new Gauge[] { new MyGauge(1); new MyGauge(2); };
+ }
+ }
+
+## Extend the reporting GUI
+
+To extend the reporting GUI just write your own `org.apache.commons.monitoring.reporting.web.plugin.Plugin`. Here too it
+relies on java ServiceLoader (SPI) mecanism.
+
+Here is the Plugin interface:
+
+ public interface Plugin {
+ String name();
+ Class<?> endpoints();
+ String mapping();
+ }
+
+
+A plugin has basically a name (what will identify it in the webapp and in the GUI - it will be the name of the plugin tab),
+a mapping, ie which base subcontext it will use for its own pages (for instance /jmx, /myplugin ...) and a class representing endpoints.
+
+To make it more concrete we'll use a sample (the standard Hello World).
+
+### Define the plugin
+
+So first we define our HelloPlugin:
+
+ public class HelloPlugin implements Plugin {
+ public String name() {
+ return "Hello";
+ }
+
+ public Class<?> endpoints() {
+ return HelloEndpoints.class;
+ }
+
+ public String mapping() {
+ return "/hello";
+ }
+ }
+
+### Define the endpoints
+
+The `HelloEndpoints` class defines all the urls accessible for the hello plugin. It uses the `org.apache.commons.monitoring.reporting.web.handler.api.Regex`
+annotation:
+
+
+ public class HelloEndpoints {
+ @Regex // will match "/hello"
+ public Template home() {
+ return new Template("hello/home.vm", new MapBuilder<String, Object>().set("name", "world).build());
+ }
+
+ @Regex("/world/([0-9]*)/([0-9]*)") // will match "/hello/world/1/2"
+ public String jsonWorld(final long start, final long end) {
+ return "{ \"name\": \world\", \"start\":\"" + long1 + "\",\"end\":\"" + long2 + "\"}";
+ }
+ }
+
+The first home method uses a template. The GUI relies on velocity and html templates needs to be in the classloader in templates directory.
+
+So basically the home method will search for templates/hello/home.vm velocity template. It is only the "main" part of the GUI
+(the tabs are automatically added). Twitter bootstrap (2.3.2) and JQuery are available.
+
+Here is a sample:
+
+ <h1>Hello</h1>
+ <div>
+ Welcome to $name
+ </div>
+
+If you need resources put them in the classloader too in "resources" folder.
+
+Note: if you want to do links in the template you can use $mapping variable as base context of your link. For instance: >a href="$mapping/foo"<Foo>/a<.
+
+If you want to filter some resources you can add a custom endpoint:
+
+ @Regex("/resources/myresource.css")
+ public void filterCss(final TemplateHelper helper) {
+ helper.renderPlain("/resources/myresource.css");
+ }
+
+#### `@Regex`
+
+`@Regex` allows you to get injected path segments, here is what is handled:
+
+* HttpServletRequest
+* HttpServletResponse
+* TemplateHelper (should be used when you want to render a velocity template which is not in /templates and is not decorated by the default GUI layout)
+* String: will inject the matching element of the regex (it is indexed = if you inject 2 strings the first one will be the first group and the second one the second group)
+* Long, Integer: same as for String but converted
+* String[]: all not yet matched segments of the regex
+
+For instance `@Regex("/operation/([^/]*)/([^/]*)/(.*)")` will match `foo(String, String, String[])`.
+If the url is `/operation/a/b/c/d/e` you'll get `foo("a", "b", { "c", "d", "e" })`.