systemstats (empty) → 0.1.0.0
raw patch · 4 files changed
+147/−0 lines, 4 filesdep +basedep +microloggerdep +optparse-applicativesetup-changed
Dependencies added: base, micrologger, optparse-applicative, statgrab, text, text-format, transformers
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- app/Main.hs +84/−0
- systemstats.cabal +31/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+module Main where++import Control.Concurrent (threadDelay)+import Control.Monad (forM, forM_, forever)+import qualified Data.Text.Lazy as T+import qualified Data.Text.Encoding as TEnc+import qualified Data.Text.Format as TF+import LuminescentDreams.Logger+import Options.Applicative+import System.Statgrab++data Config = Config { interval :: Int+ , watchCpu :: Bool+ , watchLoad :: Bool+ , watchMemory :: Bool+ , watchFilesystems :: [String]+ }+ deriving (Show)+++main :: IO ()+main = do+ cli@Config{..} <- execParser (info (helper <*> cliParser)+ (fullDesc <> progDesc "regularly stat the system"))+ print cli+ let logger = Logger (putStrLn . T.unpack) LogInfo+ let modules = mconcat [ if watchCpu then [cpuModule logger] else []+ , if watchLoad then [loadModule logger] else []+ , if watchMemory then [memoryModule logger] else []+ , [filesystemModule watchFilesystems logger]+ ]+ forever $ do+ forM modules $ \m -> m+ threadDelay (interval * 1000000)+++cliParser :: Parser Config+cliParser =+ Config <$> option auto (long "interval" <> help "number of seconds between stats" <> value 5)+ <*> switch (long "cpu" <> help "enable cpu monitoring")+ <*> switch (long "load" <> help "enable system load monitoring")+ <*> switch (long "mem" <> help "enable memory monitoring")+ <*> many (strOption (long "fs" <> help "enable filesystem monitoring"))+++cpuModule :: Logger -> IO ()+cpuModule logger =+ runStats snapshot >>= \CPU{..} -> logMsg logger LogInfo [("stats", "cpu")] (show cpuTotal)++loadModule :: Logger -> IO ()+loadModule logger =+ runStats snapshot >>= \Load{..} -> logMsg logger LogInfo [("stats", "load")] $ T.unpack $ TF.format "{}, {}, {}" (load1, load5, load15)++memoryModule :: Logger -> IO ()+memoryModule logger =+ runStats snapshot >>=+ \Memory{..} -> logMsg logger LogInfo [("stats", "memory")] $+ T.unpack $ TF.format "{}, {}, {}, {}" ( bytesToMb memUsed+ , bytesToMb memCache+ , bytesToMb memFree+ , bytesToMb memTotal+ )++filesystemModule :: [String] -> Logger -> IO ()+filesystemModule fsNames logger = do+ let fsNamesBs = map (TEnc.encodeUtf8 . T.toStrict . T.pack) fsNames+ sts <- filter (\FileSystem{..} -> fsMountPoint `elem` fsNamesBs) <$> runStats snapshots+ forM_ sts $ \FileSystem{..} ->+ logMsg logger LogInfo [("stats", "filesystem")] $+ T.unpack $ TF.format "{}: {}/{} [{}]" ( TEnc.decodeUtf8 fsMountPoint+ , bytesToGb fsUsed+ , bytesToGb fsSize+ , bytesToGb fsAvail+ )++bytesToMb :: Integer -> Float+bytesToMb s = fromIntegral s / 1024 / 1024++bytesToGb :: Integer -> Float+bytesToGb s = fromIntegral s / 1024 / 1024 / 1024
+ systemstats.cabal view
@@ -0,0 +1,31 @@+name: systemstats+version: 0.1.0.0+synopsis: An application that regularly logs system stats for later analysis+description: An application that regularly logs system stats for later analysis+homepage: https://github.com/githubuser/systemlog#readme+license: BSD3+license-file: LICENSE+author: Savanni D'Gerinel+maintainer: savanni@savannidgerinel.com+copyright: 2016 Savanni D'Gerinel+category: Web+build-type: Simple+cabal-version: >=1.10++executable systemstats+ hs-source-dirs: app+ main-is: Main.hs+ ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N+ default-language: Haskell2010++ build-depends: base >= 4.7 && < 5+ , micrologger >= 0.2 && < 0.3+ , optparse-applicative >= 0.12.1 && < 0.13+ , statgrab >= 0.1.3 && < 0.2+ , text >= 1.2 && < 1.3+ , text-format >= 0.3.1 && < 0.4+ , transformers >= 0.4.2 && < 0.5++source-repository head+ type: git+ location: https://github.com/savannidgerinel/systemlog