logger-thread 0.1.0.0 → 0.1.0.1
raw patch · 4 files changed
+83/−83 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- LoggerThread: type Logger = Text -> IO ()
- LoggerThread: withLoggerThread :: (Logger -> IO ()) -> IO ()
+ Text.LoggerThread: type Logger = Text -> IO ()
+ Text.LoggerThread: withLoggerThread :: (Logger -> IO ()) -> IO ()
Files
- app/Main.hs +1/−1
- logger-thread.cabal +2/−2
- src/LoggerThread.hs +0/−80
- src/Text/LoggerThread.hs +80/−0
app/Main.hs view
@@ -7,7 +7,7 @@ import Control.Concurrent.STM.TQueue import Protolude hiding (bracket) -import LoggerThread+import Text.LoggerThread main :: IO () main = do
logger-thread.cabal view
@@ -1,5 +1,5 @@ name: logger-thread-version: 0.1.0.0+version: 0.1.0.1 synopsis: Run FastLogger in a thread and direct all queued messages to it. description: Please see README.md homepage: https://github.com/joe9/logger-thread#readme@@ -15,7 +15,7 @@ library hs-source-dirs: src- exposed-modules: LoggerThread+ exposed-modules: Text.LoggerThread build-depends: base < 6 , protolude , fast-logger
− src/LoggerThread.hs
@@ -1,80 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE OverloadedStrings #-}--module LoggerThread- ( withLoggerThread- , Logger- ) where--import Control.Concurrent.STM.TQueue-import Control.Exception.Safe-import Control.Monad.STM (atomically)-import Data.Text-import Protolude hiding (bracket)-import System.Log.FastLogger--type Logger = Text -> IO ()--toLog :: TQueue Text -> Text -> IO ()-toLog chan s = atomically (writeTQueue chan (s <> singleton '\n'))--withLoggerThread :: (Logger -> IO ()) -> IO ()-withLoggerThread mainThread = do- logChannel <- atomically newTQueue- bracket- (async (loggerThread logChannel))- (\loggerThreadAsync -> do- putText "after the main thread, stop the loggerThread"- -- dummy text to unblock the logger channel- threadDelay (1000 * 1000)- cancel loggerThreadAsync- putText "cancelled the loggerThread"- wait loggerThreadAsync)- (\loggerThreadAsync -> do- link loggerThreadAsync- withException- (mainThread (toLog logChannel))- (\e -> do- putText "exception in main thread"- (print :: SomeException -> IO ()) e- putText "main thread exiting"))---- 1 MiB = 1 mebibyte = 1,0242 bytes = 1,048,576 bytes--- 100 MiB = 1,048,576 * 100 bytes-loggerThread :: TQueue Text -> IO ()-loggerThread chan =- withFastLogger- (LogStderr 1048576)- (\f ->- withException- (readAndLog chan f)- (\e -> do- putText "exception in logger thread"- (print :: SomeException -> IO ()) e- shutdownLogging chan f))--shutdownLogging :: TQueue Text -> (LogStr -> IO a) -> IO ()-shutdownLogging chan f = do- putText "in shutdownLogging"- maybeValue <- atomically (tryReadTQueue chan)- case maybeValue of- Just t -> (f . (toLogStr :: Text -> LogStr)) t >> shutdownLogging chan f- Nothing -> putText "LoggerThread stopped reading, exiting" >> return ()--readAndLog :: TQueue Text -> (LogStr -> IO a) -> IO ()-readAndLog chan f =- atomically (readTQueue chan) >>= f . (toLogStr :: Text -> LogStr) >>- readAndLog chan f--- log rotation is a system function, not an application function--- should not be doing this here--- not sure how to use this. If I use it readAndLog, it gives this--- message--- GetMarketsServer: /home/j/var/betfair//log/aping-20160820-betfair.log: openFile: resource busy (file is locked)--- checkAndRotate :: FileLogSpec -> IO ()--- checkAndRotate spec =--- do size <- getFileSize (log_file spec)--- when (size > log_file_size spec)--- (rotate spec)--- getFileSize--- :: BasicPrelude.FilePath -> IO Integer--- getFileSize path = withFile path ReadMode hFileSize
+ src/Text/LoggerThread.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}++module Text.LoggerThread+ ( withLoggerThread+ , Logger+ ) where++import Control.Concurrent.STM.TQueue+import Control.Exception.Safe+import Control.Monad.STM (atomically)+import Data.Text+import Protolude hiding (bracket)+import System.Log.FastLogger++type Logger = Text -> IO ()++toLog :: TQueue Text -> Text -> IO ()+toLog chan s = atomically (writeTQueue chan (s <> singleton '\n'))++withLoggerThread :: (Logger -> IO ()) -> IO ()+withLoggerThread mainThread = do+ logChannel <- atomically newTQueue+ bracket+ (async (loggerThread logChannel))+ (\loggerThreadAsync -> do+ putText "after the main thread, stop the loggerThread"+ -- dummy text to unblock the logger channel+ threadDelay (1000 * 1000)+ cancel loggerThreadAsync+ putText "cancelled the loggerThread"+ wait loggerThreadAsync)+ (\loggerThreadAsync -> do+ link loggerThreadAsync+ withException+ (mainThread (toLog logChannel))+ (\e -> do+ putText "exception in main thread"+ (print :: SomeException -> IO ()) e+ putText "main thread exiting"))++-- 1 MiB = 1 mebibyte = 1,0242 bytes = 1,048,576 bytes+-- 100 MiB = 1,048,576 * 100 bytes+loggerThread :: TQueue Text -> IO ()+loggerThread chan =+ withFastLogger+ (LogStderr 1048576)+ (\f ->+ withException+ (readAndLog chan f)+ (\e -> do+ putText "exception in logger thread"+ (print :: SomeException -> IO ()) e+ shutdownLogging chan f))++shutdownLogging :: TQueue Text -> (LogStr -> IO a) -> IO ()+shutdownLogging chan f = do+ putText "in shutdownLogging"+ maybeValue <- atomically (tryReadTQueue chan)+ case maybeValue of+ Just t -> (f . (toLogStr :: Text -> LogStr)) t >> shutdownLogging chan f+ Nothing -> putText "LoggerThread stopped reading, exiting" >> return ()++readAndLog :: TQueue Text -> (LogStr -> IO a) -> IO ()+readAndLog chan f =+ atomically (readTQueue chan) >>= f . (toLogStr :: Text -> LogStr) >>+ readAndLog chan f+-- log rotation is a system function, not an application function+-- should not be doing this here+-- not sure how to use this. If I use it readAndLog, it gives this+-- message+-- GetMarketsServer: /home/j/var/betfair//log/aping-20160820-betfair.log: openFile: resource busy (file is locked)+-- checkAndRotate :: FileLogSpec -> IO ()+-- checkAndRotate spec =+-- do size <- getFileSize (log_file spec)+-- when (size > log_file_size spec)+-- (rotate spec)+-- getFileSize+-- :: BasicPrelude.FilePath -> IO Integer+-- getFileSize path = withFile path ReadMode hFileSize