blob: 1c89a76c62f86357c452696d2aba111389cdd539 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
-----------------------------------------------------------------------------
-- |
-- Module : Plugins.Monitors.MultiCpu
-- Copyright : (c) Jose A Ortega Ruiz
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Jose A Ortega <jao@gnu.org>
-- Stability : unstable
-- Portability : unportable
--
-- A multi-cpu monitor for Xmobar
--
-----------------------------------------------------------------------------
module Plugins.Monitors.MultiCpu(multiCpuConfig, runMultiCpu) where
import Plugins.Monitors.Common
import qualified Data.ByteString.Lazy.Char8 as B
import Data.List(isPrefixOf)
multiCpuConfig :: IO MConfig
multiCpuConfig = mkMConfig
"Cpu: <total>"
[ k ++ n | n <- "" : map show [0 :: Int ..]
, k <- ["total","user","nice","system","idle"]]
cpuData :: IO [[Float]]
cpuData = do s <- B.readFile "/proc/stat"
return $ cpuParser s
cpuParser :: B.ByteString -> [[Float]]
cpuParser = map parseList . cpuLists
where cpuLists = takeWhile isCpu . map B.words . B.lines
isCpu (w:_) = "cpu" `isPrefixOf` B.unpack w
isCpu _ = False
parseList = map (read . B.unpack) . tail
parseCpuData :: IO [[Float]]
parseCpuData =
do (as, bs) <- doActionTwiceWithDelay 950000 cpuData
let p0 = zipWith percent bs as
return p0
percent :: [Float] -> [Float] -> [Float]
percent b a = if tot > 0 then map (/ tot) $ take 4 dif else [0, 0, 0, 0]
where dif = zipWith (-) b a
tot = foldr (+) 0 dif
emptyPercs :: [String]
emptyPercs = repeat " 0%"
formatMultiCpus :: [[Float]] -> Monitor [String]
formatMultiCpus [] = return $ take 15 emptyPercs
formatMultiCpus xs = fmap concat $ mapM formatCpu xs
formatCpu :: [Float] -> Monitor [String]
formatCpu x
| length x < 4 = return $ take 5 emptyPercs
| otherwise = mapM (showWithColors f . (* 100)) (t:x)
where f = pad . floatToPercent . (/ 100)
t = foldr (+) 0 $ take 3 x
pad s = take (4 - length s) " " ++ s
runMultiCpu :: [String] -> Monitor String
runMultiCpu _ =
do c <- io parseCpuData
l <- formatMultiCpus c
parseTemplate l
|