module Network.StatsD.Socket
( connectStatsD, sendStatsDIO, StatsD
, withStatsD, HasStatsD(..)
, statsd
) where
import Network.StatsD.Datagram
import Control.Monad.Base
import Control.Monad.Trans.Control
import qualified Network.Socket as S
import qualified Network.Socket.ByteString as SB
data StatsD = StatsD
{ sdSocket :: S.Socket
, sdSockAddr :: S.SockAddr
}
connectStatsD :: String -> String -> IO StatsD
connectStatsD hostname port = do
ais <- S.getAddrInfo Nothing (Just hostname) (Just port)
addr <- case ais of
ai:_ -> return ai
_ -> fail "StatsD connection failed: bad address."
sock <- S.socket (S.addrFamily addr) S.Datagram S.defaultProtocol
return $ StatsD sock (S.addrAddress addr)
sendStatsDIO :: ToDatagram a => StatsD -> a -> IO ()
sendStatsDIO sd x = do
let payload = renderDatagram $ toDatagram x
SB.sendAllTo (sdSocket sd) payload (sdSockAddr sd)
class (MonadBaseControl IO m) => HasStatsD m where
getStatsD :: m StatsD
withStatsD :: (HasStatsD m, MonadBaseControl IO m)
=> (StatsD -> m a)
-> m a
withStatsD action = getStatsD >>= action
statsd :: (HasStatsD m, ToDatagram a)
=> a
-> m ()
statsd payload = withStatsD $ \sd ->
liftBase (sendStatsDIO sd payload)