module Prometheus.Metric.Observer (
Observer(..)
, observeDuration
, timeAction
) where
import Data.Ratio ((%))
import Prometheus.MonadMonitor
import Control.Monad.IO.Class
import System.Clock (Clock(..), diffTimeSpec, getTime, toNanoSecs)
class Observer metric where
observe :: MonadMonitor m => metric -> Double -> m ()
observeDuration :: (Observer metric, MonadIO m, MonadMonitor m) => metric -> m a -> m a
observeDuration :: forall metric (m :: * -> *) a.
(Observer metric, MonadIO m, MonadMonitor m) =>
metric -> m a -> m a
observeDuration metric
metric m a
io = do
(result, duration) <- m a -> m (a, Double)
forall (m :: * -> *) a. MonadIO m => m a -> m (a, Double)
timeAction m a
io
observe metric duration
return result
timeAction :: MonadIO m => m a -> m (a, Double)
timeAction :: forall (m :: * -> *) a. MonadIO m => m a -> m (a, Double)
timeAction m a
io = do
start <- IO TimeSpec -> m TimeSpec
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO TimeSpec -> m TimeSpec) -> IO TimeSpec -> m TimeSpec
forall a b. (a -> b) -> a -> b
$ Clock -> IO TimeSpec
getTime Clock
Monotonic
result <- io
end <- liftIO $ getTime Monotonic
let duration = TimeSpec -> Integer
toNanoSecs (TimeSpec
end TimeSpec -> TimeSpec -> TimeSpec
`diffTimeSpec` TimeSpec
start) Integer -> Integer -> Ratio Integer
forall a. Integral a => a -> a -> Ratio a
% Integer
1000000000
return (result, fromRational duration)