use fast-logger/wai-logger
This commit is contained in:
parent
c0ab2e6178
commit
8bc3873080
@ -1,68 +1,92 @@
|
|||||||
-- 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 #-}
|
{-# LANGUAGE BangPatterns #-}
|
||||||
module Yesod.Logger
|
module Yesod.Logger
|
||||||
( Logger
|
( Logger
|
||||||
, makeLogger
|
, makeLogger
|
||||||
|
, makeDefaultLogger
|
||||||
, flushLogger
|
, flushLogger
|
||||||
, timed
|
, timed
|
||||||
, logText
|
, logText
|
||||||
, logLazyText
|
, logLazyText
|
||||||
, logString
|
, logString
|
||||||
|
, logBS
|
||||||
|
, logMsg
|
||||||
|
, formatLogText
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad (forever)
|
import System.IO (Handle, stdout, hFlush)
|
||||||
import Control.Monad.IO.Class (MonadIO, liftIO)
|
import Data.ByteString (ByteString)
|
||||||
import Control.Applicative ((<$>), (<*>))
|
import Data.ByteString.Char8 (pack)
|
||||||
import Control.Concurrent (forkIO)
|
import Data.ByteString.Lazy (toChunks)
|
||||||
import Control.Concurrent.Chan.Strict (Chan, newChan, readChan, writeChan)
|
|
||||||
import Control.Concurrent.MVar.Strict (MVar, newEmptyMVar, takeMVar, putMVar)
|
|
||||||
import Text.Printf (printf)
|
|
||||||
import Data.Text
|
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import qualified Data.Text.Lazy.IO
|
import Data.Text (Text)
|
||||||
|
import Data.Text.Encoding (encodeUtf8)
|
||||||
|
import qualified Data.Text.Lazy.Encoding as TLE
|
||||||
|
import System.Log.FastLogger
|
||||||
|
import Network.Wai.Logger.Date (DateRef, dateInit, getDate)
|
||||||
|
|
||||||
|
-- for timed logging
|
||||||
import Data.Time (getCurrentTime, diffUTCTime)
|
import Data.Time (getCurrentTime, diffUTCTime)
|
||||||
|
import Control.Monad.IO.Class (MonadIO, liftIO)
|
||||||
|
import Text.Printf (printf)
|
||||||
|
import Data.Text (unpack)
|
||||||
|
|
||||||
data Logger = Logger
|
-- for formatter
|
||||||
{ loggerChan :: Chan (Maybe TL.Text) -- Nothing marks the end
|
import Language.Haskell.TH.Syntax (Loc)
|
||||||
, loggerSync :: MVar () -- Used for sync on quit
|
import Yesod.Core (LogLevel, fileLocationToString)
|
||||||
}
|
|
||||||
|
|
||||||
makeLogger :: IO Logger
|
data Logger = Logger {
|
||||||
makeLogger = do
|
loggerHandle :: Handle
|
||||||
logger <- Logger <$> newChan <*> newEmptyMVar
|
, loggerDateRef :: DateRef
|
||||||
_ <- forkIO $ loggerThread logger
|
}
|
||||||
return logger
|
|
||||||
where
|
makeLogger :: Handle -> IO Logger
|
||||||
loggerThread logger = forever $ do
|
makeLogger handle = dateInit >>= return . Logger handle
|
||||||
msg <- readChan $ loggerChan logger
|
|
||||||
case msg of
|
-- | uses stdout handle
|
||||||
-- Stop: sync
|
makeDefaultLogger :: IO Logger
|
||||||
Nothing -> putMVar (loggerSync logger) ()
|
makeDefaultLogger = makeLogger stdout
|
||||||
-- Print and continue
|
|
||||||
Just m -> Data.Text.Lazy.IO.putStrLn m
|
|
||||||
|
|
||||||
-- | Flush the logger (blocks until flushed)
|
|
||||||
--
|
|
||||||
flushLogger :: Logger -> IO ()
|
flushLogger :: Logger -> IO ()
|
||||||
flushLogger logger = do
|
flushLogger = hFlush . loggerHandle
|
||||||
writeChan (loggerChan logger) Nothing
|
|
||||||
() <- takeMVar $ loggerSync logger
|
logMsg :: Logger -> [LogStr] -> IO ()
|
||||||
return ()
|
logMsg = hPutLogStr . loggerHandle
|
||||||
|
|
||||||
-- | Send a raw message to the logger
|
|
||||||
-- Native format is lazy text
|
|
||||||
logLazyText :: Logger -> TL.Text -> IO ()
|
logLazyText :: Logger -> TL.Text -> IO ()
|
||||||
logLazyText logger = writeChan (loggerChan logger) . Just
|
logLazyText logger msg = logMsg logger $
|
||||||
|
map LB (toChunks $ TLE.encodeUtf8 msg) ++ [newLine]
|
||||||
|
|
||||||
logText :: Logger -> Text -> IO ()
|
logText :: Logger -> Text -> IO ()
|
||||||
logText logger = logLazyText logger . TL.fromStrict
|
logText logger = logBS logger . encodeUtf8
|
||||||
|
|
||||||
|
logBS :: Logger -> ByteString -> IO ()
|
||||||
|
logBS logger msg = logMsg logger [LB msg, newLine]
|
||||||
|
|
||||||
logString :: Logger -> String -> IO ()
|
logString :: Logger -> String -> IO ()
|
||||||
logString logger = logLazyText logger . TL.pack
|
logString logger msg = logMsg logger [LS msg, newLine]
|
||||||
|
|
||||||
|
formatLogText :: Logger -> Loc -> LogLevel -> Text -> IO [LogStr]
|
||||||
|
formatLogText logger loc level msg = formatLogMsg logger loc level (toLB msg)
|
||||||
|
|
||||||
|
toLB :: Text -> LogStr
|
||||||
|
toLB = LB . encodeUtf8
|
||||||
|
|
||||||
|
formatLogMsg :: Logger -> Loc -> LogLevel -> LogStr -> IO [LogStr]
|
||||||
|
formatLogMsg logger loc level msg = do
|
||||||
|
date <- liftIO $ getDate $ loggerDateRef logger
|
||||||
|
return
|
||||||
|
[ LB date
|
||||||
|
, LB $ pack" ["
|
||||||
|
, LS (drop 5 $ show level)
|
||||||
|
, LB $ pack "] "
|
||||||
|
, msg
|
||||||
|
, LB $ pack " @("
|
||||||
|
, LS (fileLocationToString loc)
|
||||||
|
, LB $ pack ") "
|
||||||
|
]
|
||||||
|
|
||||||
|
newLine :: LogStr
|
||||||
|
newLine = LB $ pack "\"\n"
|
||||||
|
|
||||||
-- | Execute a monadic action and log the duration
|
-- | Execute a monadic action and log the duration
|
||||||
--
|
--
|
||||||
|
|||||||
@ -76,10 +76,10 @@ library
|
|||||||
, directory >= 1 && < 1.2
|
, directory >= 1 && < 1.2
|
||||||
, data-object >= 0.3 && < 0.4
|
, data-object >= 0.3 && < 0.4
|
||||||
, data-object-yaml >= 0.3 && < 0.4
|
, data-object-yaml >= 0.3 && < 0.4
|
||||||
-- for logger. Probably logger should be a separate package
|
|
||||||
, strict-concurrency >= 0.2.4 && < 0.2.5
|
|
||||||
, vector >= 0.9 && < 0.10
|
, vector >= 0.9 && < 0.10
|
||||||
, aeson >= 0.3
|
, aeson >= 0.3
|
||||||
|
, fast-logger >= 0.0.1
|
||||||
|
, wai-logger >= 0.0.1
|
||||||
|
|
||||||
exposed-modules: Yesod.Content
|
exposed-modules: Yesod.Content
|
||||||
Yesod.Core
|
Yesod.Core
|
||||||
|
|||||||
@ -9,7 +9,7 @@ module Yesod.Default.Main
|
|||||||
|
|
||||||
import Yesod.Core hiding (AppConfig (..))
|
import Yesod.Core hiding (AppConfig (..))
|
||||||
import Yesod.Default.Config
|
import Yesod.Default.Config
|
||||||
import Yesod.Logger (Logger, makeLogger, logString, logLazyText, flushLogger)
|
import Yesod.Logger (Logger, makeDefaultLogger, logString, logLazyText, flushLogger)
|
||||||
import Network.Wai (Application)
|
import Network.Wai (Application)
|
||||||
import Network.Wai.Handler.Warp
|
import Network.Wai.Handler.Warp
|
||||||
(runSettings, defaultSettings, settingsPort, settingsHost)
|
(runSettings, defaultSettings, settingsPort, settingsHost)
|
||||||
@ -46,7 +46,7 @@ defaultMain :: (Show env, Read env)
|
|||||||
-> IO ()
|
-> IO ()
|
||||||
defaultMain load withSite = do
|
defaultMain load withSite = do
|
||||||
config <- load
|
config <- load
|
||||||
logger <- makeLogger
|
logger <- makeDefaultLogger
|
||||||
withSite config logger $ runSettings defaultSettings
|
withSite config logger $ runSettings defaultSettings
|
||||||
{ settingsHost = "0.0.0.0"
|
{ settingsHost = "0.0.0.0"
|
||||||
, settingsPort = appPort config
|
, settingsPort = appPort config
|
||||||
@ -109,7 +109,7 @@ defaultDevelAppWith :: (Show env, Read env)
|
|||||||
-> ((Int, Application) -> IO ()) -> IO ()
|
-> ((Int, Application) -> IO ()) -> IO ()
|
||||||
defaultDevelAppWith load withSite f = do
|
defaultDevelAppWith load withSite f = do
|
||||||
conf <- load
|
conf <- load
|
||||||
logger <- makeLogger
|
logger <- makeDefaultLogger
|
||||||
let p = appPort conf
|
let p = appPort conf
|
||||||
logString logger $ "Devel application launched, listening on port " ++ show p
|
logString logger $ "Devel application launched, listening on port " ++ show p
|
||||||
withSite conf logger $ \app -> f (p, debugHandle (logHandle logger) app)
|
withSite conf logger $ \app -> f (p, debugHandle (logHandle logger) app)
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import Yesod.Auth
|
|||||||
import Yesod.Auth.OpenId
|
import Yesod.Auth.OpenId
|
||||||
import Yesod.Default.Config
|
import Yesod.Default.Config
|
||||||
import Yesod.Default.Util (addStaticContentExternal)
|
import Yesod.Default.Util (addStaticContentExternal)
|
||||||
import Yesod.Logger (Logger, logLazyText)
|
import Yesod.Logger (Logger, writeLogMsg, formatLogText, logLazyText)
|
||||||
import qualified Settings
|
import qualified Settings
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Database.Persist.Base
|
import qualified Database.Persist.Base
|
||||||
@ -108,7 +108,7 @@ instance Yesod ~sitearg~ where
|
|||||||
authRoute _ = Just $ AuthR LoginR
|
authRoute _ = Just $ AuthR LoginR
|
||||||
|
|
||||||
messageLogger y loc level msg =
|
messageLogger y loc level msg =
|
||||||
formatLogMessage loc level msg >>= logLazyText (getLogger y)
|
formatLogText (getLogger y) loc level msg >>= writeLogMsg (getLogger y)
|
||||||
|
|
||||||
-- This function creates static content files in the static folder
|
-- This function creates static content files in the static folder
|
||||||
-- and names them based on a hash of their content. This allows
|
-- and names them based on a hash of their content. This allows
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import Yesod.Default.Config
|
|||||||
import Yesod.Default.Util (addStaticContentExternal)
|
import Yesod.Default.Util (addStaticContentExternal)
|
||||||
import Yesod.Static (Static, base64md5, StaticRoute(..))
|
import Yesod.Static (Static, base64md5, StaticRoute(..))
|
||||||
import Settings.StaticFiles
|
import Settings.StaticFiles
|
||||||
import Yesod.Logger (Logger, logLazyText)
|
import Yesod.Logger (Logger, writeLogMsg, formatLogText, logLazyText)
|
||||||
import qualified Settings
|
import qualified Settings
|
||||||
import Settings (widgetFile)
|
import Settings (widgetFile)
|
||||||
import Control.Monad.Trans.Class (lift)
|
import Control.Monad.Trans.Class (lift)
|
||||||
@ -89,7 +89,7 @@ instance Yesod ~sitearg~ where
|
|||||||
urlRenderOverride _ _ = Nothing
|
urlRenderOverride _ _ = Nothing
|
||||||
|
|
||||||
messageLogger y loc level msg =
|
messageLogger y loc level msg =
|
||||||
formatLogMessage loc level msg >>= logLazyText (getLogger y)
|
formatLogText (getLogger y) loc level msg >>= writeLogMsg (getLogger y)
|
||||||
|
|
||||||
-- This function creates static content files in the static folder
|
-- This function creates static content files in the static folder
|
||||||
-- and names them based on a hash of their content. This allows
|
-- and names them based on a hash of their content. This allows
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user