packages feed

eventlog2html-0.10.0: src/Eventlog/Data.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
module Eventlog.Data (generateJson, generateJsonValidate, generateJsonData, EventlogType(..) ) where

import Prelude hiding (readFile)
import Data.Aeson (Value(..), (.=), object)
import qualified Data.Map as Map

import Eventlog.Args (Args(..))
import Eventlog.Bands (bands)
import qualified Eventlog.Events as E
import qualified Eventlog.HeapProf as H
import Eventlog.Prune
import Eventlog.Vega
import Eventlog.Types (Header(..), ProfData(..), HeapProfBreakdown(..))
import Data.List
import Data.Ord
import Eventlog.Trie
import Eventlog.Detailed
import Text.Blaze.Html
import Eventlog.Ticky
import Data.Word


data EventlogType = HeapProfile  (Header, Value, Maybe Value, Maybe Html)
                  | TickyProfile (Header, Word64, Double, Html)

generateJsonData :: Args -> ProfData -> IO (Header, Value, Maybe Value, Maybe Html)
generateJsonData a (ProfData h binfo ccMap fs traces heap_info ipes _ticky_counter _ticky_samples _total_allocs) = do
  let keeps = pruneBands a binfo
      bs = bands h (Map.map fst keeps) fs
      combinedJson = object [
          "samples" .= bandsToVega keeps bs
        , "traces"  .= tracesToVega traces
        , "heap"    .= heapToVega heap_info
        ]
      mdescs =
        sortBy (flip (comparing (fst . snd))) $ Map.toList keeps
      -- Only supply the cost centre view in cost centre profiling mode.
      cc_descs = case hHeapProfileType h of
                Just HeapProfBreakdownCostCentre -> Just (outputTree ccMap mdescs)
                _ -> Nothing

  let use_ipes = case hHeapProfileType h of
                   Just HeapProfBreakdownInfoTable -> Just ipes
                   _ -> Nothing
      desc_buckets = pruneDetailed a binfo
      bs' = bands h (Map.map fst desc_buckets) fs
      closure_table =
        case detailedLimit a of
          Just 0 ->  Nothing
          _ -> Just (renderClosureInfo bs' use_ipes desc_buckets)
  return (h, combinedJson, cc_descs, closure_table)

generateJson :: FilePath -> Args -> IO EventlogType
generateJson = generateJsonValidate (const (return ()))

generateJsonValidate :: (ProfData -> IO ()) -> FilePath
                     -> Args -> IO EventlogType
generateJsonValidate validate file a = do
  let chunk = if heapProfile a then H.chunk else E.chunk a
  dat <- chunk file
  validate dat
  case profTickySamples dat of
    [] -> HeapProfile <$> generateJsonData a dat
    -- If there are any ticky samples then generate a ticky profile
    _  -> do
      let (percen, html) = renderTicky (profTotalAllocations dat) (profTickyCounters dat) (profItl dat) (profTickySamples dat)
      return $ TickyProfile ( profHeader dat
                                , profTotalAllocations dat
                                , percen
                                , html )