hslogger-reader-1.0.0: 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 #-}
module 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 arguments of
Nothing ->
return Nothing
Just pattern' -> do
let
regexOptions
= if insensitive arguments
then
[CaseInsensitive]
else
[]
either (throwIO . RegexError) (return . return) $ regex' regexOptions pattern'
messageParser <- either (throwIO . ParserError) return $ logMessageParser (format arguments) loggerNameParser
lts <- fmap L.lines . L.readFile . logFile $ arguments
forM lts $ \lt -> do
lm <- either (const $ throwIO (MessageParseError lt)) return . eitherResult . parse messageParser $ lt
let
pred
= filterLogMessage
(lowerPrio arguments)
(upperPrio arguments)
(lowerTime arguments)
(upperTime arguments)
(pid arguments)
(tid arguments)
regex''
when (pred 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