[logging] log level specified in env `LOG_LEVEL` variable

parent 84a773b4
Pipeline #6853 failed with stages
in 17 minutes and 32 seconds
......@@ -17,10 +17,13 @@ import Language.Haskell.TH hiding (Type)
import Control.Exception.Safe (MonadMask, bracket)
import Control.Monad.IO.Class
import Control.Monad.Trans.Control
import Data.Text qualified as T
import Data.Kind (Type)
import Language.Haskell.TH.Syntax qualified as TH
import Prelude
import qualified Data.Text as T
import qualified Language.Haskell.TH.Syntax as TH
import System.Environment (lookupEnv)
import Text.Read (readMaybe)
data LogLevel =
-- | Debug messages
......@@ -39,7 +42,7 @@ data LogLevel =
| ALERT
-- | System is unusable
| EMERGENCY
deriving (Show, Eq, Ord, Enum, Bounded)
deriving (Show, Eq, Ord, Enum, Bounded, Read)
-- | This is a barebore logging interface which we
-- can extend to plug a proper logging library, without
......@@ -121,12 +124,23 @@ withLoggerHoisted params act = bracket (initLogger params) destroyLogger act
-- | A plain logger in the IO monad, waiting for more serious logging solutions like
-- the one described in https://gitlab.iscpif.fr/gargantext/haskell-gargantext/issues/229
instance HasLogger IO where
data instance Logger IO = IOLogger
data instance Logger IO = IOLogger LogLevel
type instance LogInitParams IO = ()
type instance LogPayload IO = String
initLogger = \() -> pure IOLogger
initLogger = \() -> do
mLvl <- liftIO $ lookupEnv "LOG_LEVEL"
let lvl = case mLvl of
Nothing -> INFO
Just s ->
case readMaybe s of
Nothing -> error $ "unknown log level " <> s
Just lvl' -> lvl'
pure $ IOLogger lvl
destroyLogger = \_ -> pure ()
logMsg = \IOLogger lvl msg ->
let pfx = "[" <> show lvl <> "] "
in putStrLn $ pfx <> msg
logMsg = \(IOLogger minLvl) lvl msg -> do
if lvl < minLvl
then pure ()
else do
let pfx = "[" <> show lvl <> "] "
putStrLn $ pfx <> msg
logTxt lgr lvl msg = logMsg lgr lvl (T.unpack msg)
  • @AlfredoDiNapoli What do you think of this commit? It's a simple way to specify log level by setting LOG_LEVEL=DEBUG in environment. One can then specify log level for tests etc to remove the debug messages.

  • @cgenie Yes, in principle I'm happy with this for now. Some things to think about for the near/medium term:

    1. How do we document all these env vars? We have quite a few within garg (for example I use one in test to enable verbose logging of HTTP requests), but they are quite easy to miss and forget about. Maybe we could have an enum type which would map to env var names, and have a way to turn that into documentation in the README, or similar.

    2. What you have done here works for the IO Logger, which is really the "worst" logger we could use as I have added it just as an escape hatch to be able to log in every IO monad. Ideally we should have a general (i.e. abstracted) machinery so that this behaviour becomes standard in all the instances of HasLogger m where m is either MonadIO m or MonadBaseControl IO m or similar. This way we don't have to repeat this boilerplate every time.

    3. The implementation of logMsg for IO is doing something that in principle should be abstracted out for every logger. In fact, I remember (but I can't easily check the code now) that there is already some piece of machinery in the MonadLogger class that does what you are doing here. Again, we should abstract this out, because the level filtering is something general to all loggers, not just IO.

Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment