module Control.Monad.Metrics.Internal where
import Data.IORef
import Data.HashMap.Strict (HashMap)
import Data.Text (Text)
import Lens.Micro
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 secs = seca secb
nsecs = nseca nsecb
in convertTimeSpecTo res (TimeSpec secs nsecs)
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))