diff options
Diffstat (limited to 'Monitors')
| -rw-r--r-- | Monitors/Cpu.hs | 109 | ||||
| -rw-r--r-- | Monitors/Mem.hs | 99 | ||||
| -rw-r--r-- | Monitors/Net.hs | 142 | 
3 files changed, 350 insertions, 0 deletions
| diff --git a/Monitors/Cpu.hs b/Monitors/Cpu.hs new file mode 100644 index 0000000..b67f772 --- /dev/null +++ b/Monitors/Cpu.hs @@ -0,0 +1,109 @@ +----------------------------------------------------------------------------- +-- | +-- Module      :  Monitors.Cpu +-- Copyright   :  (c) Andrea Rossato +-- License     :  BSD-style (see LICENSE) +--  +-- Maintainer  :  Andrea Rossato <andrea.rossato@unibz.it> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- A cpu monitor for XMobar +-- +----------------------------------------------------------------------------- + +module Main where + +import Numeric +import Control.Concurrent +import Text.ParserCombinators.Parsec + + +data Config =  +    Config { intervall :: Int +           , cpuNormal :: Integer +           , cpuNormalColor :: String +           , cpuCritical :: Integer +           , cpuCriticalColor :: String +           } + +defaultConfig :: Config +defaultConfig =  +    Config { intervall = 500000 +           , cpuNormal = 2 +           , cpuNormalColor = "#00FF00"  +           , cpuCritical = 60 +           , cpuCriticalColor = "#FF0000"   +           } + +config :: Config +config = defaultConfig + +-- Utilities + +interSec :: IO () +interSec = threadDelay  (intervall config) + +takeDigits :: Int -> Float -> Float +takeDigits d n =  +    read $ showFFloat (Just d) n "" + +floatToPercent :: Float -> String +floatToPercent n =  +    showFFloat (Just 2) (n*100) "%"  + + +run :: Parser [a] -> IO String -> IO [a] +run p input +        = do a <- input +             case (parse p "" a) of +               Left _ -> return [] +               Right x  -> return x + +fileCPU :: IO String +fileCPU = readFile "/proc/stat" + + +getNumbers :: Parser Float +getNumbers = skipMany space >> many1 digit >>= \n -> return $ read n + +parserCPU :: Parser [Float] +parserCPU = string "cpu" >> count 4 getNumbers + +parseCPU :: IO [Float] +parseCPU =  +    do a <- run parserCPU fileCPU +       interSec +       b <- run parserCPU fileCPU +       let dif = zipWith (-) b a +           tot = foldr (+) 0 dif +           percent = map (/ tot) dif +       return percent + +formatCpu :: [Float] -> String  +formatCpu [] = "" +formatCpu (us:ni:sy:_) +    | x >= c = setColor z cpuCriticalColor +    | x >= n  = setColor z cpuNormalColor +    | otherwise = floatToPercent y +    where x = (us * 100) + (sy * 100) + (ni * 100) +          y = us + sy + ni +          z = floatToPercent y +          c = fromInteger (cpuCritical config) +          n = fromInteger (cpuNormal config) +formatCpu _ = "" + +setColor :: String -> (Config -> String) -> String +setColor str ty = +    "<fc=" ++ ty config ++ ">" ++ +    str ++ "</fc>" +     +cpu :: IO String +cpu =  +    do l <- parseCPU +       return $ "Cpu: " ++ formatCpu l + +main :: IO () +main = +    do c <- cpu +       putStrLn c diff --git a/Monitors/Mem.hs b/Monitors/Mem.hs new file mode 100644 index 0000000..d8bd601 --- /dev/null +++ b/Monitors/Mem.hs @@ -0,0 +1,99 @@ +----------------------------------------------------------------------------- +-- | +-- Module      :  Monitors.Mem +-- Copyright   :  (c) Andrea Rossato +-- License     :  BSD-style (see LICENSE) +--  +-- Maintainer  :  Andrea Rossato <andrea.rossato@unibz.it> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- A memory monitor for XMobar +-- +----------------------------------------------------------------------------- + +module Main where + +import Numeric + +data Config =  +    Config { memNormal :: Integer +           , memNormalColor :: String +           , memCritical :: Integer +           , memCriticalColor :: String +           , swapNormal :: Integer +           , swapNormalColor :: String +           , swapCritical :: Integer +           , swapCriticalColor :: String +           } + +defaultConfig :: Config +defaultConfig =  +    Config { memNormal = 80 +           , memNormalColor =  "#00FF00"  +           , memCritical = 90 +           , memCriticalColor =  "#FF0000" +           , swapNormal = 15 +           , swapNormalColor = "#00FF00"  +           , swapCritical = 50 +           , swapCriticalColor = "#FF0000"  +           } +config :: Config +config = defaultConfig + +-- Utilities + +takeDigits :: Int -> Float -> Float +takeDigits d n =  +    read $ showFFloat (Just d) n "" + +floatToPercent :: Float -> String +floatToPercent n =  +    showFFloat (Just 2) (n*100) "%"  + +fileMEM :: IO String +fileMEM = readFile "/proc/meminfo" + +parseMEM :: IO [Float] +parseMEM =  +    do file <- fileMEM  +       let content = map words $ take 13 $ lines file +           [total, free, buffer, cache,_,_,_,_,_,_,_,swapTotal,swapFree] = map (\line -> (read $ line !! 1 :: Float) / 1024) content +           rest = free + buffer + cache +           used = total - rest +           usedratio = used * 100 / total +           swapRatio = 100 - (swapFree / swapTotal * 100) +       return [total, free, buffer, cache, rest, used, usedratio, swapFree, swapRatio] + + +formatMem :: [Float] -> String  +formatMem [] = "" +formatMem (total:_:buffer:cach:_:used:_:_:swapRatio:_) = +    "Ram: " ++ ram ++ " cached: " ++ cache ++ " Swap: " ++ swap +        where (memN,memC,swapN,swapC) = (fromIntegral $ memNormal config,fromIntegral $ memCritical config +                                        , fromIntegral $ swapNormal config, fromIntegral $ swapCritical config) +              m = floatToPercent ((used + buffer + cach) / total) +              sw = show (takeDigits 2 swapRatio) ++ "%" +              cache = show (takeDigits 2 cach) ++ "Mb" +              ram | (used / total * 100) >= memC = setColor m memCriticalColor +                  | (used / total * 100) >= memN = setColor m memNormalColor +                  | otherwise = floatToPercent (used / total) +              swap | swapRatio >= swapC = setColor sw swapCriticalColor +                   | swapRatio >= swapN = setColor sw swapNormalColor +                   | otherwise = sw +formatMem _ = "" + +setColor :: String -> (Config -> String) -> String +setColor str ty = +    "<fc=" ++ ty config ++ ">" ++ +    str ++ "</fc>" +     +mem :: IO String +mem = +    do m <- parseMEM +       return $ formatMem m + +main :: IO () +main = +    do m <- mem +       putStrLn m
\ No newline at end of file diff --git a/Monitors/Net.hs b/Monitors/Net.hs new file mode 100644 index 0000000..7554c56 --- /dev/null +++ b/Monitors/Net.hs @@ -0,0 +1,142 @@ +----------------------------------------------------------------------------- +-- | +-- Module      :  Monitors.Cpu +-- Copyright   :  (c) Andrea Rossato +-- License     :  BSD-style (see LICENSE) +--  +-- Maintainer  :  Andrea Rossato <andrea.rossato@unibz.it> +-- Stability   :  unstable +-- Portability :  unportable +-- +-- A net device monitor for XMobar +-- +----------------------------------------------------------------------------- + +module Main where + +import Numeric +import Control.Concurrent +import Text.ParserCombinators.Parsec +import System.Environment + +data Config =  +    Config { intervall :: Int +           , netDevice :: String +           , netNormal :: Integer +           , netNormalColor :: String +           , netCritical :: Integer +           , netCriticalColor :: String +           } + +defaultConfig :: Config +defaultConfig =  +    Config { intervall = 500000 +           , netDevice = "eth1" +           , netNormal = 0 +           , netNormalColor = "#00FF00"  +           , netCritical = 50 +           , netCriticalColor = "#FF0000"  +           } + +config :: Config +config = defaultConfig + +-- Utilities + +interSec :: IO () +interSec = threadDelay  (intervall config) + +takeDigits :: Int -> Float -> Float +takeDigits d n =  +    read $ showFFloat (Just d) n "" + +floatToPercent :: Float -> String +floatToPercent n =  +    showFFloat (Just 2) (n*100) "%"  + + +run :: Parser [a] -> IO String -> IO [a] +run p input +        = do a <- input +             case (parse p "" a) of +               Left _ -> return [] +               Right x  -> return x + +fileNET :: IO String +fileNET =  +    do f <- readFile "/proc/net/dev" +       return $ unlines $ drop 2 $ lines f + +-- CPU + +getNumbers :: Parser Float +getNumbers = skipMany space >> many1 digit >>= \n -> return $ read n + +-- Net Devices + +data NetDev = NA +            | ND { netDev :: String +                 , netRx :: Float +                 , netTx :: Float +                 } deriving (Eq,Read) + +instance Show NetDev where +    show NA = "N/A" +    show (ND nd rx tx) = +        nd ++ ": " ++ (formatNet rx) ++ "|" ++ formatNet tx           + +formatNet :: Float -> String +formatNet d | d > fromInteger (netCritical config) = setColor str netCriticalColor  +            | d > fromInteger (netNormal config) = setColor str netNormalColor +            | otherwise = str +            where str = show d ++ "Kb" + +pNetDev :: Parser NetDev +pNetDev =  +    do { skipMany1 space +       ; dn <- manyTill alphaNum $ char ':' +       ; [rx] <- count 1 getNumbers +       ; _ <- count 7 getNumbers +       ; [tx] <- count 1 getNumbers +       ; _ <- count 7 getNumbers +       ; char '\n' +       ; return $ ND dn (rx / 1024) (tx / 1024) +       }  + +parserNet :: Parser [NetDev] +parserNet = manyTill pNetDev eof + +parseNET :: String -> IO [NetDev] +parseNET nd =  +    do a <- run parserNet fileNET +       interSec +       b <- run parserNet fileNET +       let netRate f da db = takeDigits 2 $ ((f db) - (f da)) * fromIntegral (1000000 `div` (intervall config)) +           diffRate (da,db) = ND (netDev da)  +                              (netRate netRx da db) +                              (netRate netTx da db) +       return $ filter (\d -> netDev d == nd) $ map diffRate $ zip a b + +-- Formattings + +setColor :: String -> (Config -> String) -> String +setColor str ty = +    "<fc=" ++ ty config ++ ">" ++ +    str ++ "</fc>" +     +net :: String -> IO String +net nd =  +    do pn <- parseNET nd +       n <- case pn of +              [x] -> return x +              _ -> return $ NA +       return $ show n + +main :: IO () +main = +    do args <- getArgs +       n <- +           if length args /= 1 +              then error "No device specified.\nUsage: net dev" +              else net (args!!0) +       putStrLn n | 
