summaryrefslogtreecommitdiffhomepage
path: root/Plugins/Monitors/MultiCpu.hs
blob: f1b7b20390637c336a133dc089d4c14e00e66ec7 (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
-----------------------------------------------------------------------------
-- |
-- 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 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"]]


multiCpuData :: IO [[Float]]
multiCpuData = do s <- B.readFile "/proc/stat"
                  return $ multiCpuParser s

multiCpuParser :: B.ByteString -> [[Float]]
multiCpuParser = map (map read . tail) . lns
  where lns = takeWhile isCpu . map unpW . B.lines
        isCpu (w:_) = "cpu" `isPrefixOf` w
        isCpu _ = False
        unpW = map B.unpack . B.words

parseMultiCpu :: IO [[Float]]
parseMultiCpu =
  do (as, bs) <- doActionTwiceWithDelay 350000 multiCpuData
     let p0 = zipWith percent bs as
     (as', bs') <- doActionTwiceWithDelay 350000 multiCpuData
     let p1 = zipWith percent bs' as'
     return $ zipWith (\x y -> zipWith (\a b -> (a + b) / 2.0) x y)  p1 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

formatMultiCpus :: [[Float]] -> Monitor [String]
formatMultiCpus [] = return $ take 15 (repeat "0%")
formatMultiCpus xs = fmap concat $ mapM formatMultiCpu xs

formatMultiCpu :: [Float] -> Monitor [String]
formatMultiCpu x
  | length x < 4 = return $ take 5 (repeat "")
  | otherwise  = mapM (showWithColors f) . map (* 100) $ (t:x)
            where f s = floatToPercent (s / 100)
                  t = foldr (+) 0 $ take 3 x

runMultiCpu :: [String] -> Monitor String
runMultiCpu _ =
  do c <- io $ parseMultiCpu
     l <- formatMultiCpus c
     parseTemplate l