Merge commit '9d37249e1ad1f3c70545363db909a9c2a9408762'
This commit is contained in:
commit
299d3a4622
71
Yesod/Logger.hs
Normal file
71
Yesod/Logger.hs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
-- blantantly taken from hakyll
|
||||||
|
-- http://hackage.haskell.org/packages/archive/hakyll/3.1.1.0/doc/html/src/Hakyll-Core-Logger.html
|
||||||
|
--
|
||||||
|
-- | Produce pretty, thread-safe logs
|
||||||
|
--
|
||||||
|
{-# LANGUAGE BangPatterns #-}
|
||||||
|
module Yesod.Logger
|
||||||
|
( Logger
|
||||||
|
, makeLogger
|
||||||
|
, flushLogger
|
||||||
|
, timed
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad (forever)
|
||||||
|
import Control.Monad.Trans (MonadIO, liftIO)
|
||||||
|
import Control.Applicative ((<$>), (<*>))
|
||||||
|
import Control.Concurrent (forkIO)
|
||||||
|
import Control.Concurrent.Chan.Strict (Chan, newChan, readChan, writeChan)
|
||||||
|
import Control.Concurrent.MVar.Strict (MVar, newEmptyMVar, takeMVar, putMVar)
|
||||||
|
import Text.Printf (printf)
|
||||||
|
|
||||||
|
import Data.Time (getCurrentTime, diffUTCTime)
|
||||||
|
|
||||||
|
data Logger = Logger
|
||||||
|
{ loggerChan :: Chan (Maybe String) -- Nothing marks the end
|
||||||
|
, loggerSync :: MVar () -- Used for sync on quit
|
||||||
|
}
|
||||||
|
|
||||||
|
makeLogger :: IO Logger
|
||||||
|
makeLogger = do
|
||||||
|
logger <- Logger <$> newChan <*> newEmptyMVar
|
||||||
|
_ <- forkIO $ loggerThread logger
|
||||||
|
return logger
|
||||||
|
where
|
||||||
|
loggerThread logger = forever $ do
|
||||||
|
msg <- readChan $ loggerChan logger
|
||||||
|
case msg of
|
||||||
|
-- Stop: sync
|
||||||
|
Nothing -> putMVar (loggerSync logger) ()
|
||||||
|
-- Print and continue
|
||||||
|
Just m -> putStrLn m
|
||||||
|
|
||||||
|
-- | Flush the logger (blocks until flushed)
|
||||||
|
--
|
||||||
|
flushLogger :: Logger -> IO ()
|
||||||
|
flushLogger logger = do
|
||||||
|
writeChan (loggerChan logger) Nothing
|
||||||
|
() <- takeMVar $ loggerSync logger
|
||||||
|
return ()
|
||||||
|
|
||||||
|
-- | Send a raw message to the logger
|
||||||
|
--
|
||||||
|
message :: Logger -> String -> IO ()
|
||||||
|
message logger = writeChan (loggerChan logger) . Just
|
||||||
|
|
||||||
|
-- | Execute a monadic action and log the duration
|
||||||
|
--
|
||||||
|
timed :: MonadIO m
|
||||||
|
=> Logger -- ^ Logger
|
||||||
|
-> String -- ^ Message
|
||||||
|
-> m a -- ^ Action
|
||||||
|
-> m a -- ^ Timed and logged action
|
||||||
|
timed logger msg action = do
|
||||||
|
start <- liftIO getCurrentTime
|
||||||
|
!result <- action
|
||||||
|
stop <- liftIO getCurrentTime
|
||||||
|
let diff = fromEnum $ diffUTCTime stop start
|
||||||
|
ms = diff `div` 10 ^ (9 :: Int)
|
||||||
|
formatted = printf " [%4dms] %s" ms msg
|
||||||
|
liftIO $ message logger formatted
|
||||||
|
return result
|
||||||
Loading…
Reference in New Issue
Block a user