{-# LANGUAGE OverloadedStrings #-} module System.Nagios.Plugin.Ekg.Check ( checkEkg, checkEkg' ) where import Control.Applicative import Control.Lens import Control.Monad.IO.Class import Data.Aeson import Data.ByteString.Lazy (ByteString) import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.Text as T import Network.Wreq hiding (header) import qualified Network.Wreq as W import Options.Applicative import System.Nagios.Plugin import System.Nagios.Plugin.Ekg.Types data PluginOpts = PluginOpts { optsEndpoint :: String } pluginOptParser :: ParserInfo PluginOpts pluginOptParser = info (helper <*> opts) ( fullDesc <> progDesc "Nagios plugin exposing perfdata from EKG." <> header "check_ekg" ) where opts = PluginOpts <$> strOption ( long "ekg-endpoint" <> short 'e' <> metavar "EKG-ENDPOINT" <> value "http://localhost:8888" <> help "URL of the EKG endpoint." ) -- | Run the check against the EKG endpoint specified on the command -- line. Terminate according to the -- - -- 'OK' if we retrieve and successfully parse a result, otherwise -- 'CRITICAL'. checkEkg :: NagiosPlugin () checkEkg = do opts <- liftIO $ execParser pluginOptParser let reqOpts = W.header "Accept" .~ ["application/json"] $ defaults resp <- liftIO . getWith reqOpts $ optsEndpoint opts case resp ^. responseStatus . statusCode of 200 -> checkEkg' $ resp ^. responseBody code -> addResult Critical . T.pack $ "EKG endpoint failed with status " <> show code -- | Version of 'checkEkg' which takes a 'ByteString' rather than -- requesting it from an EKG endpoint. checkEkg' :: ByteString -> NagiosPlugin () checkEkg' bs = case (eitherDecode' bs :: Either String MetricTree) of Left err -> addResult Critical $ "failed to parse EKG output: " <> T.pack err Right meters -> do addPerfData meters addResult OK "perfdata only"