{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, FlexibleInstances, ExistentialQuantification, TypeFamilies, GeneralizedNewtypeDeriving, StandaloneDeriving, MultiParamTypeClasses, UndecidableInstances, ScopedTypeVariables, FlexibleContexts #-}
module System.Log.Heavy.Util
(
logMessage,
checkLogLevel, checkLogLevel',
checkContextFilter, checkContextFilter', checkContextFilterM
) where
import Control.Monad (when)
import Control.Monad.Trans
import Data.List (isPrefixOf)
import System.Log.Heavy.Types
import System.Log.Heavy.Level
checkContextFilter' :: [LogContextFilter] -> LogSource -> Level -> Bool
checkContextFilter' filters source level =
let includeFilters = [fltr | LogContextFilter (Just fltr) _ <- filters]
excludeFilters = [fltr | LogContextFilter _ (Just fltr) <- filters]
includeOk = null includeFilters || or [checkLogLevel' fltr source level | fltr <- includeFilters]
excludeOk = or [checkLogLevel' fltr source level | fltr <- excludeFilters]
in includeOk && not excludeOk
checkContextFilter :: LogContext -> LogMessage -> Bool
checkContextFilter context msg =
checkContextFilter' (map lcfFilter context) (lmSource msg) (lmLevel msg)
checkContextFilterM :: HasLogContext m => LogMessage -> m Bool
checkContextFilterM msg = do
context <- getLogContext
return $ checkContextFilter context msg
checkLogLevel :: LogFilter -> LogMessage -> Bool
checkLogLevel fltr m =
checkLogLevel' fltr (lmSource m) (lmLevel m)
checkLogLevel' :: LogFilter -> LogSource -> Level -> Bool
checkLogLevel' fltr source level =
case lookup (bestMatch source (map fst fltr)) fltr of
Nothing -> False
Just min -> level <= min
where
bestMatch :: LogSource -> [LogSource] -> LogSource
bestMatch src list = go [] src list
go :: LogSource -> LogSource -> [LogSource] -> LogSource
go best src [] = best
go best src (x:xs)
| src == x = x
| (x `isPrefixOf` src) && (length x > length best) = go x src xs
| otherwise = go best src xs
logMessage :: forall m. (HasLogging m, MonadIO m) => LogMessage -> m ()
logMessage msg = do
ok <- checkContextFilterM msg
when ok $ do
context <- getLogContext
logger <- getLogger
liftIO $ logger $ msg {lmContext = context ++ lmContext msg}