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: &gt;a href="$mapping/foo"&lt;Foo&gt;/a&lt;.
+
+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" })`.