easy-logger 0.1.0.4 → 0.1.0.6
raw patch · 4 files changed
+230/−49 lines, 4 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ EasyLogger.LogStr: fromLogStr :: LogStr -> ByteString
+ EasyLogger.Logger: logAllText :: Q Exp
+ EasyLogger.Logger: logDebugText :: Q Exp
+ EasyLogger.Logger: logErrorText :: Q Exp
+ EasyLogger.Logger: logInfoText :: Q Exp
+ EasyLogger.Logger: logPrintAllText :: Q Exp
+ EasyLogger.Logger: logPrintDebugText :: Q Exp
+ EasyLogger.Logger: logPrintErrorText :: Q Exp
+ EasyLogger.Logger: logPrintInfoText :: Q Exp
+ EasyLogger.Logger: logPrintWarningText :: Q Exp
+ EasyLogger.Logger: logWarningText :: Q Exp
+ EasyLogger.Logger: pureLogAllText :: Q Exp
+ EasyLogger.Logger: pureLogDebugText :: Q Exp
+ EasyLogger.Logger: pureLogErrorText :: Q Exp
+ EasyLogger.Logger: pureLogInfoText :: Q Exp
+ EasyLogger.Logger: pureLogPrintAllText :: Q Exp
+ EasyLogger.Logger: pureLogPrintDebugText :: Q Exp
+ EasyLogger.Logger: pureLogPrintErrorText :: Q Exp
+ EasyLogger.Logger: pureLogPrintInfoText :: Q Exp
+ EasyLogger.Logger: pureLogPrintWarningText :: Q Exp
+ EasyLogger.Logger: pureLogWarningText :: Q Exp
+ EasyLogger.Logger: setPrintLocationToConsole :: Bool -> IO ()
Files
- README.md +51/−8
- easy-logger.cabal +2/−2
- src/EasyLogger/LogStr.hs +3/−3
- src/EasyLogger/Logger.hs +174/−36
README.md view
@@ -8,7 +8,9 @@ Initialise the logger for your package and start logging: - import qualified Data.Text as T+ {-# LANGUAGE TemplateHaskell #-}+ import EasyLogger+ import qualified Data.Text as T main :: IO () main = do@@ -18,11 +20,50 @@ # At the end of your program, flush the buffers: finalizeAllLoggers -You can also include the logs of the libraries that you use and which use the `easy-logger` package-for logging. If the library maintainer is nice, (s)he allows you to turn on/off logging for that-library only. See the Library section below how to do it. To turn logging for all packages-(that use easy-logger) on, do this:+The log output looks like this: + $ cat package.log+ [INFO #22-Oct-2021 12:27:23] Starting App @(main:Main+++If you use libraries, **including your own package library**, to log from a file outside of+`Main.hs` you need to make the library package name available and enable the logging specifically. For this create following file:++ {-# LANGUAGE TemplateHaskell #-}+ module MyPackage.Logging+ ( enableMyPackageLogging+ , disableMyPackageLogging+ ) where++ import EasyLogger++ enableMyPackageLogging :: LogDestination -> LogLevel -> IO ()+ enableMyPackageLogging = $(initLogger)++ disableMyPackageLogging :: IO ()+ disableMyPackageLogging = $(finalizeLogger)++and then enable it:++ {-# LANGUAGE TemplateHaskell #-}+ import EasyLogger+ import MyPackage.Logging+ import qualified Data.Text as T++ main :: IO ()+ main = do+ $(initLogger) (LogFile "package.log") LogDebug+ enableMyPackageLogging (LogFile "package.log") LogDebug+ ...+ # At the end of your program, flush the buffers:+ finalizeAllLoggers+++You can also include the logs of all the libraries that you use and which use the `easy-logger`+package for logging:++ {-# LANGUAGE TemplateHaskell #-}+ import EasyLogger import qualified Data.Text as T main :: IO ()@@ -47,7 +88,8 @@ The available log levels are: - -- | Log Level. Levels are sorted. `All` < `Debug` < `Info` < `Warning` < `Error`. None disables all logging. Default: All+ -- | Log Level. Levels are sorted. `All` < `Debug` < `Info` < `Warning` < `Error`.+ -- None disables all logging. Default: All data LogLevel = LogNone | LogAll@@ -68,8 +110,9 @@ ## Library -If you are exposing a library, let your user turn on/off the logging for your library. The-Template-Haskell code ensures that your package name is provided to the logger, and thus logging for this module only is turned on/off.+If you are exposing a library (including your own library), let your user turn on/off the logging+for your library. The Template-Haskell code ensures that your package name is provided to the+logger, and thus logging for this module only is turned on/off. {-# LANGUAGE TemplateHaskell #-}
easy-logger.cabal view
@@ -5,9 +5,9 @@ -- see: https://github.com/sol/hpack name: easy-logger-version: 0.1.0.4+version: 0.1.0.6 synopsis: Logging made easy.-description: Please see the README on GitHub at <https://github.com/githubuser/easy-logger#readme>+description: Please see the README on GitHub at <https://github.com/schnecki/easy-logger#readme> category: Logging homepage: https://github.com/schnecki/easy-logger#readme bug-reports: https://github.com/schnecki/easy-logger/issues
src/EasyLogger/LogStr.hs view
@@ -1,10 +1,10 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-} module EasyLogger.LogStr ( LogStr (..) , ToLogStr (..) , logStrLen+ , fromLogStr , mkMinLogStrLen ) where
src/EasyLogger/Logger.hs view
@@ -7,6 +7,7 @@ , initLoggerAllPackages , setLoggingDestination , setMinLogLevel+ , setPrintLocationToConsole , logAll , logPrintAll , logDebug@@ -27,6 +28,26 @@ , pureLogPrintWarning , pureLogError , pureLogPrintError+ , logAllText+ , logPrintAllText+ , logDebugText+ , logPrintDebugText+ , logInfoText+ , logPrintInfoText+ , logWarningText+ , logPrintWarningText+ , logErrorText+ , logPrintErrorText+ , pureLogAllText+ , pureLogPrintAllText+ , pureLogDebugText+ , pureLogPrintDebugText+ , pureLogInfoText+ , pureLogPrintInfoText+ , pureLogWarningText+ , pureLogPrintWarningText+ , pureLogErrorText+ , pureLogPrintErrorText , finalizeAllLoggers , finalizeLogger , flushLoggers@@ -51,8 +72,6 @@ import EasyLogger.Util (liftLoc) -import Debug.Trace- -- | Add a @LoggerSet@ to the known loggers. setLoggerSet :: String -> LoggerSet -> IO () setLoggerSet pkgName set = modifyIORef' loggerSets (M.insert pkgName set)@@ -117,11 +136,11 @@ -- | Initialise the logger. MUST only be called in the executable code (not the exposed library code)! Takes a `Bool` that decides wether to log messages from other packages that use the same library -- and did not initalize the Logger (which should be the case for all of them!). initLoggerAllPackages :: Q Exp-initLoggerAllPackages = [| \dest logLevel logAllPkgs -> setMinLogLevel logLevel >> setLoggingDestination (loc_package $(qLocation >>= liftLoc)) dest logAllPkgs |]+initLoggerAllPackages = [| \dest logAllPkgs -> setLoggingDestination (loc_package $(qLocation >>= liftLoc)) dest logAllPkgs |] -- | Initialise the logger. MUST only be called in the executable code (not the exposed library code)! Ignores the other packages logs, if the same packages is used for logging. initLogger :: Q Exp-initLogger = [| \dest logLevel -> setMinLogLevel logLevel >> setLoggingDestination (loc_package $(qLocation >>= liftLoc)) dest False |]+initLogger = [| \dest -> setLoggingDestination (loc_package $(qLocation >>= liftLoc)) dest False |] -- | Set the destination for all consequitive for logging. You should only set this once, at the beginning of the program! The default is `LogStdOut`. setLoggingDestination :: String -> LogDestination -> LogFromAllPackages -> IO ()@@ -174,10 +193,10 @@ logLevelText LogError = "ERROR" -- | Generic log function. Use TH version, e.g. `logDebug`.-logFun :: (ToLogStr msg) => Loc -> LogLevel -> msg -> IO ()-logFun _ LogNone _ = return ()-logFun loc@(Loc _ pkg _ _ _) level msg = do- minLevel <- readIORef minLogLevel+logFun :: (ToLogStr msg) => Bool -> Loc -> LogLevel -> msg -> IO ()+logFun _ _ LogNone _ = return ()+logFun printMsg loc@(Loc _ pkg _ _ _) level msg = do+ (minLevel, printLoc) <- readIORef minLogLevel when (level >= minLevel) $ do now <- join (readIORef cachedTime) readIORef loggerSets >>= \sets ->@@ -185,167 +204,286 @@ Nothing -- Check the package name of the caller, as otherwise any library logging would halt the process. | M.null sets && pkg == mainLogPkgName -> error "You must call `initLogger` at the start of your application! See the documentation of `EasyLogger.Logger`." Nothing -> return ()- Just set -> pushLogStr set (defaultLogStr loc now level (toLogStr msg))+ Just set -> do+ let logStr = defaultLogStr True loc now level (toLogStr msg)+ logStrPrint | printLoc = logStr+ | otherwise = defaultLogStr False loc now level (toLogStr msg)+ when printMsg $ S8.hPutStr handle (fromLogStr logStrPrint) >> hFlush handle+ pushLogStr set logStr where getLogger sets = M.lookup pkg sets <|> M.lookup defaultLogPkgName sets+ handle = case level of+ LogError -> stderr+ _ -> stdout +mkTxt :: T.Text -> T.Text+mkTxt = id++ cachedTime :: IORef (IO FormattedTime) cachedTime = unsafePerformIO $ do cache <- newTimeCache simpleTimeFormat' newIORef cache -minLogLevel :: IORef LogLevel-minLogLevel = unsafePerformIO $ newIORef LogAll+-- | Min Log Level and whether to print location to console.+minLogLevel :: IORef (LogLevel, Bool)+minLogLevel = unsafePerformIO $ newIORef (LogAll, False) {-# NOINLINE minLogLevel #-} -- | Set the least logging level. Levels lower will not be logged. Log Level Order: `Debug` < `Info` < `Warning` < `Error`. `None` disables all logging. Note that the output to stderr using e.g. `logPrintError` will not -- be affected! setMinLogLevel :: LogLevel -> IO ()-setMinLogLevel = writeIORef minLogLevel+setMinLogLevel x = modifyIORef minLogLevel (\(_, b) -> (x, b)) +-- | Set the least logging level. Levels lower will not be logged. Log Level Order: `Debug` < `Info` < `Warning` < `Error`. `None` disables all logging. Note that the output to stderr using e.g. `logPrintError` will not+-- be affected!+setPrintLocationToConsole :: Bool -> IO ()+setPrintLocationToConsole x = modifyIORef minLogLevel (\(l, _) -> (l, x))++ ------------------------------ All ------------------------------ -- | Generates a function that takes a 'Text' and logs a 'LevelAll' message. Usage: ----- > $(logAll) "This is a debug log message"+-- > $(logAll) ("This is a debug log message" :: T.Text) logAll :: Q Exp-logAll = [| liftIO . logFun $(qLocation >>= liftLoc) LogAll |]+logAll = [| liftIO . logFun False $(qLocation >>= liftLoc) LogAll |] +-- | Same as logAll, but with concrete type `Text` as message.+--+-- > $(logAll) "This is a debug log message"+--+logAllText :: Q Exp+logAllText = [| liftIO . logFun False $(qLocation >>= liftLoc) LogAll . mkTxt |]++ -- | Same as `logAll`, but for pure code. Uses @unsafePerformIO@. -- -- > $(pureLogAll) "This is a debug log message" (3 * 3) pureLogAll :: Q Exp-pureLogAll = [| \txt a -> unsafePerformIO (logFun $(qLocation >>= liftLoc) LogAll txt >> return a) |]+pureLogAll = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogAll txt >> return a) |] +-- | Same as `pureLogAll`, but with concrete type `Text` as message.+pureLogAllText :: Q Exp+pureLogAllText = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogAll (mkTxt txt) >> return a) |] + -- | Same as `logAll`, but also prints the message on `stdout`. logPrintAll :: Q Exp-logPrintAll = [| \txt -> liftIO (hPutStrLn stdout ("DEBUG: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogAll txt) |]+logPrintAll = [| liftIO . logFun True $(qLocation >>= liftLoc) LogAll |] +-- | Same as `logAll`, but also prints the message on `stdout`. Only for `Text`.+logPrintAllText :: Q Exp+logPrintAllText = [| liftIO . logFun True $(qLocation >>= liftLoc) LogAll . mkTxt |]++ -- | Same as `pureLogAll`, but also prints the message on `stdout`. -- -- > $(pureLogPrintAll) "This is a debug log message" (3 * 3) pureLogPrintAll :: Q Exp-pureLogPrintAll = [| \txt a -> unsafePerformIO (hPutStrLn stdout ("DEBUG: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogAll txt >> return a) |]+pureLogPrintAll = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogAll txt >> return a) |] +-- | Same as `pureLogPrintAll`, but with concrete type `Text` as log message.+pureLogPrintAllText :: Q Exp+pureLogPrintAllText = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogAll (mkTxt txt) >> return a) |]++ ------------------------------ Debug ------------------------------ -- | Generates a function that takes a 'Text' and logs a 'LevelDebug' message. Usage: -- -- > $(logDebug) "This is a debug log message" logDebug :: Q Exp-logDebug = [| liftIO . logFun $(qLocation >>= liftLoc) LogDebug |]+logDebug = [| liftIO . logFun False $(qLocation >>= liftLoc) LogDebug |] +-- | Same as `logDebug` but with `Text` as fixed message type.+logDebugText :: Q Exp+logDebugText = [| liftIO . logFun False $(qLocation >>= liftLoc) LogDebug . mkTxt |]++ -- | Same as `logDebug`, but for pure code. Uses @unsafePerformIO@ -- -- > $(pureLogDebug) "This is a debug log message" defaultValue pureLogDebug :: Q Exp-pureLogDebug = [| \txt a -> unsafePerformIO (logFun $(qLocation >>= liftLoc) LogDebug txt >> return a) |]+pureLogDebug = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogDebug txt >> return a) |] +-- | Same as `pureLogDebug`, but with concrete type `Text` as message.+pureLogDebugText :: Q Exp+pureLogDebugText = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogDebug (mkTxt txt) >> return a) |]++ -- | Same as `logDebug`, but also prints the message on `stdout`. logPrintDebug :: Q Exp-logPrintDebug = [| \txt -> hPutStrLn stdout ("DEBUG: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogDebug txt |]+logPrintDebug = [| liftIO . logFun True $(qLocation >>= liftLoc) LogDebug |] +-- | Same as `logDebug`, but also prints the message on `stdout`. Only for Text.+logPrintDebugText :: Q Exp+logPrintDebugText = [| liftIO . logFun True $(qLocation >>= liftLoc) LogDebug . mkTxt |]++ -- | Same as `pureLogDebug`, but also prints the message on `stdout`. -- -- > $(purePrintLogDebug) "This is a debug log message" defaultValue pureLogPrintDebug :: Q Exp-pureLogPrintDebug = [| \txt a -> unsafePerformIO (hPutStrLn stdout ("DEBUG: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogDebug txt >> return a) |]+pureLogPrintDebug = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogDebug txt >> return a) |] +-- | Same as `pureLogPrintDebug`, but with concrete type `Text` as log message.+pureLogPrintDebugText :: Q Exp+pureLogPrintDebugText = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogDebug (mkTxt txt) >> return a) |]++ ------------------------------ Info ------------------------------ -- | Generates a function that takes a 'Text' and logs a 'LevelInfo' message. Usage: -- -- > $(logInfo) "This is a info log message" logInfo :: Q Exp-logInfo = [| liftIO . logFun $(qLocation >>= liftLoc) LogInfo |]+logInfo = [| liftIO . logFun False $(qLocation >>= liftLoc) LogInfo |] ++-- | Same as `logInfo` but with `Text` as fixed message type.+logInfoText :: Q Exp+logInfoText = [| liftIO . logFun False $(qLocation >>= liftLoc) LogInfo . mkTxt |]++ -- | Same as `logInfo`, but for pure code. Uses @unsafePerformIO@. -- -- > $(pureLogInfo) "This is a warning log message" (funcX 10) pureLogInfo :: Q Exp-pureLogInfo = [| \txt a -> unsafePerformIO (logFun $(qLocation >>= liftLoc) LogInfo txt >> return a) |]+pureLogInfo = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogInfo txt >> return a) |] +-- | Same as `pureLogInfo`, but with concrete type `Text` as message.+pureLogInfoText :: Q Exp+pureLogInfoText = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogInfo (mkTxt txt) >> return a) |]++ -- | Same as `logInfo`, but also prints the message on `stdout`. logPrintInfo :: Q Exp-logPrintInfo = [| \txt -> liftIO (hPutStrLn stdout ("INFO: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogInfo txt) |]+logPrintInfo = [| liftIO . logFun True $(qLocation >>= liftLoc) LogInfo |] +-- | Same as `logInfo`, but also prints the message on `stdout`.+logPrintInfoText :: Q Exp+logPrintInfoText = [| liftIO . logFun True $(qLocation >>= liftLoc) LogInfo . mkTxt |]++ -- | Same as `pureLogInfo`, but also prints the message on `stdout`. -- -- > $(pureLogPrintInfo) "This is a warning log message" (funcX 10) pureLogPrintInfo :: Q Exp-pureLogPrintInfo = [| \txt a -> unsafePerformIO (hPutStrLn stdout ("INFO: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogInfo txt >> return a) |]+pureLogPrintInfo = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogInfo txt >> return a) |] +-- | Same as `pureLogPrintInfo`, but with concrete type `Text` as log message.+pureLogPrintInfoText :: Q Exp+pureLogPrintInfoText = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogInfo (mkTxt txt) >> return a) |]++ ------------------------------ Warning ------------------------------ -- | Generates a function that takes a 'Text' and logs a 'LevelWarning' message. Usage: -- -- > $(logWarning) "This is a warning log message" logWarning :: Q Exp-logWarning = [| liftIO . logFun $(qLocation >>= liftLoc) LogWarning |]+logWarning = [| liftIO . logFun False $(qLocation >>= liftLoc) LogWarning |] +-- | Same as `logWarning` but with `Text` as fixed message type.+logWarningText :: Q Exp+logWarningText = [| liftIO . logFun False $(qLocation >>= liftLoc) LogWarning . mkTxt |]++ -- | Same as `logWarning`, but for pure code. Uses @unsafePerformIO@. -- -- > $(pureLogWarning) "This is a warning log message" "myresult" pureLogWarning :: Q Exp-pureLogWarning = [| \txt a -> unsafePerformIO (logFun $(qLocation >>= liftLoc) LogWarning txt >> return a) |]+pureLogWarning = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogWarning txt >> return a) |] +-- | Same as `pureLogWarning`, but with concrete type `Text` as message.+pureLogWarningText :: Q Exp+pureLogWarningText = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogWarning (mkTxt txt) >> return a) |] + -- | Same as `logWarning`, but also prints the message on `stdout`. logPrintWarning :: Q Exp-logPrintWarning = [| \txt -> liftIO (hPutStrLn stdout ("WARNING: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogWarning txt) |]+logPrintWarning = [| liftIO . logFun True $(qLocation >>= liftLoc) LogWarning |] +-- | Same as `logWarning`, but also prints the message on `stdout`.+logPrintWarningText :: Q Exp+logPrintWarningText = [| liftIO . logFun True $(qLocation >>= liftLoc) LogWarning . mkTxt |]++ -- | Same as `pureLogWarning`, but also prints the warning. -- -- > $(pureLogPrintWarning) "This is a error log message" (4 + 4) pureLogPrintWarning :: Q Exp-pureLogPrintWarning = [| \txt a -> unsafePerformIO (hPutStrLn stdout ("WARNING: " ++ T.unpack txt) >> hFlush stdout >> logFun $(qLocation >>= liftLoc) LogWarning txt >> return a) |]+pureLogPrintWarning = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogWarning txt >> return a) |] +-- | Same as `pureLogPrintWarning`, but with concrete type `Text` as log message.+pureLogPrintWarningText :: Q Exp+pureLogPrintWarningText = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogWarning (mkTxt txt) >> return a) |]++ ------------------------------ Error ------------------------------ -- | Generates a function that takes a 'Text' and logs a 'LevelError' message. Usage: -- -- > $(logError) "This is a error log message" logError :: Q Exp-logError = [| liftIO . logFun $(qLocation >>= liftLoc) LogError |]+logError = [| liftIO . logFun False $(qLocation >>= liftLoc) LogError |] +-- | Same as `logError` but with `Text` as fixed message type.+logErrorText :: Q Exp+logErrorText = [| liftIO . logFun False $(qLocation >>= liftLoc) LogError . mkTxt |] -- | Same as `logError`, but for pure code. Uses @unsafePerformIO@. -- -- > $(pureLogError) "This is a error log message" (4 + 4) pureLogError :: Q Exp-pureLogError = [| \txt a -> unsafePerformIO (logFun $(qLocation >>= liftLoc) LogError txt >> return a) |]+pureLogError = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogError txt >> return a) |] +-- | Same as `pureLogError`, but with concrete type `Text` as message.+pureLogErrorText :: Q Exp+pureLogErrorText = [| \txt a -> unsafePerformIO (logFun False $(qLocation >>= liftLoc) LogError (mkTxt txt) >> return a) |]++ -- | Same as `logError`, but also prints the message on `stderr`. logPrintError :: Q Exp-logPrintError = [| \txt -> liftIO (hPutStrLn stderr ("ERROR: " ++ T.unpack txt) >> hFlush stderr >> logFun $(qLocation >>= liftLoc) LogError txt) |]+logPrintError = [| liftIO . logFun True $(qLocation >>= liftLoc) LogError |] +-- | Same as `logError`, but also prints the message on `stderr`.+logPrintErrorText :: Q Exp+logPrintErrorText = [| liftIO . logFun True $(qLocation >>= liftLoc) LogError . mkTxt |]++ -- | Same as `pureLogError`, but also prints the message on `stderr`. -- -- > $(pureLogPrintError) "This is a error log message" (4 + 4) pureLogPrintError :: Q Exp-pureLogPrintError = [| \txt a -> unsafePerformIO (hPutStrLn stderr ("ERROR: " ++ T.unpack txt) >> hFlush stderr >> logFun $(qLocation >>= liftLoc) LogError txt >> return a) |]+pureLogPrintError = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogError txt >> return a) |] +-- | Same as `pureLogPrintError`, but with concrete type `Text` as log message.+pureLogPrintErrorText :: Q Exp+pureLogPrintErrorText = [| \txt a -> unsafePerformIO (logFun True $(qLocation >>= liftLoc) LogError (mkTxt txt) >> return a) |] + ---- Helpers: -defaultLogStr :: Loc+defaultLogStr :: Bool+ -> Loc -> FormattedTime -> LogLevel -> LogStr -> LogStr-defaultLogStr loc time level msg =- "[" <> toLogStr (logLevelText level) <> ("#" <> toLogStr time) <> "] " <> mkTrailWs msg <> " @(" <> toLogStr (S8.pack fileLocStr) <> ")\n"+defaultLogStr prLoc loc time level msg =+ "[" <> toLogStr (logLevelText level) <> ("#" <> toLogStr time) <> "] " <> mkTrailWs msg <> (if prLoc then " @(" <> toLogStr (S8.pack fileLocStr) <> ")\n" else "\n") where mkTrailWs = mkMinLogStrLen defaultMinLogMsgLen fileLocStr = loc_package loc ++ ':' : loc_module loc ++ ' ' : loc_filename loc ++ ':' : line loc ++ ':' : char loc ++ '-' : lineEnd loc ++ ':' : charEnd loc