himari-1.1.6.1: example/anomaly-monitor/Anomaly.hs
module Anomaly
( AnomalySeverity (..)
, AnomalyReport (..)
, determineSeverity
, formatReport
) where
import Data.Text qualified as T
import Himari
-- | Severity level of detected anomaly.
data AnomalySeverity
= Normal
| Warning
| Critical
| Catastrophic
deriving (Bounded, Enum, Eq, Generic, Ord, Read, Show)
-- | Anomaly detection result.
data AnomalyReport = AnomalyReport
{ cpuUsage :: Double
, threshold :: Double
, severity :: AnomalySeverity
, timestamp :: UTCTime
}
deriving (Eq, Generic, Ord, Read, Show)
-- | Determine severity based on how much the threshold is exceeded.
-- returns `Normal` when not exceeded
determineSeverity :: Double -> Double -> AnomalySeverity
determineSeverity threshold' usage
| usage < threshold' = Normal
| usage < threshold' + 5 = Warning
| usage < threshold' + 15 = Critical
| otherwise = Catastrophic
-- | Format anomaly report for logging.
formatReport :: AnomalyReport -> Text
formatReport report =
mconcat
[ "[ANOMALY DETECTED] "
, "Severity: "
, T.pack $ show report.severity
, " | CPU: "
, T.pack $ showFFloat (Just 1) report.cpuUsage "%"
, " (threshold: "
, T.pack $ showFFloat (Just 1) report.threshold "%"
, ") | Time: "
, T.pack $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S UTC" report.timestamp
]