5

我有一个基于 Servant 构建的应用程序,现在我想向应用程序添加日志记录。我浏览了 Haskell 日志包,我假设这个提供了我需要的东西:https ://github.com/serokell/log-warper/blob/master/log-warper/examples/HowTo.md

经常用于使用 Servant 构建应用程序的“设计模式”之一是使用 Reader monad,所以我对应用程序使用这种方法:我有包含 AppConfig 的 AppEnv。通常,我可以向 AppEnv 添加类似“记录器”实体的内容,然后在处理程序中使用它。虽然,log-warper 不提供“记录器”,但它使用了不同的方法(我认为这似乎是另一个 monad;请参阅上面链接中的示例)。所以我不知道如何将这个记录器与仆人一起使用。

这是我的基于仆人的应用程序(使用最新版本的仆人,基于文档中的示例:http: //haskell-servant.readthedocs.io/en/stable/tutorial/Server.html#welcome-hoistserver):

data AppEnv = AppEnv { config :: Config }
type MyHandler = ReaderT AppEnv (ExceptT ServantErr IO)

startApp :: AppEnv -> IO ()
startApp env = do
  run 16384 (app env)

app :: AppEnv -> Application
app env = serve readerAPI (readerServer env)

readerAPI :: Proxy ReaderAPI
readerAPI = Proxy

readerToHandler :: AppEnv -> Reader AppEnv a -> Handler a
readerToHandler env r = return (runReader r env)

readerServer :: AppEnv -> Server ReaderAPI
readerServer env = hoistServer readerAPI (readerToHandler env) readerServerT

b :: Reader AppEnv Bool
b = do
  c <- config <$> ask
  let
    s = getServerConfig c
    p = getServerPort s
  return (p == 1)

getServerConfig :: Config -> ServerConfig
getServerConfig (Config s _) = s

getServerPort :: ServerConfig -> Int
getServerPort (ServerConfig _ p) = p

readerServerT :: ServerT ReaderAPI (Reader AppEnv)
readerServerT = a :<|> b where
    a :: Reader AppEnv Int
    a = return 1797

这是主要功能:

main :: IO ()
main = do
  config <- loadYamlSettings ["etc/config.yaml"] [] useEnv
  print (config :: Config)
  let
    env = AppEnv config
  startApp env

现在,我如何将 log-warper 添加到应用程序中,以便我可以初始化记录器(我假设使用 launchFromFile),然后在应用程序中使用日志记录(logInfo、logError 等)(特别是在处理程序中,但可能在其他功能)?

谢谢

4

1 回答 1

0

常规日志记录

如果你想要一个带有一些复杂选项的通用日志工具,katip看起来是个不错的选择。甚至还有一个关于如何与仆人一起使用它的小讨论。您只需要为katip您的Config类型添加几个参数,初始化它们,然后您就可以登录您的处理程序。

请求记录

servant-server是建立在上面的waiwarp所以你可以重用很多那里的工具。如果您只是对记录有关对servant 的请求的数据感兴趣,则可以使用wai-logger而无需更改任何类型。

startApp看起来像这样。

startApp :: AppEnv -> IO ()
startApp env = do
  withStdoutLogger $ \logger -> 
    runSettings (setPort 16384 $ setLogger logger $ defaultSettings) $ app env 
于 2019-11-21T13:11:50.893 回答