This library simplifies using ekg in three ways:
- It allows specifying metrics as constructors of a user-defined GADT carrying both the metric name (to avoid typos) and the metric kind (a counter, a distribution and so on — to avoid code duplication). Multiple GADTs in the same appplication are supported (hence "extensible").
- It encapsulates managing all the necessary EKG objects on-demand via a monadic API.
- It allows defining new kinds of metrics in the user code (hence "extensible" one more time). You want a combined distribution + counter? No prob!
System.Metrics.Extensible is your entry point of choice!
First we enable a few extensions and import some packages:
{-# LANGUAGE DataKinds, GADTs, StandaloneDeriving #-} import System.Metrics.Extensible import System.Remote.Monitoring -- for ekg stuffThen we define a type that represents the possible metrics in our application:
data SomeMetrics ty name where SomeCounter :: SomeMetrics Counter "some_counter" AnotherCounter :: SomeMetrics Counter "other_counter" SomeGauge :: SomeMetrics Gauge "some_gauge"The string literals are what will be shown via ekg UI.
There is a couple of requirements:
- The type shall be of the kind
* -> Symbol -> *. - The first type argument (
CounterandGaugein the example above) shall be an instance ofTrackerLike. All ekg counters are already instances of this class. - The type shall be comparable, hence we also do
deriving instance Eq (SomeMetrics ty name) deriving instance Ord (SomeMetrics ty name)
Then we can write our small program!
main :: IO () main = do ekgServer <- forkServer "localhost" 8000 withMetricsStore ekgServer $ \store -> flip runMetricsT store $ do track SomeCounter track SomeGauge 42withMetricsStorecreates the metrics store that's managed by this library and runs anIOcomputation with that store.runMetricsTis what runs the monad transformer giving access to the metrics.trackis the function that's responsible for updating the metrics. Its arguments depend on the specific metric that's being tracked: for instance, as can be seen in the example above,Counters have no arguments, whileGauges accept the corresponding new value.