diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -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 #-}
diff --git a/easy-logger.cabal b/easy-logger.cabal
--- a/easy-logger.cabal
+++ b/easy-logger.cabal
@@ -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
diff --git a/src/EasyLogger/LogStr.hs b/src/EasyLogger/LogStr.hs
--- a/src/EasyLogger/LogStr.hs
+++ b/src/EasyLogger/LogStr.hs
@@ -1,10 +1,10 @@
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE OverloadedStrings    #-}
-{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
 module EasyLogger.LogStr
     ( LogStr (..)
     , ToLogStr (..)
     , logStrLen
+    , fromLogStr
     , mkMinLogStrLen
     ) where
 
diff --git a/src/EasyLogger/Logger.hs b/src/EasyLogger/Logger.hs
--- a/src/EasyLogger/Logger.hs
+++ b/src/EasyLogger/Logger.hs
@@ -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
