commercialhaskell / rio

A standard library for Haskell
Other
842 stars 54 forks source link

Documentation for File Logging #107

Open locallycompact opened 6 years ago

locallycompact commented 6 years ago

Hi, I can't find anywhere in the documentation that covers writing out a log to both a file and to stdout. I expected to be able to do something like this:

configHandle <- openFile ("log.txt") WriteMode
logOptions <- logOptionsHandle stdout True <> logOptionsHandle configHandle True
withLogFunc logOptions $ flip runRIO $ do
             ...

which is obviously wrong as LogOptions isn't a monoid, but I can't see the actual way to do this.

Thanks

snoyberg commented 6 years ago

Better docs for this would definitely be a good thing. If we can come up with a solution, would you consider sending a doc PR?

I think what you're looking for is the Monoid instance of LogFunc itself:

withLogFunc options1 $ \lf1 -> withLogFunc options2 $ \lf2 ->
  runRIO (lf1 <> lf2) ...

Does that work for you?

locallycompact commented 6 years ago

Happy to put together a PR. :) That certainly compiles but it doesn't seem to be writing to file. Here's what I have:

{-# LANGUAGE NoImplicitPrelude #-}

import RIO
import System.IO

main = do
  configHandle <- openFile "foo.txt" WriteMode
  logStdout <- logOptionsHandle stdout True
  logFoo <- logOptionsHandle configHandle True

  withLogFunc logStdout $ \lfs ->
   withLogFunc logFoo    $ \lfo ->
    runRIO (lfs <> lfo) $
     logInfo . displayShow $ "foo"

This touches foo.txt but leaves it empty, and similarly if I run with just logFoo. What could be wrong here?

snoyberg commented 6 years ago

I think it's a lack of flushing. Using withBinaryFile instead seems to work:

{-# LANGUAGE NoImplicitPrelude #-}

import RIO

main = withBinaryFile "foo.txt" WriteMode $ \configHandle -> do
  logStdout <- logOptionsHandle stdout True
  logFoo <- logOptionsHandle configHandle True

  withLogFunc logStdout $ \lfs ->
   withLogFunc logFoo    $ \lfo ->
    runRIO (lfs <> lfo) $
     logInfo . displayShow $ "foo"