hslogger-reader-1.0.2: src-exe/filter-logs/Main.hs
-- | Filter hslogger-produced logs and print to standard
-- output. Requires logs to use default hslogger time format and for
-- logger names to not include whitespace.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE RecordWildCards #-}
module Main
( main
) where
import Arguments
import Options.Applicative (execParser)
import Prelude hiding (takeWhile)
import System.Log.Reader
import System.Log.Logger
import qualified Data.Text.Lazy as L
import qualified Data.Text.Lazy.IO as L
import Data.Attoparsec.Text.Lazy
import Data.Maybe
import Control.Applicative
import Data.Time
import Data.Text.ICU hiding (pattern)
import Control.Exception
import Control.Monad
import Data.Typeable
import Data.Monoid
main = do
Arguments {..} <- execParser opts
regex'' <- case pattern of
Nothing ->
return Nothing
Just pattern' -> do
let
regexOptions
= if insensitive
then
[CaseInsensitive]
else
[]
either (throwIO . RegexError) (return . return) $ regex' regexOptions pattern'
messageParser <- either (throwIO . ParserError) return $ logMessageParser format loggerNameParser
lts <- fmap L.lines . L.readFile $ logFile
forM lts $ \lt -> do
case maybeResult $ parse messageParser lt of
Nothing ->
when noContinue $
throwIO $ MessageParseError lt
Just lm ->
when (filterLogMessage lowerPrio upperPrio lowerTime upperTime pid tid regex'' lm) $
L.putStrLn lt
where
loggerNameParser
= takeTill isHorizontalSpace
filterLogMessage
:: Priority -- ^ Lower priority
-> Priority -- ^ Upper priority
-> Maybe UTCTime -- ^ Lower bound on date
-> Maybe UTCTime -- ^ Upper bound on date
-> Maybe Int -- ^ Process ID
-> Maybe Int -- ^ Thread ID
-> Maybe Regex
-> LogMessage
-> Bool
filterLogMessage lowerPrio upperPrio lTime uTime pid tid reg lm
= and . catMaybes $
[ (>= lowerPrio) <$> priority lm
, (<= upperPrio) <$> priority lm
, liftA2 (<=) lTime $ zonedTimeToUTC <$> timestamp lm
, liftA2 (>=) uTime $ zonedTimeToUTC <$> timestamp lm
, liftA2 (==) pid $ processId lm
, liftA2 (==) tid $ threadId lm
, do
reg' <- reg
name <- loggerName lm
return . fromMaybe False $ find reg' name >> return True
]
data Errors
= MessageParseError L.Text
| RegexError ParseError
| ParserError String
deriving (Typeable)
instance Show Errors where
show (MessageParseError lt)
= L.unpack $ "Format of following message does not match expected: " <> lt
show (RegexError err)
= "Failure parsing regular expression: " <> show err
show (ParserError str)
= "Failure parsing log format spec: " <> str
instance Exception Errors