Giter Club home page Giter Club logo

monad-metrics's Introduction

#!/usr/bin/env stack

-- stack --install-ghc runghc --package monad-metrics --package turtle --package markdown-unlit -- "-pgmL markdown-unlit"

monad-metrics

Build Status

This library defines a convenient wrapper and API for using EKG metrics in your application. It's heavily inspired by the metrics code that Taylor Fausak used in his Haskell application blunt.

Usage

This README is an executable literate Haskell file. If you have stack installed, then you can run the file with:

./README.lhs

We'll need to start with the import/pragma boilerplate:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}

import qualified Control.Monad.Metrics as Metrics
import           Control.Monad.Metrics (Metrics, Resolution(..), MonadMetrics(..))
import           Control.Monad.Reader
import qualified System.Metrics        as EKG

The Control.Monad.Metrics module is designed to be imported qualified.

Initialize!

First, you need to initialize the Metrics data type. You can do so using initialize (to create a new EKG store) or initializeWith if you want to pass a preexisting store.

initializing :: Bool -> EKG.Store -> IO Metrics
initializing True store = Metrics.initializeWith store
initializing False _    = Metrics.initialize

Embed!

The next step is to implement an instance of the class MonadMetrics for your monad transformer stack. This library has explicitly decided not to provide a concrete monad transformer to reduce the dependency footprint. Fortunately, it's pretty easy!

Suppose you've got the following stack:

type App = ReaderT Config IO

data Config = Config { configMetrics :: Metrics }

then you can easily get the required instance with:

instance MonadMetrics (ReaderT Config IO) where
    getMetrics = asks configMetrics

Now, you're off to the races! Let's record some metrics.

If you're after a really simple embedding, you can use run or run':

simple :: Int -> IO ()
simple i = 
    Metrics.run $ do
        metrics <- Metrics.getMetrics
        Metrics.gauge "Simple" i
        forM_ [1..i] $ \_ -> do
            Metrics.increment "Count!"

gettingThere :: IO ()
gettingThere = 
    Metrics.run' (\metrics -> Config metrics) $ do
        liftIO $ putStrLn "it accepts a constructor"

Measure!

Once your application has the required instance, you can use EKG's metrics (counters, gauges, labels, distributions).

For detailed descriptions of the various metric types, see the corresponding EKG documentation:

Generally, the library provides "sane default" functions which accept the name of the metric to work with and the value to contribute to that metric.

w = Metrics.label "Foo" "Bar"
x = Metrics.counter "MetricName" 6
y = Metrics.distribution "Distribute" 3.4
z = Metrics.gauge "Gauge" 7

Generalized versions of these functions are available with an apostrophe. Labels accept any Showable value, while gauges and counters accept any Integral value.

a = Metrics.label' "List" [1,2,3]
b = Metrics.counter' "Count" (3 :: Integer)

Timers

You can time actions with timed, which has a resolution of seconds. You can use timed' which accepts a Resolution argument to provide a different scale.

timedProcess :: App Int
timedProcess = 
    Metrics.timed "summing1" $ do
        pure $! sum [1 .. 100000]

timedInMilliseconds :: App Int
timedInMilliseconds = 
    Metrics.timed' Microseconds "summing2" $ do
        pure $! sum [1..100]

A demonstration

main :: IO ()
main = do
    metrics <- Metrics.initialize
    flip runReaderT (Config metrics) $ do
        Metrics.label "ProgramName" "README"
        forM_ [1..10] $ \_ -> do
            Metrics.increment "up-to-ten"
        Metrics.timed' Nanoseconds "Whatever" $ do
            liftIO $ putStrLn "Hello World!" 

monad-metrics's People

Contributors

parsonsmatt avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.