//////////////////////
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
//////////////////////

[[core-api-metrics, Metrics API]]
= Metrics API =
The Polygene™ platform defines an advanced Metrics SPI to capture runtime metrics of Polygene's internals as well be used by
application code (via this API) to provide production metrics for operations personnel, ensuring healthy state of
the applications.


== MetricsProvider ==
There are quite a lot of different Metrics components available, which are instantiated via factories. There is one
factory for each component type, to allow for additional components to be created in the future without breaking
compatibility in the existing implementations.

The MetricsProvider is a standard Polygene™ Service and simply acquired via the @Service annotation on a field or
constructor argument.

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=common
--------------

== Gauge ==
A Gauge is the simplest form of Metric. It is a value that the application sets, which is polled upon request. The
application need to provide the implementation of the _value()_ method. Gauges are genericized for type-safe value
handling.

A Gauge can represent anything, for instance, thread pool levels, queue sizes and other resource allocations. It is
useful to have separate gauges for percentage (%) and absolute numbers of the same resource. Operations are mainly
interested in being alerted when threshold are reached as a percentage, as it is otherwise too many numbers to keep
track of.

To create a Gauge, you do something like;

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=gauge
--------------

== Counter ==
Often we want to track the many counters in a system. This might be "number of HTTP requests" or
"filesystem access frequency". By creating a _Counter_ metrics, it is simply a matter of calling the _increment_
or _decrement_ on that metric. This will track both number of counts/steps as well as the rate (per second), and
many visualization platforms. such as Kibana, Graphite and Grafana, are made to handle this particular metric very well.

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=counter
--------------

== Histogram ==
Histograms is about computing the running standard deviations and variances. Please see
http://www.johndcook.com/standard_deviation.html["Accurately computing running variance"] for more detailed information.

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=histogram
--------------

== Meter ==
The _Meter_ is a more advanced _Counter_, which measures mean throughput and one-, five-, and fifteen-minute
exponentially-weighted moving average throughputs.

Wikipedia has a section
http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average["Exponential moving average"] in the
"Moving Average" article.

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=meter
--------------

== Timer ==
Timers capture both the length of some execution as well as rate of calls. They can be used to time method calls, or
critical sections, or even HTTP requests duration and similar.

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=timer
--------------

== HealthCheck ==
HealthCheck is a metric to report the health of a system or component. The HealthCheck metric will be called upon
regularly to report its status, which is then forwarded to the monitoring system.

[snippet,java]
--------------
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=healthcheck
--------------


= Timing Capture =
A lot of metrics are around the time it takes to execute something and Polygene supports this at its core.

== Usage ==
There are currently the following possibilities available;

    * @TimingCapture - capture timing on a single method
    * TimingCaptureAll - capture timing on all methods of a composite

Before looking at the details of these, we need to point out that there are some pre-conditions for Metrics to be
working. First of all, you need to install a Metrics Extensions, most likely the
<<extension-metrics-codahale, Codahale Metrics Extension>>. See your chosen extension for details on how to do that.

Once the Metrics extension is installed, you will also need a suitable backend to gather all the data out of a
production plant and likewise a good front-end to view this. See your chosen Metrics Extension for this as well.

== TimingCaptureAll ==
There is a TimingCaptureAllConcern, which when added to a composite will install a _Timer_ for every method call
in the composite.

== @TimingCapture ==
The +@TimingCapture+ annotation can be placed on any method of the composite, to indicate that
a Timer is wanted on that method.

Example;

[snippet,java]
----
source=core/api/src/test/java/org/apache/polygene/api/metrics/DocumentationSupport.java
tag=capture
----

== Which method? ==
It is valid to annotate either the composite interface methods or the mixin implementation methods.
Any of the method declarations should work. From the testcases we have the following example;

[snippet,java]
----
source=core/testsupport/src/main/java/org/apache/polygene/test/metrics/AbstractTimingCaptureTest.java
tag=complex-capture
----

