module Network.Metrics.Internal (
Handle(..)
, Group
, Bucket
, Value
, MetricType(..)
, Metric(..)
, MetricSink(..)
, Sink(..)
, hOpen
, hClose
, hPush
) where
import Control.Monad (unless)
import Network.Socket hiding (send)
import Network.Socket.ByteString.Lazy (send)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BL
data Handle = Handle Socket SockAddr deriving (Show)
type Group = BS.ByteString
type Bucket = BS.ByteString
type Value = BS.ByteString
data MetricType = Counter | Gauge | Timer deriving (Show)
data Metric = Metric MetricType Group Bucket Value deriving (Show)
class MetricSink a where
push :: Metric -> a -> IO ()
close :: a -> IO ()
data Sink = forall a. MetricSink a => Sink a
instance MetricSink Sink where
push m (Sink s) = push m s
close (Sink s) = close s
hOpen :: SocketType -> String -> String -> IO Handle
hOpen typ host port = do
(addr:_) <- getAddrInfo Nothing (Just host) (Just port)
sock <- socket (addrFamily addr) typ defaultProtocol
return $ Handle sock (addrAddress addr)
hClose :: Handle -> IO ()
hClose (Handle sock _) = sClose sock
hPush :: BL.ByteString -> Handle -> IO ()
hPush bstr (Handle sock addr) | BL.null bstr = return ()
| otherwise = do
sIsConnected sock >>= \b -> unless b $ connect sock addr
_ <- send sock bstr
return ()