packages feed

monad-metrics-extensible-0.1.0.1: README.md

# monad-metrics-extensible

## tl;dr

This library simplifies using [ekg](http://hackage.haskell.org/package/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!

`import System.Metrics.Extensible` is your entry point of choice!

## A quick example

First we enable a few extensions and import some packages:
```haskell
{-# LANGUAGE DataKinds, GADTs, StandaloneDeriving #-}

import System.Metrics.Extensible
import System.Remote.Monitoring -- for ekg stuff
```

Then we define a type that represents the possible metrics in our
application:
```haskell
data SomeMetrics ty name where
  SomeCounter     :: SomeMetrics Counter "some_counter"
  AnotherCounter  :: SomeMetrics Counter "other_counter"
  SomeGauge       :: SomeMetrics Gauge   "some_gauge"
```
The string literals is 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 (`Counter` and `Gauge` in the example above)
  shall be an instance of `TrackerLike`. All ekg counters are already
  an instance of this class.
* The type shall be comparable, hence we shall also do
```haskell
deriving instance Eq (SomeMetrics ty name)
deriving instance Ord (SomeMetrics ty name)
```

Then we can write our small program!

```haskell
main :: IO ()
main = do
  ekgServer <- forkServer "localhost" 8000
  withMetricsStore ekgServer $ \store -> flip runMetricsT store $ do
    track SomeCounter
    track SomeGauge 42
```

* `withMetricsStore` creates the metrics store that's managed by this
  library and runs an `IO` computation with that store.
* `runMetricsT` is what runs the monad transformer giving access to
  the metrics.
* `track` is the function that's responsible for updating the metrics.
  Its arguments depend on the specific metric that's being tracked:
  for instance, `Counter`s have no arguments, while `Gauge`s accept
  the corresponding new value.