summaryrefslogtreecommitdiffhomepage
path: root/Monitors/Net.hs
blob: 7554c56584699312502036ac2e850cf550a9f688 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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