module Control.Eff.LogWriter.File
( withFileLogging
, withFileLogWriter
)
where
import Control.Eff as Eff
import Control.Eff.Log
import Control.Eff.LogWriter.IO
import GHC.Stack
import Data.Text as T
import qualified System.IO as IO
import System.Directory ( canonicalizePath
, createDirectoryIfMissing
)
import System.FilePath ( takeDirectory )
import qualified Control.Exception.Safe as Safe
import qualified Control.Monad.Catch as Catch
import Control.Monad.Trans.Control ( MonadBaseControl
, liftBaseOp
)
withFileLogging
:: (Lifted IO e, MonadBaseControl IO (Eff e))
=> FilePath
-> Text
-> Facility
-> LogPredicate
-> Eff (Logs : LogWriterReader IO : e) a
-> Eff e a
withFileLogging fnIn a f p e =
liftBaseOp (withOpenedLogFile fnIn) (\lw -> withIoLogging lw a f p e)
withFileLogWriter
:: (Lifted IO e, LogsTo IO e, MonadBaseControl IO (Eff e))
=> FilePath
-> Eff e b
-> Eff e b
withFileLogWriter fnIn e =
liftBaseOp (withOpenedLogFile fnIn) (`addLogWriter` e)
withOpenedLogFile :: HasCallStack => FilePath -> (LogWriter IO -> IO a) -> IO a
withOpenedLogFile fnIn ioE = Safe.bracket
(do
fnCanon <- canonicalizePath fnIn
createDirectoryIfMissing True (takeDirectory fnCanon)
h <- IO.openFile fnCanon IO.AppendMode
IO.hSetBuffering h (IO.BlockBuffering (Just 1024))
return h
)
(\h -> Safe.try @IO @Catch.SomeException (IO.hFlush h) >> IO.hClose h)
(\h -> ioE (ioHandleLogWriter h))