1-- | Produce pretty, thread-safe logs
3{-# LANGUAGE BangPatterns #-}
4module Hakyll.Core.Logger
14import Control.Monad (forever)
15import Control.Monad.Trans (MonadIO, liftIO)
16import Control.Applicative (pure, (<$>), (<*>))
17import Control.Concurrent (forkIO)
18import Control.Concurrent.Chan (Chan, newChan, readChan, writeChan)
19import Control.Concurrent.MVar (MVar, newEmptyMVar, takeMVar, putMVar)
20import Text.Printf (printf)
22import Data.Time (getCurrentTime, diffUTCTime)
24-- | Logger structure. Very complicated.
27 { loggerChan :: Chan (Maybe String) -- ^ Nothing marks the end
28 , loggerSync :: MVar () -- ^ Used for sync on quit
29 , loggerSink :: String -> IO () -- ^ Out sink
32-- | Create a new logger
34makeLogger :: (String -> IO ()) -> IO Logger
36 logger <- Logger <$> newChan <*> newEmptyMVar <*> pure sink
37 _ <- forkIO $ loggerThread logger
40 loggerThread logger = forever $ do
41 msg <- readChan $ loggerChan logger
44 Nothing -> putMVar (loggerSync logger) ()
46 Just m -> loggerSink logger m
48-- | Flush the logger (blocks until flushed)
50flushLogger :: Logger -> IO ()
51flushLogger logger = do
52 writeChan (loggerChan logger) Nothing
53 () <- takeMVar $ loggerSync logger
56-- | Send a raw message to the logger
58message :: Logger -> String -> IO ()
59message logger = writeChan (loggerChan logger) . Just
61-- | Start a section in the log
65 -> String -- ^ Section name
66 -> m () -- ^ No result
67section logger = liftIO . message logger
69-- | Execute a monadic action and log the duration
73 -> String -- ^ Message
75 -> m a -- ^ Timed and logged action
76timed logger msg action = do
77 start <- liftIO getCurrentTime
79 stop <- liftIO getCurrentTime
80 let diff = fromEnum $ diffUTCTime stop start
81 ms = diff `div` 10 ^ (9 :: Int)
82 formatted = printf " [%4dms] %s" ms msg
83 liftIO $ message logger formatted
86-- | Log something at the same level as 'timed', but without the timing
90 -> String -- ^ Message
91 -> m () -- ^ No result
92report logger msg = liftIO $ message logger $ " [ ] " ++ msg
94-- | Log an error that was thrown in the compilation phase
98 -> String -- ^ Message
99 -> m () -- ^ No result
100thrown logger msg = liftIO $ message logger $ " [ ERROR] " ++ msg
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list