module Control.Monad.Metrics.Internal where
import Data.HashMap.Strict (HashMap)
import Data.IORef
import Data.Text (Text)
import Lens.Micro (Lens')
import System.Clock (TimeSpec (..))
import System.Metrics (Store)
import System.Metrics.Counter (Counter)
import System.Metrics.Distribution (Distribution)
import System.Metrics.Gauge (Gauge)
import System.Metrics.Label (Label)
data Metrics = Metrics
{ _metricsCounters :: IORef (HashMap Text Counter)
, _metricsGauges :: IORef (HashMap Text Gauge)
, _metricsDistributions :: IORef (HashMap Text Distribution)
, _metricsLabels :: IORef (HashMap Text Label)
, _metricsStore :: Store
}
metricsCounters :: Lens' Metrics (IORef (HashMap Text Counter))
metricsCounters f (Metrics c g d l s) = fmap (\c' -> Metrics c' g d l s) (f c)
metricsGauges :: Lens' Metrics (IORef (HashMap Text Gauge))
metricsGauges f (Metrics c g d l s) = fmap (\g' -> Metrics c g' d l s) (f g)
metricsDistributions :: Lens' Metrics (IORef (HashMap Text Distribution))
metricsDistributions f (Metrics c g d l s) = fmap (\d' -> Metrics c g d' l s) (f d)
metricsLabels :: Lens' Metrics (IORef (HashMap Text Label))
metricsLabels f (Metrics c g d l s) = fmap (\l' -> Metrics c g d l' s) (f l)
metricsStore :: Lens' Metrics Store
metricsStore f (Metrics c g d l s) = fmap (Metrics c g d l) (f s)
data Resolution
= Nanoseconds
| Microseconds
| Milliseconds
| Seconds
| Minutes
| Hours
| Days
deriving (Eq, Show, Ord, Enum)
diffTime :: Resolution -> TimeSpec -> TimeSpec -> Double
diffTime res (TimeSpec seca nseca) (TimeSpec secb nsecb) =
let sec' = seca - secb
nsec' = nseca - nsecb
in convertTimeSpecTo res (TimeSpec sec' nsec')
convertTimeSpecTo :: Resolution -> TimeSpec -> Double
convertTimeSpecTo res (TimeSpec secs' nsecs') =
case res of
Nanoseconds -> nsecs + sToNs secs
Microseconds -> nsToUs nsecs + sToUs secs
Milliseconds -> nsToMs nsecs + sToMs secs
Seconds -> nsToS nsecs + secs
Minutes -> sToMin (nsToS nsecs + secs)
Hours -> sToHour (nsToS nsecs + secs)
Days -> sToDay (nsToS nsecs + secs)
where
nsecs = fromIntegral nsecs'
secs = fromIntegral secs'
nsToUs, nsToMs, nsToS, sToMin, sToHour, sToDay, sToNs, sToUs, sToMs :: Double -> Double
nsToUs = (/ 10^(3 :: Int))
nsToMs = (/ 10^(6 :: Int))
nsToS = (/ 10^(9 :: Int))
sToMin = (/ 60)
sToHour = sToMin . sToMin
sToDay = (/ 24) . sToHour
sToNs = (* 10^(9 :: Int))
sToUs = (* 10^(6 :: Int))
sToMs = (* 10^(3 :: Int))