mem-info 0.4.1.2 → 0.4.2.0
raw patch · 4 files changed
+107/−3 lines, 4 filesdep ~basenew-component:exe:mem_pidsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ System.MemInfo: BadSelfId :: NotRun
+ System.MemInfo: defaultRoot :: FilePath
+ System.MemInfo: instance GHC.Exception.Type.Exception System.MemInfo.NotRun
+ System.MemInfo: printUsages :: AsCmdName a => Map a MemUsage -> IO ()
+ System.MemInfo: selfId :: (MonadReader ProcRoot m, MonadIO m) => m ProcessID
+ System.MemInfo: selfId' :: IO ProcessID
Files
- ChangeLog.md +11/−1
- exe/MemPids.hs +46/−0
- mem-info.cabal +14/−1
- src/System/MemInfo.hs +36/−1
ChangeLog.md view
@@ -2,6 +2,16 @@ `mem-info` uses [PVP Versioning][1]. +## 0.4.2.0 -- 2026-02-11++- Add the function `selfId` to System.MemInfo to allow the current process+ to access its own process information++- Adds `printUsages` and `defaultRoot` as exports to System.MemInfo++- Add an example executable `mem_pids` that uses System.MemInfo functions as+ library functions+ ## 0.4.1.2 -- 2026-01-14 - Relax the upper bound on the containers dependency@@ -21,7 +31,7 @@ Used to specify an alternate process root than the default, _/proc_. This allows reporting of process status for other machines whose proc information has been mounted or synced to a local filesystem- + - Breaking changes: - [ProcNamer][2] takes an additional argument that specifies the proc filesystem root
+ exe/MemPids.hs view
@@ -0,0 +1,46 @@+{- |+Module : MemPids+Copyright : (c) 2022 Tim Emiola+Maintainer : Tim Emiola <adetokunbo@emio.la>+SPDX-License-Identifier: BSD3++An example program that prints the usage of a specified processes.+-}+module Main (main) where++import Data.List.NonEmpty (NonEmpty ((:|)))+import System.Environment (getArgs)+import System.MemInfo (+ defaultRoot,+ mkReportBud,+ printUsage,+ printUsages,+ readForOnePid,+ readMemUsage,+ selfId',+ )+import Text.Read (readEither)+++main :: IO ()+main = do+ let readPrintPid p = readForOnePid p >>= ifOkDo printUsage+ readProcID = either (const $ Left "bad pid") Right . readEither+ toProcessID = ifOkDo pure . readProcID+ args <- getArgs+ case args of+ [] -> selfId' >>= readPrintPid+ [x] -> toProcessID x >>= readPrintPid+ xs -> do+ let toEither = maybe (Left "odd: could not make a bud") Right+ mkReportBud' root pids = mkReportBud root pids >>= pure . toEither+ n : ns <- mapM toProcessID xs+ mkReportBud' defaultRoot (n :| ns) >>= ifOkDo readMemUsage >>= ifOkDo printUsages+++ifOkDo :: (Show a) => (b -> IO c) -> Either a b -> IO c+ifOkDo =+ let core = "Usage: mem_pids [args]"+ fail' x | show x == "" = fail core+ fail' x = fail $ core ++ ": error: " ++ show x+ in either fail'
mem-info.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: mem-info-version: 0.4.1.2+version: 0.4.2.0 synopsis: Print the core memory usage of programs description: A utility to accurately report the core memory usage of programs.@@ -101,6 +101,19 @@ -- printmem is the printmem command executable printmem main-is: PrintMem.hs+ hs-source-dirs: exe+ default-language: Haskell2010+ build-depends:+ , base >=4.14 && <5+ , mem-info++ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ ghc-options:+ -Wall -Wincomplete-uni-patterns -Wpartial-fields -fwarn-tabs++-- mem_pids is an example that reports the usage of one or many pids+executable mem_pids+ main-is: MemPids.hs hs-source-dirs: exe default-language: Haskell2010 build-depends:
src/System/MemInfo.hs view
@@ -49,15 +49,22 @@ -- * Print /MemUsage/ printUsage', printUsage,+ printUsages, + -- * The current process ID+ selfId,+ selfId',+ -- * Convenient re-exports mkReportBud,+ defaultRoot, ProcessID, AsCmdName (..), ) where +import Control.Exception (Exception) import Control.Monad.IO.Class (MonadIO, liftIO)-import Control.Monad.Reader (MonadReader (ask), runReaderT)+import Control.Monad.Reader (MonadReader (ask), asks, runReaderT) import Data.Bifunctor (Bifunctor (..)) import Data.Functor ((<&>)) import Data.List (sortBy)@@ -168,6 +175,14 @@ printUsage = flip printUsage' True +-- | Like @'printUsage' for several @processIDs@+printUsages ::+ (AsCmdName a) =>+ Map a MemUsage ->+ IO ()+printUsages = mapM_ printUsage . Map.toAscList++ onlyPrintTotal :: (AsCmdName k) => ReportBud -> Bool -> Bool -> [(k, MemUsage)] -> IO () onlyPrintTotal bud showSwap onlyTotal totals = do let (private, swap) = overallTotals $ map snd totals@@ -453,15 +468,20 @@ | NeedsRoot | OddKernel | NoRecords+ | BadSelfId deriving (Eq, Show) +instance Exception NotRun++ fmtNotRun :: NotRun -> Text fmtNotRun NeedsRoot = "run as root when no pids are specified using -p" fmtNotRun (PidLost x) = fmtLostPid x fmtNotRun OddKernel = "unrecognized kernel version" fmtNotRun (MissingPids pids) = "no records available for: " +| listF (toInteger <$> pids) |+ "" fmtNotRun NoRecords = "could not find any process records"+fmtNotRun BadSelfId = "self value was not a valid process ID" {- | Represents reasons a specified @pid@ may not have memory@@ -517,6 +537,21 @@ fromBadStatus NoParent = NoStatusParent pid statusPath <- pidPath "status" pid first fromBadStatus . parseStatusInfo <$> liftIO (readUtf8Text statusPath)+++-- | the processId of the current running process+selfId :: (MonadReader ProcRoot m, MonadIO m) => m ProcessID+selfId = do+ let mkSelfPath root = "" +| root |+ "/self"+ selfText <- asks mkSelfPath >>= liftIO . getSymbolicLinkTarget+ case readMaybe selfText of+ Just procId -> pure procId+ Nothing -> liftIO $ throwIO BadSelfId+++-- | Like 'selfId' using the default ProcRoot+selfId' :: IO ProcessID+selfId' = runReaderT selfId defaultRoot parseCmdline :: Text -> Maybe (NonEmpty Text)