module Network.Wai.Application.Monitoring (monitorGC) where
import Control.Monad.IO.Class (liftIO)
import qualified Data.HashMap.Strict as M
import qualified GHC.Stats as Stats
import Network.HTTP.Types (status200)
import Network.Wai (Application, Response(ResponseBuilder))
import Blaze.ByteString.Builder (fromLazyByteString)
import Data.Aeson (toJSON, Value(Object))
import Data.Aeson.Encode (encode)
monitorGC :: Application
monitorGC _ = do
stats <- liftIO Stats.getGCStats
return $ ResponseBuilder
status200
[("Content-Type", "application/json")]
$ fromLazyByteString $ encode $ partitionGCStats stats
partitionGCStats :: Stats.GCStats
-> Value
partitionGCStats (Stats.GCStats {..}) =
Object $ M.fromList [("counters", counters), ("gauges", gauges)]
where
counters = Object $ M.fromList
[ ("bytes_allocated" , toJSON bytesAllocated)
, ("num_gcs" , toJSON numGcs)
, ("num_bytes_usage_samples" , toJSON numByteUsageSamples)
, ("cumulative_bytes_used" , toJSON cumulativeBytesUsed)
, ("bytes_copied" , toJSON bytesCopied)
, ("mutator_cpu_seconds" , toJSON mutatorCpuSeconds)
, ("mutator_wall_seconds" , toJSON mutatorWallSeconds)
, ("gc_cpu_seconds" , toJSON gcCpuSeconds)
, ("gc_wall_seconds" , toJSON gcWallSeconds)
, ("cpu_seconds" , toJSON cpuSeconds)
, ("wall_seconds" , toJSON wallSeconds)
]
gauges = Object $ M.fromList
[ ("max_bytes_used" , toJSON maxBytesUsed)
, ("current_bytes_used" , toJSON currentBytesUsed)
, ("current_bytes_slop" , toJSON currentBytesSlop)
, ("max_bytes_slop" , toJSON maxBytesSlop)
, ("peak_megabytes_allocated" , toJSON $ peakMegabytesAllocated*1024*1024)
, ("par_avg_bytes_copied" , toJSON parAvgBytesCopied)
, ("par_max_bytes_copied" , toJSON parMaxBytesCopied)
]