-- | UDP Chunked support for sending messages to graylog. module Graylog.UDP ( sendLog , module Export ) where import Data.Aeson import Data.ByteString.Builder import qualified Data.ByteString.Lazy as LBS import Data.Monoid import Data.Word import Network.Socket.ByteString.Lazy import System.Random import Graylog.Gelf as Export import Graylog.Types as Export sendLog :: Graylog -> GELF -> IO () sendLog glog msg = do cks <- chunky glog raw mapM_ (send $ _graylogSocket glog) cks where raw = encode msg chunky :: Graylog -> LBS.ByteString -> IO [LBS.ByteString] chunky glog raw = do groupId <- randomIO let groups = divide totalNum raw return $ append groupId groups seqNums where magic = word8 0x1e <> word8 0x0f seqNums = [0..] :: [Word8] totalNum = if excess > 0 then count + 1 else count (count, excess) = quotRem (LBS.length raw) gsize hlen = 12 gsize = (fromIntegral (_graylogChunkSize glog)) - hlen divide 0 dat = [dat] divide num dat = let (pre, post) = LBS.splitAt gsize dat in pre : divide (num - 1) post append _ [] _ = [] append _ _ [] = error "the impossible has happened." append gid (g:gs) (s:ss) = (toLazyByteString $ magic <> word64BE gid <> word8 s <> word8 (fromIntegral totalNum) <> lazyByteString g) : append gid gs ss