{-# Language OverloadedStrings #-}
module RtsStats
( Stats
, getStats
, statsToEntries
) where
import Data.Int (Int64)
import Data.List (intercalate)
import Data.List.Split (chunksOf)
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Word (Word32, Word64)
import GHC.Stats
class Render a where render :: a -> Text
instance Render Word32 where render :: Word32 -> Text
render = Word32 -> Text
forall a. (Show a, Num a, Ord a) => a -> Text
prettyNum
instance Render Word64 where render :: Word64 -> Text
render = Word64 -> Text
forall a. (Show a, Num a, Ord a) => a -> Text
prettyNum
instance Render Int64 where render :: Int64 -> Text
render = Int64 -> Text
forall a. (Show a, Num a, Ord a) => a -> Text
prettyNum
instance Render Double where render :: Double -> Text
render = String -> Text
Text.pack (String -> Text) -> (Double -> String) -> Double -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> String
forall a. Show a => a -> String
show
prettyNum :: Show a => Num a => Ord a => a -> Text
prettyNum :: a -> Text
prettyNum a
n = String -> Text
Text.pack (String -> String
addSign (String -> String
addCommas (a -> String
forall a. Show a => a -> String
show (a -> a
forall a. Num a => a -> a
abs a
n))))
where
addSign :: String -> String
addSign = if a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then (:) Char
'-' else String -> String
forall a. a -> a
id
addCommas :: String -> String
addCommas :: String -> String
addCommas = String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> [String]
forall e. Int -> [e] -> [[e]]
chunksOf Int
3 (String -> [String]) -> (String -> String) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse
newtype Stats = Stats RTSStats
getStats :: IO (Maybe Stats)
getStats :: IO (Maybe Stats)
getStats =
do Bool
enabled <- IO Bool
getRTSStatsEnabled
if Bool
enabled then Stats -> Maybe Stats
forall a. a -> Maybe a
Just (Stats -> Maybe Stats)
-> (RTSStats -> Stats) -> RTSStats -> Maybe Stats
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RTSStats -> Stats
Stats (RTSStats -> Maybe Stats) -> IO RTSStats -> IO (Maybe Stats)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO RTSStats
getRTSStats
else Maybe Stats -> IO (Maybe Stats)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Stats
forall a. Maybe a
Nothing
statsToEntries :: Stats -> [(Text, Text)]
statsToEntries :: Stats -> [(Text, Text)]
statsToEntries (Stats RTSStats
rts) =
let rgc :: GCDetails
rgc = RTSStats -> GCDetails
gc RTSStats
rts in GCDetails -> [(Text, Text)] -> [(Text, Text)]
seq GCDetails
rgc
[ (Text
"GCs" , Word32 -> Text
forall a. Render a => a -> Text
render (Word32 -> Text) -> Word32 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word32
gcs RTSStats
rts)
, (Text
"Major GCs" , Word32 -> Text
forall a. Render a => a -> Text
render (Word32 -> Text) -> Word32 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word32
major_gcs RTSStats
rts)
, (Text
"Allocated bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
allocated_bytes RTSStats
rts)
, (Text
"Max live bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
max_live_bytes RTSStats
rts)
, (Text
"Max large objects bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
max_large_objects_bytes RTSStats
rts)
, (Text
"Max compact bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
max_compact_bytes RTSStats
rts)
, (Text
"Max slop bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
max_slop_bytes RTSStats
rts)
, (Text
"Max memory in use bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
max_mem_in_use_bytes RTSStats
rts)
, (Text
"Cumulative live bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
cumulative_live_bytes RTSStats
rts)
, (Text
"Copied bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
copied_bytes RTSStats
rts)
, (Text
"Parallel copied bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
par_copied_bytes RTSStats
rts)
, (Text
"Cumulative parallel max copied bytes", Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Word64
cumulative_par_max_copied_bytes RTSStats
rts)
, (Text
"Mutator CPU ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Int64
mutator_cpu_ns RTSStats
rts)
, (Text
"Mutator elapsed ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Int64
mutator_elapsed_ns RTSStats
rts)
, (Text
"GC CPU ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Int64
gc_cpu_ns RTSStats
rts)
, (Text
"GC elapsed ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Int64
gc_elapsed_ns RTSStats
rts)
, (Text
"CPU ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Int64
cpu_ns RTSStats
rts)
, (Text
"Elapsed ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ RTSStats -> Int64
elapsed_ns RTSStats
rts)
, (Text
"==[Totals]==" , Text
"" )
, (Text
"" , Text
"" )
, (Text
"Generation" , Word32 -> Text
forall a. Render a => a -> Text
render (Word32 -> Text) -> Word32 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word32
gcdetails_gen GCDetails
rgc)
, (Text
"Threads" , Word32 -> Text
forall a. Render a => a -> Text
render (Word32 -> Text) -> Word32 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word32
gcdetails_threads GCDetails
rgc)
, (Text
"Allocated bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_allocated_bytes GCDetails
rgc)
, (Text
"Live bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_live_bytes GCDetails
rgc)
, (Text
"Large objects bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_large_objects_bytes GCDetails
rgc)
, (Text
"Compact bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_compact_bytes GCDetails
rgc)
, (Text
"Slop bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_slop_bytes GCDetails
rgc)
, (Text
"Memory in use bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_mem_in_use_bytes GCDetails
rgc)
, (Text
"Copied bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_copied_bytes GCDetails
rgc)
, (Text
"Parallel max copied bytes" , Word64 -> Text
forall a. Render a => a -> Text
render (Word64 -> Text) -> Word64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Word64
gcdetails_par_max_copied_bytes GCDetails
rgc)
, (Text
"Sync elapsed ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Int64
gcdetails_sync_elapsed_ns GCDetails
rgc)
, (Text
"CPU ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Int64
gcdetails_cpu_ns GCDetails
rgc)
, (Text
"Elapsed ns" , Int64 -> Text
forall a. Render a => a -> Text
render (Int64 -> Text) -> Int64 -> Text
forall a b. (a -> b) -> a -> b
$ GCDetails -> Int64
gcdetails_elapsed_ns GCDetails
rgc)
, (Text
"==[Last GC]==" , Text
"" )
]