borel-0.18.0: lib/Borel/Ceilometer.hs
{-# LANGUAGE TupleSections #-}
module Borel.Ceilometer
( ceilometer
, module Borel.Ceilometer.Instance
)
where
import Control.Applicative
import Control.Monad.Reader
import qualified Data.Bimap as BM
import qualified Data.List as L
import qualified Data.Map as M
import Data.Maybe
import Data.Monoid
import Pipes hiding (Proxy)
import System.Log.Logger
-- friends
import Ceilometer.Client
import Vaultaire.Types
import Borel.Ceilometer.Instance
import Borel.Types
--------------------------------------------------------------------------------
-- | Use Ceilometer to decode and aggregate a stream of raw data points.
--
ceilometer
:: (MonadIO m, Applicative m)
=> FlavorMap -- ^ Instance flavor mapping
-> GroupedMetric -- ^ Requested metrics, this determines how we present the fold result
-> Env -- ^ Ceilometer arguments
-> Producer SimplePoint m () -- ^ Raw points
-> m [Result]
ceilometer flavors metrics cenv@(Env _ sd _ _ _) raw = do
liftIO $ debugM "borel" ("using ceilometer to decode data with " <> show sd)
fromMaybe [] <$> fmap handleResult <$> decodeFold cenv raw
where handleResult :: FoldResult -> [Result]
handleResult x = case (x, metrics) of
(RSingle val, [m]) -> [(m,val)]
(RMapNum32 vals, [m]) -> [(m, M.foldlWithKey (\a k v -> a + (fromIntegral k * v)) 0 vals)]
(RMapNum64 vals, [m]) -> [(m, M.foldlWithKey (\a k v -> a + (fromIntegral k * v)) 0 vals)]
(RMapText vals, _) -> let ms = intersect metrics flavors
in map (\(metric, flavor) -> (metric,) $ fromMaybe 0 $ M.lookup flavor vals) ms
_ -> []
-- Intersect the flavor map and the list of metrics requested. Flatten the result.
intersect :: [Metric] -> FlavorMap -> [(Metric, Flavor)]
intersect ms = BM.fold (\k1 _ acc -> maybe acc ((:acc) . (,k1))
$ L.find (== mkInstance k1) ms) []