{-#LANGUAGE CPP #-}
{-#LANGUAGE RecordWildCards#-}
module Xmobar.Plugins.Monitors.Cpu
( startCpu
, runCpu
, cpuConfig
, CpuDataRef
, CpuOpts
, CpuArguments
, parseCpu
, getArguments
) where
import Xmobar.Plugins.Monitors.Common
import qualified Data.ByteString.Lazy.Char8 as B
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
#ifdef FREEBSD
import System.BSD.Sysctl (sysctlPeekArray)
#endif
import System.Console.GetOpt
import Xmobar.App.Timer (doEveryTenthSeconds)
import Control.Monad (void)
newtype CpuOpts = CpuOpts
{ CpuOpts -> Maybe IconPattern
loadIconPattern :: Maybe IconPattern
}
defaultOpts :: CpuOpts
defaultOpts :: CpuOpts
defaultOpts = CpuOpts :: Maybe IconPattern -> CpuOpts
CpuOpts
{ loadIconPattern :: Maybe IconPattern
loadIconPattern = Maybe IconPattern
forall a. Maybe a
Nothing
}
options :: [OptDescr (CpuOpts -> CpuOpts)]
options :: [OptDescr (CpuOpts -> CpuOpts)]
options =
[ String
-> [String]
-> ArgDescr (CpuOpts -> CpuOpts)
-> String
-> OptDescr (CpuOpts -> CpuOpts)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"" [String
"load-icon-pattern"] ((String -> CpuOpts -> CpuOpts)
-> String -> ArgDescr (CpuOpts -> CpuOpts)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
x CpuOpts
o ->
CpuOpts
o { loadIconPattern :: Maybe IconPattern
loadIconPattern = IconPattern -> Maybe IconPattern
forall a. a -> Maybe a
Just (IconPattern -> Maybe IconPattern)
-> IconPattern -> Maybe IconPattern
forall a b. (a -> b) -> a -> b
$ String -> IconPattern
parseIconPattern String
x }) String
"") String
""
]
barField :: String
barField :: String
barField = String
"bar"
vbarField :: String
vbarField :: String
vbarField = String
"vbar"
ipatField :: String
ipatField :: String
ipatField = String
"ipat"
totalField :: String
totalField :: String
totalField = String
"total"
userField :: String
userField :: String
userField = String
"user"
niceField :: String
niceField :: String
niceField = String
"nice"
systemField :: String
systemField :: String
systemField = String
"system"
idleField :: String
idleField :: String
idleField = String
"idle"
iowaitField :: String
iowaitField :: String
iowaitField = String
"iowait"
cpuConfig :: IO MConfig
cpuConfig :: IO MConfig
cpuConfig =
String -> [String] -> IO MConfig
mkMConfig
String
"Cpu: <total>%"
[ String
barField
, String
vbarField
, String
ipatField
, String
totalField
, String
userField
, String
niceField
, String
systemField
, String
idleField
, String
iowaitField
]
data CpuData = CpuData {
CpuData -> Float
cpuUser :: !Float,
CpuData -> Float
cpuNice :: !Float,
CpuData -> Float
cpuSystem :: !Float,
CpuData -> Float
cpuIdle :: !Float,
CpuData -> Float
cpuIowait :: !Float,
CpuData -> Float
cpuTotal :: !Float
}
#ifdef FREEBSD
type CpuDataRef = IORef [Word]
cpuData :: IO [Word]
cpuData = sysctlPeekArray "kern.cp_time" :: IO [Word]
parseCpu :: CpuDataRef -> IO CpuData
parseCpu cref = do
prev <- readIORef cref
curr <- cpuData
writeIORef cref curr
let diff = map fromIntegral $ zipWith (-) curr prev
user = diff !! 0
nice = diff !! 1
system = diff !! 2
intr = diff !! 3
idle = diff !! 4
total = user + nice + system + intr + idle
return CpuData
{ cpuUser = user/total
, cpuNice = nice/total
, cpuSystem = (system+intr)/total
, cpuIdle = idle/total
, cpuIowait = 0
, cpuTotal = user/total
}
#else
type CpuDataRef = IORef [Int]
cpuData :: IO [Int]
cpuData :: IO [Int]
cpuData = ByteString -> [Int]
cpuParser (ByteString -> [Int]) -> IO ByteString -> IO [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO ByteString
B.readFile String
"/proc/stat"
readInt :: B.ByteString -> Int
readInt :: ByteString -> Int
readInt ByteString
bs = case ByteString -> Maybe (Int, ByteString)
B.readInt ByteString
bs of
Maybe (Int, ByteString)
Nothing -> Int
0
Just (Int
i, ByteString
_) -> Int
i
cpuParser :: B.ByteString -> [Int]
cpuParser :: ByteString -> [Int]
cpuParser = (ByteString -> Int) -> [ByteString] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Int
readInt ([ByteString] -> [Int])
-> (ByteString -> [ByteString]) -> ByteString -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
forall a. [a] -> [a]
tail ([ByteString] -> [ByteString])
-> (ByteString -> [ByteString]) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
B.words (ByteString -> [ByteString])
-> (ByteString -> ByteString) -> ByteString -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
forall a. [a] -> a
head ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
B.lines
convertToCpuData :: [Float] -> CpuData
convertToCpuData :: [Float] -> CpuData
convertToCpuData (Float
u:Float
n:Float
s:Float
ie:Float
iw:[Float]
_) =
CpuData :: Float -> Float -> Float -> Float -> Float -> Float -> CpuData
CpuData
{ cpuUser :: Float
cpuUser = Float
u
, cpuNice :: Float
cpuNice = Float
n
, cpuSystem :: Float
cpuSystem = Float
s
, cpuIdle :: Float
cpuIdle = Float
ie
, cpuIowait :: Float
cpuIowait = Float
iw
, cpuTotal :: Float
cpuTotal = [Float] -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Float
u, Float
n, Float
s]
}
convertToCpuData [Float]
args = String -> CpuData
forall a. HasCallStack => String -> a
error (String -> CpuData) -> String -> CpuData
forall a b. (a -> b) -> a -> b
$ String
"convertToCpuData: Unexpected list" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [Float] -> String
forall a. Show a => a -> String
show [Float]
args
parseCpu :: CpuDataRef -> IO CpuData
parseCpu :: CpuDataRef -> IO CpuData
parseCpu CpuDataRef
cref =
do [Int]
a <- CpuDataRef -> IO [Int]
forall a. IORef a -> IO a
readIORef CpuDataRef
cref
[Int]
b <- IO [Int]
cpuData
CpuDataRef -> [Int] -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef CpuDataRef
cref [Int]
b
let dif :: [Int]
dif = (Int -> Int -> Int) -> [Int] -> [Int] -> [Int]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) [Int]
b [Int]
a
tot :: Float
tot = Int -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Float) -> Int -> Float
forall a b. (a -> b) -> a -> b
$ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
dif
safeDiv :: a -> Float
safeDiv a
n = case Float
tot of
Float
0 -> Float
0
Float
v -> a -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
v
percent :: [Float]
percent = (Int -> Float) -> [Int] -> [Float]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Float
forall {a}. Integral a => a -> Float
safeDiv [Int]
dif
CpuData -> IO CpuData
forall (m :: * -> *) a. Monad m => a -> m a
return (CpuData -> IO CpuData) -> CpuData -> IO CpuData
forall a b. (a -> b) -> a -> b
$ [Float] -> CpuData
convertToCpuData [Float]
percent
#endif
data Field = Field {
Field -> String
fieldName :: !String,
Field -> ShouldCompute
fieldCompute :: !ShouldCompute
} deriving (Field -> Field -> Bool
(Field -> Field -> Bool) -> (Field -> Field -> Bool) -> Eq Field
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Field -> Field -> Bool
$c/= :: Field -> Field -> Bool
== :: Field -> Field -> Bool
$c== :: Field -> Field -> Bool
Eq, Eq Field
Eq Field
-> (Field -> Field -> Ordering)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Field)
-> (Field -> Field -> Field)
-> Ord Field
Field -> Field -> Bool
Field -> Field -> Ordering
Field -> Field -> Field
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Field -> Field -> Field
$cmin :: Field -> Field -> Field
max :: Field -> Field -> Field
$cmax :: Field -> Field -> Field
>= :: Field -> Field -> Bool
$c>= :: Field -> Field -> Bool
> :: Field -> Field -> Bool
$c> :: Field -> Field -> Bool
<= :: Field -> Field -> Bool
$c<= :: Field -> Field -> Bool
< :: Field -> Field -> Bool
$c< :: Field -> Field -> Bool
compare :: Field -> Field -> Ordering
$ccompare :: Field -> Field -> Ordering
Ord, Int -> Field -> String -> String
[Field] -> String -> String
Field -> String
(Int -> Field -> String -> String)
-> (Field -> String) -> ([Field] -> String -> String) -> Show Field
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Field] -> String -> String
$cshowList :: [Field] -> String -> String
show :: Field -> String
$cshow :: Field -> String
showsPrec :: Int -> Field -> String -> String
$cshowsPrec :: Int -> Field -> String -> String
Show)
data ShouldCompute = Compute | Skip deriving (ShouldCompute -> ShouldCompute -> Bool
(ShouldCompute -> ShouldCompute -> Bool)
-> (ShouldCompute -> ShouldCompute -> Bool) -> Eq ShouldCompute
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ShouldCompute -> ShouldCompute -> Bool
$c/= :: ShouldCompute -> ShouldCompute -> Bool
== :: ShouldCompute -> ShouldCompute -> Bool
$c== :: ShouldCompute -> ShouldCompute -> Bool
Eq, Eq ShouldCompute
Eq ShouldCompute
-> (ShouldCompute -> ShouldCompute -> Ordering)
-> (ShouldCompute -> ShouldCompute -> Bool)
-> (ShouldCompute -> ShouldCompute -> Bool)
-> (ShouldCompute -> ShouldCompute -> Bool)
-> (ShouldCompute -> ShouldCompute -> Bool)
-> (ShouldCompute -> ShouldCompute -> ShouldCompute)
-> (ShouldCompute -> ShouldCompute -> ShouldCompute)
-> Ord ShouldCompute
ShouldCompute -> ShouldCompute -> Bool
ShouldCompute -> ShouldCompute -> Ordering
ShouldCompute -> ShouldCompute -> ShouldCompute
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ShouldCompute -> ShouldCompute -> ShouldCompute
$cmin :: ShouldCompute -> ShouldCompute -> ShouldCompute
max :: ShouldCompute -> ShouldCompute -> ShouldCompute
$cmax :: ShouldCompute -> ShouldCompute -> ShouldCompute
>= :: ShouldCompute -> ShouldCompute -> Bool
$c>= :: ShouldCompute -> ShouldCompute -> Bool
> :: ShouldCompute -> ShouldCompute -> Bool
$c> :: ShouldCompute -> ShouldCompute -> Bool
<= :: ShouldCompute -> ShouldCompute -> Bool
$c<= :: ShouldCompute -> ShouldCompute -> Bool
< :: ShouldCompute -> ShouldCompute -> Bool
$c< :: ShouldCompute -> ShouldCompute -> Bool
compare :: ShouldCompute -> ShouldCompute -> Ordering
$ccompare :: ShouldCompute -> ShouldCompute -> Ordering
Ord, Int -> ShouldCompute -> String -> String
[ShouldCompute] -> String -> String
ShouldCompute -> String
(Int -> ShouldCompute -> String -> String)
-> (ShouldCompute -> String)
-> ([ShouldCompute] -> String -> String)
-> Show ShouldCompute
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [ShouldCompute] -> String -> String
$cshowList :: [ShouldCompute] -> String -> String
show :: ShouldCompute -> String
$cshow :: ShouldCompute -> String
showsPrec :: Int -> ShouldCompute -> String -> String
$cshowsPrec :: Int -> ShouldCompute -> String -> String
Show)
formatField :: MonitorConfig -> CpuOpts -> CpuData -> Field -> IO String
formatField :: MonitorConfig -> CpuOpts -> CpuData -> Field -> IO String
formatField MonitorConfig
cpuParams CpuOpts
cpuOpts cpuInfo :: CpuData
cpuInfo@CpuData {Float
cpuTotal :: Float
cpuIowait :: Float
cpuIdle :: Float
cpuSystem :: Float
cpuNice :: Float
cpuUser :: Float
cpuTotal :: CpuData -> Float
cpuIowait :: CpuData -> Float
cpuIdle :: CpuData -> Float
cpuSystem :: CpuData -> Float
cpuNice :: CpuData -> Float
cpuUser :: CpuData -> Float
..} Field {String
ShouldCompute
fieldCompute :: ShouldCompute
fieldName :: String
fieldCompute :: Field -> ShouldCompute
fieldName :: Field -> String
..}
| String
fieldName String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
barField =
if ShouldCompute
fieldCompute ShouldCompute -> ShouldCompute -> Bool
forall a. Eq a => a -> a -> Bool
== ShouldCompute
Compute
then MonitorConfig -> Float -> Float -> IO String
forall (m :: * -> *).
MonadIO m =>
MonitorConfig -> Float -> Float -> m String
pShowPercentBar MonitorConfig
cpuParams (Float
100 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cpuTotal) Float
cpuTotal
else String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| String
fieldName String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
vbarField =
if ShouldCompute
fieldCompute ShouldCompute -> ShouldCompute -> Bool
forall a. Eq a => a -> a -> Bool
== ShouldCompute
Compute
then MonitorConfig -> Float -> Float -> IO String
forall (m :: * -> *).
MonadIO m =>
MonitorConfig -> Float -> Float -> m String
pShowVerticalBar MonitorConfig
cpuParams (Float
100 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cpuTotal) Float
cpuTotal
else String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| String
fieldName String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
ipatField =
if ShouldCompute
fieldCompute ShouldCompute -> ShouldCompute -> Bool
forall a. Eq a => a -> a -> Bool
== ShouldCompute
Compute
then Maybe IconPattern -> Float -> IO String
pShowIconPattern (CpuOpts -> Maybe IconPattern
loadIconPattern CpuOpts
cpuOpts) Float
cpuTotal
else String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| Bool
otherwise =
if ShouldCompute
fieldCompute ShouldCompute -> ShouldCompute -> Bool
forall a. Eq a => a -> a -> Bool
== ShouldCompute
Compute
then MonitorConfig -> Float -> IO String
forall (m :: * -> *).
MonadIO m =>
MonitorConfig -> Float -> m String
pShowPercentWithColors MonitorConfig
cpuParams (String -> CpuData -> Float
getFieldValue String
fieldName CpuData
cpuInfo)
else String -> IO String
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
getFieldValue :: String -> CpuData -> Float
getFieldValue :: String -> CpuData -> Float
getFieldValue String
field CpuData{Float
cpuTotal :: Float
cpuIowait :: Float
cpuIdle :: Float
cpuSystem :: Float
cpuNice :: Float
cpuUser :: Float
cpuTotal :: CpuData -> Float
cpuIowait :: CpuData -> Float
cpuIdle :: CpuData -> Float
cpuSystem :: CpuData -> Float
cpuNice :: CpuData -> Float
cpuUser :: CpuData -> Float
..}
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
barField = Float
cpuTotal
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
vbarField = Float
cpuTotal
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
ipatField = Float
cpuTotal
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
totalField = Float
cpuTotal
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
userField = Float
cpuUser
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
niceField = Float
cpuNice
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
systemField = Float
cpuSystem
| String
field String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
idleField = Float
cpuIdle
| Bool
otherwise = Float
cpuIowait
computeFields :: [String] -> [String] -> [Field]
computeFields :: [String] -> [String] -> [Field]
computeFields [] [String]
_ = []
computeFields (String
x:[String]
xs) [String]
inputFields =
if String
x String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
inputFields
then (Field :: String -> ShouldCompute -> Field
Field {fieldName :: String
fieldName = String
x, fieldCompute :: ShouldCompute
fieldCompute = ShouldCompute
Compute}) Field -> [Field] -> [Field]
forall a. a -> [a] -> [a]
:
[String] -> [String] -> [Field]
computeFields [String]
xs [String]
inputFields
else (Field :: String -> ShouldCompute -> Field
Field {fieldName :: String
fieldName = String
x, fieldCompute :: ShouldCompute
fieldCompute = ShouldCompute
Skip}) Field -> [Field] -> [Field]
forall a. a -> [a] -> [a]
:
[String] -> [String] -> [Field]
computeFields [String]
xs [String]
inputFields
formatCpu :: CpuArguments -> CpuData -> IO [String]
formatCpu :: CpuArguments -> CpuData -> IO [String]
formatCpu CpuArguments{[String]
[(String, [(String, String, String)])]
[(String, String, String)]
[Field]
CpuDataRef
MonitorConfig
CpuOpts
cpuFields :: CpuArguments -> [Field]
cpuAllTemplate :: CpuArguments -> [(String, [(String, String, String)])]
cpuInputTemplate :: CpuArguments -> [(String, String, String)]
cpuOpts :: CpuArguments -> CpuOpts
cpuArgs :: CpuArguments -> [String]
cpuParams :: CpuArguments -> MonitorConfig
cpuDataRef :: CpuArguments -> CpuDataRef
cpuFields :: [Field]
cpuAllTemplate :: [(String, [(String, String, String)])]
cpuInputTemplate :: [(String, String, String)]
cpuOpts :: CpuOpts
cpuArgs :: [String]
cpuParams :: MonitorConfig
cpuDataRef :: CpuDataRef
..} CpuData
cpuInfo = do
[String]
strs <- (Field -> IO String) -> [Field] -> IO [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (MonitorConfig -> CpuOpts -> CpuData -> Field -> IO String
formatField MonitorConfig
cpuParams CpuOpts
cpuOpts CpuData
cpuInfo) [Field]
cpuFields
[String] -> IO [String]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (String -> Bool) -> String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) [String]
strs
getInputFields :: CpuArguments -> [String]
getInputFields :: CpuArguments -> [String]
getInputFields CpuArguments{[String]
[(String, [(String, String, String)])]
[(String, String, String)]
[Field]
CpuDataRef
MonitorConfig
CpuOpts
cpuFields :: [Field]
cpuAllTemplate :: [(String, [(String, String, String)])]
cpuInputTemplate :: [(String, String, String)]
cpuOpts :: CpuOpts
cpuArgs :: [String]
cpuParams :: MonitorConfig
cpuDataRef :: CpuDataRef
cpuFields :: CpuArguments -> [Field]
cpuAllTemplate :: CpuArguments -> [(String, [(String, String, String)])]
cpuInputTemplate :: CpuArguments -> [(String, String, String)]
cpuOpts :: CpuArguments -> CpuOpts
cpuArgs :: CpuArguments -> [String]
cpuParams :: CpuArguments -> MonitorConfig
cpuDataRef :: CpuArguments -> CpuDataRef
..} = ((String, String, String) -> String)
-> [(String, String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\(String
_,String
f,String
_) -> String
f) [(String, String, String)]
cpuInputTemplate
optimizeAllTemplate :: CpuArguments -> CpuArguments
optimizeAllTemplate :: CpuArguments -> CpuArguments
optimizeAllTemplate args :: CpuArguments
args@CpuArguments {[String]
[(String, [(String, String, String)])]
[(String, String, String)]
[Field]
CpuDataRef
MonitorConfig
CpuOpts
cpuFields :: [Field]
cpuAllTemplate :: [(String, [(String, String, String)])]
cpuInputTemplate :: [(String, String, String)]
cpuOpts :: CpuOpts
cpuArgs :: [String]
cpuParams :: MonitorConfig
cpuDataRef :: CpuDataRef
cpuFields :: CpuArguments -> [Field]
cpuAllTemplate :: CpuArguments -> [(String, [(String, String, String)])]
cpuInputTemplate :: CpuArguments -> [(String, String, String)]
cpuOpts :: CpuArguments -> CpuOpts
cpuArgs :: CpuArguments -> [String]
cpuParams :: CpuArguments -> MonitorConfig
cpuDataRef :: CpuArguments -> CpuDataRef
..} =
let inputFields :: [String]
inputFields = CpuArguments -> [String]
getInputFields CpuArguments
args
allTemplates :: [(String, [(String, String, String)])]
allTemplates =
((String, [(String, String, String)]) -> Bool)
-> [(String, [(String, String, String)])]
-> [(String, [(String, String, String)])]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(String
field, [(String, String, String)]
_) -> String
field String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
inputFields) [(String, [(String, String, String)])]
cpuAllTemplate
in CpuArguments
args {cpuAllTemplate :: [(String, [(String, String, String)])]
cpuAllTemplate = [(String, [(String, String, String)])]
allTemplates}
data CpuArguments =
CpuArguments
{ CpuArguments -> CpuDataRef
cpuDataRef :: !CpuDataRef
, CpuArguments -> MonitorConfig
cpuParams :: !MonitorConfig
, CpuArguments -> [String]
cpuArgs :: ![String]
, CpuArguments -> CpuOpts
cpuOpts :: !CpuOpts
, CpuArguments -> [(String, String, String)]
cpuInputTemplate :: ![(String, String, String)]
, CpuArguments -> [(String, [(String, String, String)])]
cpuAllTemplate :: ![(String, [(String, String, String)])]
, CpuArguments -> [Field]
cpuFields :: ![Field]
}
getArguments :: [String] -> IO CpuArguments
getArguments :: [String] -> IO CpuArguments
getArguments [String]
cpuArgs = do
[Int]
initCpuData <- IO [Int]
cpuData
CpuDataRef
cpuDataRef <- [Int] -> IO CpuDataRef
forall a. a -> IO (IORef a)
newIORef [Int]
initCpuData
IO CpuData -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CpuData -> IO ()) -> IO CpuData -> IO ()
forall a b. (a -> b) -> a -> b
$ CpuDataRef -> IO CpuData
parseCpu CpuDataRef
cpuDataRef
MonitorConfig
cpuParams <- [String] -> IO MConfig -> IO MonitorConfig
computeMonitorConfig [String]
cpuArgs IO MConfig
cpuConfig
[(String, String, String)]
cpuInputTemplate <- MonitorConfig -> IO [(String, String, String)]
runTemplateParser MonitorConfig
cpuParams
[(String, [(String, String, String)])]
cpuAllTemplate <- [String] -> IO [(String, [(String, String, String)])]
runExportParser (MonitorConfig -> [String]
pExport MonitorConfig
cpuParams)
[String]
nonOptions <-
case ArgOrder Opts
-> [OptDescr Opts] -> [String] -> ([Opts], [String], [String])
forall a.
ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
getOpt ArgOrder Opts
forall a. ArgOrder a
Permute [OptDescr Opts]
pluginOptions [String]
cpuArgs of
([Opts]
_, [String]
n, []) -> [String] -> IO [String]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [String]
n
([Opts]
_, [String]
_, [String]
errs) -> String -> IO [String]
forall a. HasCallStack => String -> a
error (String -> IO [String]) -> String -> IO [String]
forall a b. (a -> b) -> a -> b
$ String
"getArguments: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [String] -> String
forall a. Show a => a -> String
show [String]
errs
CpuOpts
cpuOpts <-
case ArgOrder (CpuOpts -> CpuOpts)
-> [OptDescr (CpuOpts -> CpuOpts)]
-> [String]
-> ([CpuOpts -> CpuOpts], [String], [String])
forall a.
ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
getOpt ArgOrder (CpuOpts -> CpuOpts)
forall a. ArgOrder a
Permute [OptDescr (CpuOpts -> CpuOpts)]
options [String]
nonOptions of
([CpuOpts -> CpuOpts]
o, [String]
_, []) -> CpuOpts -> IO CpuOpts
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CpuOpts -> IO CpuOpts) -> CpuOpts -> IO CpuOpts
forall a b. (a -> b) -> a -> b
$ ((CpuOpts -> CpuOpts) -> CpuOpts -> CpuOpts)
-> CpuOpts -> [CpuOpts -> CpuOpts] -> CpuOpts
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (CpuOpts -> CpuOpts) -> CpuOpts -> CpuOpts
forall a. a -> a
id CpuOpts
defaultOpts [CpuOpts -> CpuOpts]
o
([CpuOpts -> CpuOpts]
_, [String]
_, [String]
errs) -> String -> IO CpuOpts
forall a. HasCallStack => String -> a
error (String -> IO CpuOpts) -> String -> IO CpuOpts
forall a b. (a -> b) -> a -> b
$ String
"getArguments options: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [String] -> String
forall a. Show a => a -> String
show [String]
errs
let cpuFields :: [Field]
cpuFields =
[String] -> [String] -> [Field]
computeFields
(((String, [(String, String, String)]) -> String)
-> [(String, [(String, String, String)])] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, [(String, String, String)]) -> String
forall a b. (a, b) -> a
fst [(String, [(String, String, String)])]
cpuAllTemplate)
(((String, String, String) -> String)
-> [(String, String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\(String
_, String
f, String
_) -> String
f) [(String, String, String)]
cpuInputTemplate)
CpuArguments -> IO CpuArguments
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CpuArguments -> IO CpuArguments)
-> CpuArguments -> IO CpuArguments
forall a b. (a -> b) -> a -> b
$ CpuArguments -> CpuArguments
optimizeAllTemplate CpuArguments :: CpuDataRef
-> MonitorConfig
-> [String]
-> CpuOpts
-> [(String, String, String)]
-> [(String, [(String, String, String)])]
-> [Field]
-> CpuArguments
CpuArguments {[String]
[(String, [(String, String, String)])]
[(String, String, String)]
[Field]
CpuDataRef
MonitorConfig
CpuOpts
cpuFields :: [Field]
cpuOpts :: CpuOpts
cpuAllTemplate :: [(String, [(String, String, String)])]
cpuInputTemplate :: [(String, String, String)]
cpuParams :: MonitorConfig
cpuDataRef :: CpuDataRef
cpuArgs :: [String]
cpuFields :: [Field]
cpuAllTemplate :: [(String, [(String, String, String)])]
cpuInputTemplate :: [(String, String, String)]
cpuOpts :: CpuOpts
cpuArgs :: [String]
cpuParams :: MonitorConfig
cpuDataRef :: CpuDataRef
..}
runCpu :: CpuArguments -> IO String
runCpu :: CpuArguments -> IO String
runCpu args :: CpuArguments
args@CpuArguments {[String]
[(String, [(String, String, String)])]
[(String, String, String)]
[Field]
CpuDataRef
MonitorConfig
CpuOpts
cpuFields :: [Field]
cpuAllTemplate :: [(String, [(String, String, String)])]
cpuInputTemplate :: [(String, String, String)]
cpuOpts :: CpuOpts
cpuArgs :: [String]
cpuParams :: MonitorConfig
cpuDataRef :: CpuDataRef
cpuFields :: CpuArguments -> [Field]
cpuAllTemplate :: CpuArguments -> [(String, [(String, String, String)])]
cpuInputTemplate :: CpuArguments -> [(String, String, String)]
cpuOpts :: CpuArguments -> CpuOpts
cpuArgs :: CpuArguments -> [String]
cpuParams :: CpuArguments -> MonitorConfig
cpuDataRef :: CpuArguments -> CpuDataRef
..} = do
CpuData
cpuValue <- CpuDataRef -> IO CpuData
parseCpu CpuDataRef
cpuDataRef
[String]
temMonitorValues <- CpuArguments -> CpuData -> IO [String]
formatCpu CpuArguments
args CpuData
cpuValue
let templateInput :: TemplateInput
templateInput =
TemplateInput :: [String]
-> [(String, String, String)]
-> [(String, [(String, String, String)])]
-> TemplateInput
TemplateInput
{ temInputTemplate :: [(String, String, String)]
temInputTemplate = [(String, String, String)]
cpuInputTemplate
, temAllTemplate :: [(String, [(String, String, String)])]
temAllTemplate = [(String, [(String, String, String)])]
cpuAllTemplate
, [String]
temMonitorValues :: [String]
temMonitorValues :: [String]
..
}
MonitorConfig -> TemplateInput -> IO String
pureParseTemplate MonitorConfig
cpuParams TemplateInput
templateInput
startCpu :: [String] -> Int -> (String -> IO ()) -> IO ()
startCpu :: [String] -> Int -> (String -> IO ()) -> IO ()
startCpu [String]
args Int
refreshRate String -> IO ()
cb = do
CpuArguments
cpuArgs <- [String] -> IO CpuArguments
getArguments [String]
args
Int -> IO () -> IO ()
doEveryTenthSeconds Int
refreshRate (CpuArguments -> IO String
runCpu CpuArguments
cpuArgs IO String -> (String -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO ()
cb)