monad-metrics-extensible: An extensible and type-safe wrapper around EKG metrics

[ bsd3, library, web ] [ Propose Tags ]

Please see the README on GitHub at https://github.com/0xd34df00d/monad-metrics-extensible#readme


[Skip to Readme]
Versions [faq] 0.1.0.0, 0.1.0.1
Change log ChangeLog.md
Dependencies base (>=4.7 && <5), dependent-map, dependent-sum, ekg, ekg-core, exceptions, mtl, stm, text [details]
License BSD-3-Clause
Copyright 2019 Georg Rudoy
Author Georg Rudoy
Maintainer 0xd34df00d@gmail.com
Category Web
Home page https://github.com/0xd34df00d/monad-metrics-extensible#readme
Bug tracker https://github.com/0xd34df00d/monad-metrics-extensible/issues
Source repo head: git clone https://github.com/0xd34df00d/monad-metrics-extensible
Uploaded by 0xd34df00d at Mon Jul 15 00:39:14 UTC 2019
Distributions NixOS:0.1.0.1
Downloads 85 total (20 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2019-07-15 [all 1 reports]

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for monad-metrics-extensible-0.1.0.1

[back to package description]

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!

import 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 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
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 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, Counters have no arguments, while Gauges accept the corresponding new value.