Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to the new GHC.Stats API #23

Merged
merged 1 commit into from Feb 27, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
136 changes: 100 additions & 36 deletions System/Metrics.hs
Expand Up @@ -331,9 +331,15 @@ createDistribution name store = do
-- easily be added to a metrics store by calling their register
-- function.

#if MIN_VERSION_base(4,10,0)
-- | Convert nanoseconds to milliseconds.
nsToMs :: Int64 -> Int64
nsToMs s = round (realToFrac s / (1000000.0 :: Double))
#else
-- | Convert seconds to milliseconds.
toMs :: Double -> Int64
toMs s = round (s * 1000.0)
sToMs :: Double -> Int64
sToMs s = round (s * 1000.0)
#endif

-- | Register a number of metrics related to garbage collector
-- behavior.
Expand Down Expand Up @@ -410,18 +416,42 @@ toMs s = round (s * 1000.0)
registerGcMetrics :: Store -> IO ()
registerGcMetrics store =
registerGroup
#if MIN_VERSION_base(4,10,0)
(M.fromList
[ ("rts.gc.bytes_allocated" , Counter . fromIntegral . Stats.allocated_bytes)
, ("rts.gc.num_gcs" , Counter . fromIntegral . Stats.gcs)
, ("rts.gc.num_bytes_usage_samples" , Counter . fromIntegral . Stats.major_gcs)
, ("rts.gc.cumulative_bytes_used" , Counter . fromIntegral . Stats.cumulative_live_bytes)
, ("rts.gc.bytes_copied" , Counter . fromIntegral . Stats.copied_bytes)
, ("rts.gc.mutator_cpu_ms" , Counter . nsToMs . Stats.mutator_cpu_ns)
, ("rts.gc.mutator_wall_ms" , Counter . nsToMs . Stats.mutator_elapsed_ns)
, ("rts.gc.gc_cpu_ms" , Counter . nsToMs . Stats.gc_cpu_ns)
, ("rts.gc.gc_wall_ms" , Counter . nsToMs . Stats.gc_elapsed_ns)
, ("rts.gc.cpu_ms" , Counter . nsToMs . Stats.cpu_ns)
, ("rts.gc.wall_ms" , Counter . nsToMs . Stats.elapsed_ns)
, ("rts.gc.max_bytes_used" , Gauge . fromIntegral . Stats.max_live_bytes)
, ("rts.gc.current_bytes_used" , Gauge . fromIntegral . Stats.gcdetails_live_bytes . Stats.gc)
, ("rts.gc.current_bytes_slop" , Gauge . fromIntegral . Stats.gcdetails_slop_bytes . Stats.gc)
, ("rts.gc.max_bytes_slop" , Gauge . fromIntegral . Stats.max_slop_bytes)
, ("rts.gc.peak_megabytes_allocated" , Gauge . fromIntegral . (`quot` (1024*1024)) . Stats.max_mem_in_use_bytes)
, ("rts.gc.par_tot_bytes_copied" , Gauge . fromIntegral . Stats.par_copied_bytes)
, ("rts.gc.par_avg_bytes_copied" , Gauge . fromIntegral . Stats.par_copied_bytes)
, ("rts.gc.par_max_bytes_copied" , Gauge . fromIntegral . Stats.cumulative_par_max_copied_bytes)
])
getRTSStats
#else
(M.fromList
[ ("rts.gc.bytes_allocated" , Counter . Stats.bytesAllocated)
, ("rts.gc.num_gcs" , Counter . Stats.numGcs)
, ("rts.gc.num_bytes_usage_samples" , Counter . Stats.numByteUsageSamples)
, ("rts.gc.cumulative_bytes_used" , Counter . Stats.cumulativeBytesUsed)
, ("rts.gc.bytes_copied" , Counter . Stats.bytesCopied)
, ("rts.gc.mutator_cpu_ms" , Counter . toMs . Stats.mutatorCpuSeconds)
, ("rts.gc.mutator_wall_ms" , Counter . toMs . Stats.mutatorWallSeconds)
, ("rts.gc.gc_cpu_ms" , Counter . toMs . Stats.gcCpuSeconds)
, ("rts.gc.gc_wall_ms" , Counter . toMs . Stats.gcWallSeconds)
, ("rts.gc.cpu_ms" , Counter . toMs . Stats.cpuSeconds)
, ("rts.gc.wall_ms" , Counter . toMs . Stats.wallSeconds)
, ("rts.gc.mutator_cpu_ms" , Counter . sToMs . Stats.mutatorCpuSeconds)
, ("rts.gc.mutator_wall_ms" , Counter . sToMs . Stats.mutatorWallSeconds)
, ("rts.gc.gc_cpu_ms" , Counter . sToMs . Stats.gcCpuSeconds)
, ("rts.gc.gc_wall_ms" , Counter . sToMs . Stats.gcWallSeconds)
, ("rts.gc.cpu_ms" , Counter . sToMs . Stats.cpuSeconds)
, ("rts.gc.wall_ms" , Counter . sToMs . Stats.wallSeconds)
, ("rts.gc.max_bytes_used" , Gauge . Stats.maxBytesUsed)
, ("rts.gc.current_bytes_used" , Gauge . Stats.currentBytesUsed)
, ("rts.gc.current_bytes_slop" , Gauge . Stats.currentBytesSlop)
Expand All @@ -432,11 +462,68 @@ registerGcMetrics store =
, ("rts.gc.par_max_bytes_copied" , Gauge . Stats.parMaxBytesCopied)
])
getGcStats
#endif
store

#if MIN_VERSION_base(4,10,0)
-- | Get RTS statistics.
getRTSStats :: IO Stats.RTSStats
getRTSStats = do
enabled <- Stats.getRTSStatsEnabled
if enabled
then Stats.getRTSStats
else return emptyRTSStats

-- | Empty RTS statistics, as if the application hasn't started yet.
emptyRTSStats :: Stats.RTSStats
emptyRTSStats = Stats.RTSStats
{ gcs = 0
, major_gcs = 0
, allocated_bytes = 0
, max_live_bytes = 0
, max_large_objects_bytes = 0
, max_compact_bytes = 0
, max_slop_bytes = 0
, max_mem_in_use_bytes = 0
, cumulative_live_bytes = 0
, copied_bytes = 0
, par_copied_bytes = 0
, cumulative_par_max_copied_bytes = 0
# if MIN_VERSION_base(4,11,0)
, cumulative_par_balanced_copied_bytes = 0
# endif
, mutator_cpu_ns = 0
, mutator_elapsed_ns = 0
, gc_cpu_ns = 0
, gc_elapsed_ns = 0
, cpu_ns = 0
, elapsed_ns = 0
, gc = emptyGCDetails
}

emptyGCDetails :: Stats.GCDetails
emptyGCDetails = Stats.GCDetails
{ gcdetails_gen = 0
, gcdetails_threads = 0
, gcdetails_allocated_bytes = 0
, gcdetails_live_bytes = 0
, gcdetails_large_objects_bytes = 0
, gcdetails_compact_bytes = 0
, gcdetails_slop_bytes = 0
, gcdetails_mem_in_use_bytes = 0
, gcdetails_copied_bytes = 0
, gcdetails_par_max_copied_bytes = 0
# if MIN_VERSION_base(4,11,0)
, gcdetails_par_balanced_copied_bytes = 0
# endif
, gcdetails_sync_elapsed_ns = 0
, gcdetails_cpu_ns = 0
, gcdetails_elapsed_ns = 0
}
#else
-- | Get GC statistics.
getGcStats :: IO Stats.GCStats
#if MIN_VERSION_base(4,6,0)
# if MIN_VERSION_base(4,6,0)
getGcStats = do
enabled <- Stats.getGCStatsEnabled
if enabled
Expand All @@ -445,7 +532,6 @@ getGcStats = do

-- | Empty GC statistics, as if the application hasn't started yet.
emptyGCStats :: Stats.GCStats
# if MIN_VERSION_base(4,10,0)
emptyGCStats = Stats.GCStats
{ bytesAllocated = 0
, numGcs = 0
Expand All @@ -465,40 +551,18 @@ emptyGCStats = Stats.GCStats
, wallSeconds = 0
, parTotBytesCopied = 0
, parMaxBytesCopied = 0
, mblocksAllocated = 0
}
# else
emptyGCStats = Stats.GCStats
{ bytesAllocated = 0
, numGcs = 0
, maxBytesUsed = 0
, numByteUsageSamples = 0
, cumulativeBytesUsed = 0
, bytesCopied = 0
, currentBytesUsed = 0
, currentBytesSlop = 0
, maxBytesSlop = 0
, peakMegabytesAllocated = 0
, mutatorCpuSeconds = 0
, mutatorWallSeconds = 0
, gcCpuSeconds = 0
, gcWallSeconds = 0
, cpuSeconds = 0
, wallSeconds = 0
, parTotBytesCopied = 0
, parMaxBytesCopied = 0
}
# endif
#else
getGcStats = Stats.getGCStats
#endif
# endif

-- | Helper to work around rename in GHC.Stats in base-4.6.
gcParTotBytesCopied :: Stats.GCStats -> Int64
#if MIN_VERSION_base(4,6,0)
# if MIN_VERSION_base(4,6,0)
gcParTotBytesCopied = Stats.parTotBytesCopied
#else
# else
gcParTotBytesCopied = Stats.parAvgBytesCopied
# endif
#endif

------------------------------------------------------------------------
Expand Down