-
-
Notifications
You must be signed in to change notification settings - Fork 390
Log live_bytes and heap_size as reported by GHC.Stats #1508
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
Changes from all commits
c460f78
e6b973b
adcd0fd
74cb490
cb8ba71
63eadb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
{-# LANGUAGE NumericUnderscores #-} | ||
-- | Logging utilities for reporting heap statistics | ||
module Development.IDE.Main.HeapStats ( withHeapStats ) where | ||
|
||
import GHC.Stats | ||
import Development.IDE.Types.Logger (Logger, logInfo) | ||
import Control.Concurrent.Async | ||
import qualified Data.Text as T | ||
import Data.Word | ||
import Control.Monad | ||
import Control.Concurrent | ||
import Text.Printf (printf) | ||
|
||
-- | Interval at which to report the latest heap statistics. | ||
heapStatsInterval :: Int | ||
heapStatsInterval = 60_000_000 -- 60s | ||
|
||
-- | Report the live bytes and heap size at the last major collection. | ||
logHeapStats :: Logger -> IO () | ||
logHeapStats l = do | ||
stats <- getRTSStats | ||
-- live_bytes is the total amount of live memory in a program | ||
-- (corresponding to the amount on a heap profile) | ||
let live_bytes = gcdetails_live_bytes (gc stats) | ||
-- heap_size is the total amount of memory the RTS is using | ||
-- this corresponds closer to OS memory usage | ||
heap_size = gcdetails_mem_in_use_bytes (gc stats) | ||
format :: Word64 -> T.Text | ||
format m = T.pack (printf "%.2fMB" (fromIntegral @Word64 @Double m / 1e6)) | ||
message = "Live bytes: " <> format live_bytes <> " " <> | ||
"Heap size: " <> format heap_size | ||
logInfo l message | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is Info the right severity? Telemetry? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I choose There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it depends what the purpose of this logging is. |
||
|
||
-- | An action which logs heap statistics at the 'heapStatsInterval' | ||
heapStatsThread :: Logger -> IO r | ||
heapStatsThread l = forever $ do | ||
threadDelay heapStatsInterval | ||
logHeapStats l | ||
|
||
-- | A helper function which lauches the 'heapStatsThread' and kills it | ||
-- appropiately when the inner action finishes. It also checks to see | ||
-- if `-T` is enabled. | ||
withHeapStats :: Logger -> IO r -> IO r | ||
withHeapStats l k = do | ||
enabled <- getRTSStatsEnabled | ||
if enabled | ||
then do | ||
logInfo l ("Logging heap statistics every " | ||
<> T.pack (printf "%.2fs" (fromIntegral @Int @Double heapStatsInterval / 1e6))) | ||
withAsync (heapStatsThread l) (const k) | ||
else do | ||
logInfo l "Heap statistics are not enabled (RTS option -T is needed)" | ||
k |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a config option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A command line option? I am not sure configuring this is very useful,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
60s seems arbitrary. A config or command line option would make the choice available to the user