NoLoggingT 不会禁用永久日志记录
NoLoggingT does not disable logging in Persistent
我做了这段代码,我对两件事感到困惑:
- 为什么这两个部分的工作方式不同,一个记录日志而另一个不记录?
- 如果在
selectFoobars
上添加了 NoLoggingT 包装器,为什么第二部分会记录日志?
代码:
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad.IO.Class
import Control.Monad.Logger.CallStack
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.Resource (ResourceT)
import Data.String.Class (toString)
import Database.Esqueleto
import Database.Persist.Sqlite (createSqlitePool)
import qualified Database.Persist.Sqlite as P
import Database.Persist.TH
import GHC.Natural
import System.Log.FastLogger (fromLogStr)
instance MonadLogger IO where
monadLoggerLog _loc _src _lvl msg =
putStrLn (toString (fromLogStr (toLogStr msg)))
share
[mkPersist sqlSettings, mkMigrate "migrateAll"]
[persistLowerCase|
Foo
bar Natural
|]
runSomeQuery :: ConnectionPool -> Natural -> IO (Maybe Natural)
runSomeQuery pool aid = do
flip runSqlPersistMPool pool $ do
runMigration migrateAll
_ <- selectFooBars aid
return Nothing
selectFooBars ::
Natural -> ReaderT SqlBackend (NoLoggingT (ResourceT IO)) [Entity Foo]
selectFooBars aid = do
logDebugN "This should not log?"
select . from $ \s -> do
where_ $ (s ^. FooBar ==. val aid)
limit 1
return s
main :: IO ()
main = do
logDebugN "MAIN"
P.runSqlite ":memory:" $ do
logDebugN "STARTING UP 01"
runMigration migrateAll
_ <- selectFooBars 123
return ()
budgetPool <- createSqlitePool ":memory:" 1
logDebugN ">>>>>>>>>>>>>>>"
logDebugN ">>>>>>>>>>>>>>>"
logDebugN ">>>>>>>>>>>>>>>"
logDebugN "STARTING UP 02"
_ <- runSomeQuery budgetPool 975
return ()
找到完全可构建的存储库
似乎日志功能分配给了连接信息本身,并且 createSqlPool
分配了你 运行 你的 createSqlitePool
中的任何地方:
createSqlPool
:: (MonadLogger m, MonadUnliftIO m, IsSqlBackend backend)
=> (LogFunc -> IO backend)
-> Int
-> m (Pool backend)
createSqlPool mkConn size = do
logFunc <- askLogFunc
liftIO $ createPool (mkConn logFunc) close' 1 20 size
并且runSqlite
在NoLoggingT
中显式运行其代码:
runSqlite :: (MonadUnliftIO m, IsSqlBackend backend)
=> Text -- ^ connection string
-> ReaderT backend (NoLoggingT (ResourceT m)) a -- ^ database action
-> m a
runSqlite connstr = runResourceT
. runNoLoggingT
. withSqliteConn connstr
. runSqlConn
因此,如果您将代码更改为:
budgetPool <- runNoLoggingT $ createSqlitePool ":memory:" 1
它将停止记录。它仍然不尊重 selectFooBars
类型注释中的 NoLoggingT
,这有点令人困惑。
我做了这段代码,我对两件事感到困惑:
- 为什么这两个部分的工作方式不同,一个记录日志而另一个不记录?
- 如果在
selectFoobars
上添加了 NoLoggingT 包装器,为什么第二部分会记录日志?
代码:
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad.IO.Class
import Control.Monad.Logger.CallStack
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.Resource (ResourceT)
import Data.String.Class (toString)
import Database.Esqueleto
import Database.Persist.Sqlite (createSqlitePool)
import qualified Database.Persist.Sqlite as P
import Database.Persist.TH
import GHC.Natural
import System.Log.FastLogger (fromLogStr)
instance MonadLogger IO where
monadLoggerLog _loc _src _lvl msg =
putStrLn (toString (fromLogStr (toLogStr msg)))
share
[mkPersist sqlSettings, mkMigrate "migrateAll"]
[persistLowerCase|
Foo
bar Natural
|]
runSomeQuery :: ConnectionPool -> Natural -> IO (Maybe Natural)
runSomeQuery pool aid = do
flip runSqlPersistMPool pool $ do
runMigration migrateAll
_ <- selectFooBars aid
return Nothing
selectFooBars ::
Natural -> ReaderT SqlBackend (NoLoggingT (ResourceT IO)) [Entity Foo]
selectFooBars aid = do
logDebugN "This should not log?"
select . from $ \s -> do
where_ $ (s ^. FooBar ==. val aid)
limit 1
return s
main :: IO ()
main = do
logDebugN "MAIN"
P.runSqlite ":memory:" $ do
logDebugN "STARTING UP 01"
runMigration migrateAll
_ <- selectFooBars 123
return ()
budgetPool <- createSqlitePool ":memory:" 1
logDebugN ">>>>>>>>>>>>>>>"
logDebugN ">>>>>>>>>>>>>>>"
logDebugN ">>>>>>>>>>>>>>>"
logDebugN "STARTING UP 02"
_ <- runSomeQuery budgetPool 975
return ()
找到完全可构建的存储库
似乎日志功能分配给了连接信息本身,并且 createSqlPool
分配了你 运行 你的 createSqlitePool
中的任何地方:
createSqlPool
:: (MonadLogger m, MonadUnliftIO m, IsSqlBackend backend)
=> (LogFunc -> IO backend)
-> Int
-> m (Pool backend)
createSqlPool mkConn size = do
logFunc <- askLogFunc
liftIO $ createPool (mkConn logFunc) close' 1 20 size
并且runSqlite
在NoLoggingT
中显式运行其代码:
runSqlite :: (MonadUnliftIO m, IsSqlBackend backend)
=> Text -- ^ connection string
-> ReaderT backend (NoLoggingT (ResourceT m)) a -- ^ database action
-> m a
runSqlite connstr = runResourceT
. runNoLoggingT
. withSqliteConn connstr
. runSqlConn
因此,如果您将代码更改为:
budgetPool <- runNoLoggingT $ createSqlitePool ":memory:" 1
它将停止记录。它仍然不尊重 selectFooBars
类型注释中的 NoLoggingT
,这有点令人困惑。