module Network.Metrics.Statsd (
MetricType
, Metric(..)
, open
, emit
, I.Handle
, I.close
) where
import Network.Socket
import System.Random (randomRIO)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BL
import qualified Network.Metrics.Internal as I
data MetricType = Counter | Timer | Gauge deriving (Show)
data Metric = Metric
{ type' :: MetricType
, bucket :: BS.ByteString
, value :: Integer
, rate :: Double
} deriving (Show)
data Sampled = Sampled | Exact | Ignore
open :: String -> String -> IO I.Handle
open = I.open Datagram
emit :: Metric -> I.Handle -> IO I.Handle
emit metric handle = do
rand <- randomRIO (0.0, 1.0)
I.emit (encoded rand) handle
where
encoded = BL.fromChunks . components metric . sample (rate metric)
sample :: Double -> Double -> Sampled
sample rate rand | rate < 1.0 && rand <= rate = Sampled
| rate == 1.0 = Exact
| otherwise = Ignore
components :: Metric -> Sampled -> [BS.ByteString]
components Metric{..} sampled = case sampled of
Sampled -> base ++ ["@", BS.pack $ show rate]
Exact -> base
Ignore -> []
where
base = [bucket, ":", BS.pack $ show value, "|", suffix type']
suffix :: MetricType -> BS.ByteString
suffix typ = case typ of
Counter -> "c"
Gauge -> "g"
Timer -> "ms"