ocharles/logging-effect

Q: withBatchedHandler

Closed this issue · 5 comments

I might be tired or slow today, but I don't understand the second argument of withBatchedHandler.

withBatchedHandler :: (MonadIO io, MonadMask io) => 
       BatchingOptions 
  -> (NonEmpty message -> IO ()) 
  -> (Handler io message -> io a) 
  -> io a 

Is that the "flushing" function? How is it supposed to be used? Thanks!

The NonEmpty message -> IO () argument? That is indeed a 'flushing' argument that takes a batch of messages and should atomically deliver them to your desired logging output. For example,

traverse_ putStrLn

is a reasonable function that would be NonEmpty String -> IO (). Here's an example withBatchedHandler call we use at work:

withLogHandler
  :: ( MonadIO m, MonadMask m )
  => ( Handler m ( WithSeverity ( PP.Doc () ) ) -> m a ) -> m a
withLogHandler =
  withBatchedHandler
    defaultBatchingOptions
    ( \messages -> do
        PP.vsep ( toList ( fmap ( renderWithSeverity id ) messages ) ) <> PP.line'
          & PP.layoutPretty ( PP.LayoutOptions PP.Unbounded )
          & liftIO . PP.renderIO stdout

        hFlush stdout
    )

I see, thanks! The documentation is a bit terse on this. I'll try it out and see if I can submit a docs PR soon! 🎉

Happy to help, and happy to see if we can improve the docs!

Ah, another thing I just noticed. Do you always have to hFlush "by hand" before exiting that bracket?

I would strongly advise doing so, yea. withBatchedHandler doesn't know what you're actually doing there, so it has no idea if you're interacting with handles or not. All it knows is that you're dispatching a batch of messages. As such, I'd suggest if you are writing to stdout/stderr you probably want to flush too, to ensure your messages appear promptly.