Description
An extensible and type-safe wrapper around EKG metrics.
Description
Please see the README on GitHub at https://github.com/0xd34df00d/monad-metrics-extensible#readme
README.md
monad-metrics-extensible
tl;dr
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!
A quick example
First we enable a few extensions and import some packages:
{-# 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:
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 (
Counter
andGauge
in 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 42
withMetricsStore
creates the metrics store that's managed by this library and runs anIO
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, as can be seen in the example above,Counter
s have no arguments, whileGauge
s accept the corresponding new value.