-- | Generic code to poll any of the many data files maintained by the kernel in -- POSIX systems. Provides methods for applying a custom parsing function to the -- contents of the file and to calculate differentials across one or more values -- provided via the file. module System.Information.StreamInfo ( getParsedInfo , getLoad , getTransfer) where import Control.Concurrent (threadDelay) import Data.Maybe (fromJust) -- | Apply the given parser function to the file under the given path to produce -- a lookup map, then use the given selector as key to extract from it the -- desired value. getParsedInfo :: FilePath -> (String -> [(String, [Integer])]) -> String -> IO [Integer] getParsedInfo path parser selector = do file <- readFile path (length file) `seq` return () return (fromJust $ lookup selector $ parser file) truncVal :: Double -> Double truncVal v | isNaN v || v < 0.0 = 0.0 | otherwise = v -- | Execute the given action twice with the given delay in-between and return -- the difference between the two samples. probe :: IO [Integer] -> Double -> IO [Integer] probe action delay = do a <- action threadDelay $ round (delay * 1e6) b <- action return $ zipWith (-) b a -- | Probe the given action and, interpreting the result as a variation in time, -- return the speed of change of its values. getTransfer :: Double -> IO [Integer] -> IO [Double] getTransfer interval action = do deltas <- probe action interval return $ map (truncVal . (/interval) . fromIntegral) deltas -- | Probe the given action and return the relative variation of each of the -- obtained values against the whole, where the whole is calculated as the sum -- of all the values in the probe. getLoad :: Double -> IO [Integer] -> IO [Double] getLoad interval action = do deltas <- probe action interval let total = fromIntegral $ foldr (+) 0 deltas ratios = map ((/total) . fromIntegral) deltas return $ map truncVal ratios