Logging TH functions and a minor bugfix
This commit is contained in:
parent
410aec472f
commit
1948a9a429
@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
module Yesod.Core
|
module Yesod.Core
|
||||||
( -- * Type classes
|
( -- * Type classes
|
||||||
Yesod (..)
|
Yesod (..)
|
||||||
@ -16,6 +17,11 @@ module Yesod.Core
|
|||||||
-- * Logging
|
-- * Logging
|
||||||
, LogLevel (..)
|
, LogLevel (..)
|
||||||
, formatLogMessage
|
, formatLogMessage
|
||||||
|
, logDebug
|
||||||
|
, logInfo
|
||||||
|
, logWarn
|
||||||
|
, logError
|
||||||
|
, logOther
|
||||||
-- * Misc
|
-- * Misc
|
||||||
, yesodVersion
|
, yesodVersion
|
||||||
, yesodRender
|
, yesodRender
|
||||||
@ -33,3 +39,35 @@ import Yesod.Dispatch
|
|||||||
import Yesod.Handler
|
import Yesod.Handler
|
||||||
import Yesod.Request
|
import Yesod.Request
|
||||||
import Yesod.Widget
|
import Yesod.Widget
|
||||||
|
|
||||||
|
import Language.Haskell.TH.Syntax
|
||||||
|
import Data.Text (Text)
|
||||||
|
|
||||||
|
logTH :: LogLevel -> Q Exp
|
||||||
|
logTH level =
|
||||||
|
[|messageLoggerHandler $(qLocation >>= liftLoc) $(lift level)|]
|
||||||
|
where
|
||||||
|
liftLoc :: Loc -> Q Exp
|
||||||
|
liftLoc (Loc a b c d e) = [|Loc $(lift a) $(lift b) $(lift c) $(lift d) $(lift e)|]
|
||||||
|
|
||||||
|
-- | Generates a function that takes a 'Text' and logs a 'LevelDebug' message. Usage:
|
||||||
|
--
|
||||||
|
-- > $(logDebug) "This is a debug log message"
|
||||||
|
logDebug :: Q Exp
|
||||||
|
logDebug = logTH LevelDebug
|
||||||
|
|
||||||
|
-- | See 'logDebug'
|
||||||
|
logInfo :: Q Exp
|
||||||
|
logInfo = logTH LevelInfo
|
||||||
|
-- | See 'logDebug'
|
||||||
|
logWarn :: Q Exp
|
||||||
|
logWarn = logTH LevelWarn
|
||||||
|
-- | See 'logDebug'
|
||||||
|
logError :: Q Exp
|
||||||
|
logError = logTH LevelError
|
||||||
|
|
||||||
|
-- | Generates a function that takes a 'Text' and logs a 'LevelOther' message. Usage:
|
||||||
|
--
|
||||||
|
-- > $(logOther "My new level") "This is a log message"
|
||||||
|
logOther :: Text -> Q Exp
|
||||||
|
logOther = logTH . LevelOther
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE CPP #-}
|
{-# LANGUAGE CPP #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
-- | The basic typeclass for a Yesod application.
|
-- | The basic typeclass for a Yesod application.
|
||||||
module Yesod.Internal.Core
|
module Yesod.Internal.Core
|
||||||
( -- * Type classes
|
( -- * Type classes
|
||||||
@ -22,6 +23,7 @@ module Yesod.Internal.Core
|
|||||||
-- * Logging
|
-- * Logging
|
||||||
, LogLevel (..)
|
, LogLevel (..)
|
||||||
, formatLogMessage
|
, formatLogMessage
|
||||||
|
, messageLoggerHandler
|
||||||
-- * Misc
|
-- * Misc
|
||||||
, yesodVersion
|
, yesodVersion
|
||||||
, yesodRender
|
, yesodRender
|
||||||
@ -53,7 +55,7 @@ import qualified Text.Blaze.Html5 as TBH
|
|||||||
import Data.Text.Lazy.Builder (toLazyText)
|
import Data.Text.Lazy.Builder (toLazyText)
|
||||||
import Data.Text.Lazy.Encoding (encodeUtf8)
|
import Data.Text.Lazy.Encoding (encodeUtf8)
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Control.Monad.IO.Class (liftIO)
|
import Control.Monad.IO.Class (MonadIO (liftIO))
|
||||||
import Web.Cookie (parseCookies)
|
import Web.Cookie (parseCookies)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Time
|
import Data.Time
|
||||||
@ -70,6 +72,7 @@ import qualified Data.Text.Lazy as TL
|
|||||||
import qualified Data.Text.Lazy.IO
|
import qualified Data.Text.Lazy.IO
|
||||||
import qualified System.IO
|
import qualified System.IO
|
||||||
import qualified Data.Text.Lazy.Builder as TB
|
import qualified Data.Text.Lazy.Builder as TB
|
||||||
|
import Language.Haskell.TH.Syntax (Loc (..), Lift (..))
|
||||||
|
|
||||||
#if GHC7
|
#if GHC7
|
||||||
#define HAMLET hamlet
|
#define HAMLET hamlet
|
||||||
@ -245,29 +248,44 @@ class RenderRoute (Route a) => Yesod a where
|
|||||||
|
|
||||||
-- | Send a message to the log. By default, prints to stderr.
|
-- | Send a message to the log. By default, prints to stderr.
|
||||||
messageLogger :: a
|
messageLogger :: a
|
||||||
|
-> Loc -- ^ position in source code
|
||||||
-> LogLevel
|
-> LogLevel
|
||||||
-> Text -- ^ source
|
|
||||||
-> Text -- ^ message
|
-> Text -- ^ message
|
||||||
-> IO ()
|
-> IO ()
|
||||||
messageLogger _ level src msg =
|
messageLogger _ loc level msg =
|
||||||
formatLogMessage level src msg >>=
|
formatLogMessage loc level msg >>=
|
||||||
Data.Text.Lazy.IO.hPutStrLn System.IO.stderr
|
Data.Text.Lazy.IO.hPutStrLn System.IO.stderr
|
||||||
|
|
||||||
|
messageLoggerHandler :: (Yesod m, MonadIO mo)
|
||||||
|
=> Loc -> LogLevel -> Text -> GGHandler s m mo ()
|
||||||
|
messageLoggerHandler loc level msg = do
|
||||||
|
y <- getYesod
|
||||||
|
liftIO $ messageLogger y loc level msg
|
||||||
|
|
||||||
data LogLevel = LevelDebug | LevelInfo | LevelWarn | LevelError | LevelOther Text
|
data LogLevel = LevelDebug | LevelInfo | LevelWarn | LevelError | LevelOther Text
|
||||||
deriving (Eq, Show, Read, Ord)
|
deriving (Eq, Show, Read, Ord)
|
||||||
|
|
||||||
formatLogMessage :: LogLevel
|
instance Lift LogLevel where
|
||||||
-> Text -- ^ source
|
lift LevelDebug = [|LevelDebug|]
|
||||||
|
lift LevelInfo = [|LevelInfo|]
|
||||||
|
lift LevelWarn = [|LevelWarn|]
|
||||||
|
lift LevelError = [|LevelError|]
|
||||||
|
lift (LevelOther x) = [|LevelOther $ TS.pack $(lift $ TS.unpack x)|]
|
||||||
|
|
||||||
|
formatLogMessage :: Loc
|
||||||
|
-> LogLevel
|
||||||
-> Text -- ^ message
|
-> Text -- ^ message
|
||||||
-> IO TL.Text
|
-> IO TL.Text
|
||||||
formatLogMessage level src msg = do
|
formatLogMessage loc level msg = do
|
||||||
now <- getCurrentTime
|
now <- getCurrentTime
|
||||||
return $ TB.toLazyText $
|
return $ TB.toLazyText $
|
||||||
TB.fromText (TS.pack $ show now)
|
TB.fromText (TS.pack $ show now)
|
||||||
`mappend` TB.fromText ": "
|
`mappend` TB.fromText ": "
|
||||||
`mappend` TB.fromText (TS.pack $ show level)
|
`mappend` TB.fromText (TS.pack $ show level)
|
||||||
`mappend` TB.fromText "@("
|
`mappend` TB.fromText "@("
|
||||||
`mappend` TB.fromText src
|
`mappend` TB.fromText (TS.pack $ loc_filename loc)
|
||||||
|
`mappend` TB.fromText ":"
|
||||||
|
`mappend` TB.fromText (TS.pack $ show $ fst $ loc_start loc)
|
||||||
`mappend` TB.fromText ") "
|
`mappend` TB.fromText ") "
|
||||||
`mappend` TB.fromText msg
|
`mappend` TB.fromText msg
|
||||||
|
|
||||||
|
|||||||
@ -279,11 +279,11 @@ mkSubsiteExp segments (SinglePiece _:pieces) frontVars x = do
|
|||||||
fsp <- [|fromSinglePiece|]
|
fsp <- [|fromSinglePiece|]
|
||||||
let exp' = CaseE (fsp `AppE` VarE next)
|
let exp' = CaseE (fsp `AppE` VarE next)
|
||||||
[ Match
|
[ Match
|
||||||
(ConP (mkName "Left") [WildP])
|
(ConP (mkName "Nothing") [])
|
||||||
(NormalB nothing)
|
(NormalB nothing)
|
||||||
[]
|
[]
|
||||||
, Match
|
, Match
|
||||||
(ConP (mkName "Right") [VarP next'])
|
(ConP (mkName "Just") [VarP next'])
|
||||||
(NormalB innerExp)
|
(NormalB innerExp)
|
||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, OverloadedStrings #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
|
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Yesod.Dispatch
|
import Network.Wai.Handler.Warp (run)
|
||||||
import Yesod.Content
|
import Data.Text (unpack)
|
||||||
import Yesod.Handler
|
|
||||||
import Network.Wai.Handler.Warp (runEx)
|
|
||||||
|
|
||||||
data Subsite = Subsite String
|
data Subsite = Subsite String
|
||||||
|
|
||||||
@ -14,16 +13,18 @@ mkYesodSub "Subsite" [] [$parseRoutes|
|
|||||||
/multi/*Strings SubMultiR
|
/multi/*Strings SubMultiR
|
||||||
|]
|
|]
|
||||||
|
|
||||||
getSubRootR :: GHandler Subsite m RepPlain
|
getSubRootR :: Yesod m => GHandler Subsite m RepPlain
|
||||||
getSubRootR = do
|
getSubRootR = do
|
||||||
Subsite s <- getYesodSub
|
Subsite s <- getYesodSub
|
||||||
tm <- getRouteToMaster
|
tm <- getRouteToMaster
|
||||||
render <- getUrlRender
|
render <- getUrlRender
|
||||||
return $ RepPlain $ toContent $ "Hello Sub World: " ++ s ++ ". " ++ render (tm SubRootR)
|
$(logDebug) "I'm in SubRootR"
|
||||||
|
return $ RepPlain $ toContent $ "Hello Sub World: " ++ s ++ ". " ++ unpack (render (tm SubRootR))
|
||||||
|
|
||||||
handleSubMultiR :: Strings -> GHandler Subsite m RepPlain
|
handleSubMultiR :: Yesod m => Strings -> GHandler Subsite m RepPlain
|
||||||
handleSubMultiR x = do
|
handleSubMultiR x = do
|
||||||
Subsite y <- getYesodSub
|
Subsite y <- getYesodSub
|
||||||
|
$(logInfo) "In SubMultiR"
|
||||||
return . RepPlain . toContent . show $ (x, y)
|
return . RepPlain . toContent . show $ (x, y)
|
||||||
|
|
||||||
data HelloWorld = HelloWorld { getSubsite :: String -> Subsite }
|
data HelloWorld = HelloWorld { getSubsite :: String -> Subsite }
|
||||||
@ -33,5 +34,7 @@ mkYesod "HelloWorld" [$parseRoutes|
|
|||||||
|]
|
|]
|
||||||
instance Yesod HelloWorld where approot _ = ""
|
instance Yesod HelloWorld where approot _ = ""
|
||||||
-- getRootR :: GHandler HelloWorld HelloWorld RepPlain -- FIXME remove type sig
|
-- getRootR :: GHandler HelloWorld HelloWorld RepPlain -- FIXME remove type sig
|
||||||
getRootR = return $ RepPlain "Hello World"
|
getRootR = do
|
||||||
main = toWaiApp (HelloWorld Subsite) >>= runEx print 3000
|
$(logOther "HAHAHA") "Here I am"
|
||||||
|
return $ RepPlain "Hello World"
|
||||||
|
main = toWaiApp (HelloWorld Subsite) >>= run 3000
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user