{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module System.Metrics.Prometheus.Ridley.Metrics.CPU.Unix
( getLoadAvg
, processCPULoad
) where
import Control.Applicative ((<|>))
import Data.Maybe (fromJust)
import qualified Data.Text as T
import Data.Traversable
import qualified Data.Vector as V
import Shelly
import qualified System.Metrics.Prometheus.Metric.Gauge as P
import System.Metrics.Prometheus.Ridley.Types
import Text.Read (readMaybe)
getLoadAvg :: IO (V.Vector Double)
getLoadAvg = do
rawOutput <- shelly $ silently $ T.strip <$> run "cat" ["/proc/loadavg"]
let standardFormat = case traverse (readMaybe . T.unpack) (take 3 . T.lines $ rawOutput) of
Just [a,b,c] -> Just [a,b,c]
_ -> Nothing
let alternativeFormat = case traverse (readMaybe . T.unpack) (take 3 . T.splitOn " " $ rawOutput) of
Just [a,b,c] -> Just [a,b,c]
_ -> Nothing
return . V.fromList . fromJust $ standardFormat <|> alternativeFormat <|> Just noAvgInfo
where
noAvgInfo = [-1.0, -1.0, -1.0]
updateCPULoad :: (P.Gauge, P.Gauge, P.Gauge) -> Bool -> IO ()
updateCPULoad (cpu1m, cpu5m, cpu15m) _ = do
loadVec <- getLoadAvg
P.set (loadVec `V.unsafeIndex` 0) cpu1m
P.set (loadVec `V.unsafeIndex` 1) cpu5m
P.set (loadVec `V.unsafeIndex` 2) cpu15m
processCPULoad :: (P.Gauge, P.Gauge, P.Gauge) -> RidleyMetricHandler
processCPULoad g = RidleyMetricHandler {
metric = g
, updateMetric = updateCPULoad
, flush = False
}