packages feed

aws-xray-client-0.1.0.0: library/Network/AWS/XRayClient/SendSegments.hs

-- | Module for sending segments to the XRay daemon.

module Network.AWS.XRayClient.SendSegments
  ( sendSegmentsToDaemon
  , NoAddressInfoException(..)
  ) where

import Prelude

import Control.Exception (Exception, SomeException, catch, throwIO)
import Data.Aeson
import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as BSL
import Data.Foldable (traverse_)
import Data.Monoid ((<>))
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typeable
import Network.AWS.XRayClient.Segment as X
import Network.Socket
import Network.Socket.ByteString (sendAll)
import System.IO (hPutStrLn, stderr)

-- | Makes JSON payloads for each segment and sends it to the daemon.
sendSegmentsToDaemon :: Text -> Int -> [XRaySegment] -> IO ()
sendSegmentsToDaemon host port segments = catch
  (sendUDPByteStrings host port $ makeXRayPayload <$> segments)
  (\(err :: SomeException) ->
    hPutStrLn stderr ("sendUDPByteStrings: " ++ show err)
  )

makeXRayPayload :: XRaySegment -> ByteString
makeXRayPayload segment =
  let header = object ["format" .= ("json" :: String), "version" .= (1 :: Int)]
  in BSL.toStrict $ encode header <> "\n" <> encode segment

-- | Sends the entirety of multiple 'ByteString' values to a given host/port
-- via UDP Datagrams.
sendUDPByteStrings :: Text -> Int -> [ByteString] -> IO ()
sendUDPByteStrings host port payloads = do
  addrInfos <- getAddrInfo Nothing (Just $ T.unpack host) (Just $ show port)
  case addrInfos of
    [] ->
      throwIO
        $ NoAddressInfoException
        $ "No address info for "
        ++ T.unpack host
        ++ ":"
        ++ show port
    (serverAddr : _) -> do
      sock <- socket (addrFamily serverAddr) Datagram defaultProtocol
      connect sock (addrAddress serverAddr)
      traverse_ (sendAll sock) payloads
      close sock

newtype NoAddressInfoException
  = NoAddressInfoException String
  deriving (Show, Typeable)

instance Exception NoAddressInfoException