{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE RecordWildCards #-}
module Eventlog.Events(chunk) where
import GHC.RTS.Events hiding (Header, header)
import Prelude hiding (init, lookup)
import qualified Data.Text as T
import Eventlog.Types
import Data.List
import Data.Function
import Data.Word
fromNano :: Word64 -> Double
fromNano e = fromIntegral e * 1e-9
chunk :: FilePath -> IO (PartialHeader, [Frame], [Trace])
chunk f = eventlogToHP . either error id =<< readEventLogFromFile f
eventlogToHP :: EventLog -> IO (PartialHeader, [Frame], [Trace])
eventlogToHP (EventLog _h e) = do
eventsToHP e
eventsToHP :: Data -> IO (PartialHeader, [Frame], [Trace])
eventsToHP (Data es) = do
let
el@EL{..} = foldEvents es
fir = Frame (fromNano start) []
las = Frame (fromNano end) []
return $ (elHeader el, fir : reverse (las: normalise frames) , traces)
normalise :: [(Word64, [Sample])] -> [Frame]
normalise fs = map (\(t, ss) -> Frame (fromNano t) ss) fs
data EL = EL
{ pargs :: Maybe [String]
, samples :: Maybe (Word64, [Sample])
, frames :: [(Word64, [Sample])]
, traces :: [Trace]
, start :: Word64
, end :: Word64 } deriving Show
initEL :: Word64 -> EL
initEL t = EL Nothing Nothing [] [] t 0
foldEvents :: [Event] -> EL
foldEvents (e:es) =
let res = foldl' folder (initEL (evTime e)) (e:es)
in addFrame 0 res
foldEvents [] = error "Empty event log"
folder :: EL -> Event -> EL
folder el (Event t e _) = el &
updateLast t .
case e of
Message s -> addTrace (Trace (fromNano t) (T.pack s))
UserMessage s -> addTrace (Trace (fromNano t) (T.pack s))
HeapProfBegin {} -> addFrame t
HeapProfSampleBegin {} -> addFrame t
HeapProfSampleString _hid res k -> addSample (Sample k (fromIntegral res))
ProgramArgs _ as -> addArgs as
_ -> id
addArgs :: [String] -> EL -> EL
addArgs as el = el { pargs = Just as }
addTrace :: Trace -> EL -> EL
addTrace t el = el { traces = t : traces el }
addFrame :: Word64 -> EL -> EL
addFrame t el =
el { samples = Just (t, [])
, frames = sampleToFrames (samples el) (frames el) }
sampleToFrames :: Maybe (Word64, [Sample]) -> [(Word64, [Sample])]
-> [(Word64, [Sample])]
sampleToFrames (Just (t, ss)) fs = (t, (reverse ss)) : fs
sampleToFrames Nothing fs = fs
addSample :: Sample -> EL -> EL
addSample s el = el { samples = go <$> (samples el) }
where
go (t, ss) = (t, (s:ss))
updateLast :: Word64 -> EL -> EL
updateLast t el = el { end = t }
elHeader :: EL -> PartialHeader
elHeader EL{..} =
let title = maybe "" (T.unwords . map T.pack) pargs
in Header title "aaa" "" ""