diff --git a/changelog.d/5-internal/logger-effect b/changelog.d/5-internal/logger-effect new file mode 100644 index 00000000000..e229f528293 --- /dev/null +++ b/changelog.d/5-internal/logger-effect @@ -0,0 +1 @@ +Generalise and move the Logger effect diff --git a/libs/polysemy-wire-zoo/polysemy-wire-zoo.cabal b/libs/polysemy-wire-zoo/polysemy-wire-zoo.cabal index f86bf650688..1eb84f96149 100644 --- a/libs/polysemy-wire-zoo/polysemy-wire-zoo.cabal +++ b/libs/polysemy-wire-zoo/polysemy-wire-zoo.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: be6e191f98f61663091d940ccdb428f4f844cf94b6defd13f19a3c65d9e4e894 +-- hash: 0204c1b2ab38844b968c4c7d7eaa789d6a585ce3d7b9f347de6b9f18792b1055 name: polysemy-wire-zoo version: 0.1.0 @@ -21,6 +21,9 @@ library exposed-modules: Polysemy.TinyLog Wire.Sem.FromUTC + Wire.Sem.Logger + Wire.Sem.Logger.Level + Wire.Sem.Logger.TinyLog Wire.Sem.Now Wire.Sem.Now.Input Wire.Sem.Now.IO diff --git a/libs/polysemy-wire-zoo/src/Polysemy/TinyLog.hs b/libs/polysemy-wire-zoo/src/Polysemy/TinyLog.hs index 6c2d316a33b..b01e04c8e34 100644 --- a/libs/polysemy-wire-zoo/src/Polysemy/TinyLog.hs +++ b/libs/polysemy-wire-zoo/src/Polysemy/TinyLog.hs @@ -14,40 +14,22 @@ -- -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -{-# LANGUAGE TemplateHaskell #-} -module Polysemy.TinyLog where +-- NOTE: This is an obsolete module. Instead, please use the more general +-- Wire.Sem.Logger logging effect. +module Polysemy.TinyLog + ( module Polysemy.TinyLog, + Logger (..), + trace, + debug, + info, + warn, + err, + fatal, + ) +where -import Imports -import Polysemy -import System.Logger (Level (..)) import qualified System.Logger as Log +import Wire.Sem.Logger -data TinyLog m a where - Polylog :: Log.Level -> (Log.Msg -> Log.Msg) -> TinyLog m () - -makeSem ''TinyLog - -runTinyLog :: Member (Embed IO) r => Log.Logger -> Sem (TinyLog ': r) a -> Sem r a -runTinyLog logger = interpret $ \(Polylog lvl msg) -> Log.log logger lvl msg - -discardLogs :: Sem (TinyLog ': r) a -> Sem r a -discardLogs = interpret f - where - f :: Applicative n => TinyLog m x -> n x - f (Polylog _ _) = pure () - --- | Abbreviation of 'log' using the corresponding log level. -trace, debug, info, warn, err, fatal :: Member TinyLog r => (Log.Msg -> Log.Msg) -> Sem r () -trace = polylog Trace -debug = polylog Debug -info = polylog Info -warn = polylog Warn -err = polylog Error -fatal = polylog Fatal -{-# INLINE trace #-} -{-# INLINE debug #-} -{-# INLINE info #-} -{-# INLINE warn #-} -{-# INLINE err #-} -{-# INLINE fatal #-} +type TinyLog = Logger (Log.Msg -> Log.Msg) diff --git a/services/spar/src/Spar/Sem/Logger.hs b/libs/polysemy-wire-zoo/src/Wire/Sem/Logger.hs similarity index 75% rename from services/spar/src/Spar/Sem/Logger.hs rename to libs/polysemy-wire-zoo/src/Wire/Sem/Logger.hs index 81296c3c954..8a3f96560c6 100644 --- a/services/spar/src/Spar/Sem/Logger.hs +++ b/libs/polysemy-wire-zoo/src/Wire/Sem/Logger.hs @@ -17,45 +17,51 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Spar.Sem.Logger - ( module Spar.Sem.Logger, - SAML.Level (..), +module Wire.Sem.Logger + ( module Wire.Sem.Logger, + module Wire.Sem.Logger.Level, ) where import Imports hiding (log) import Polysemy -import qualified SAML2.WebSSO as SAML +import Wire.Sem.Logger.Level data Logger msg m a where - Log :: SAML.Level -> msg -> Logger msg m () + Log :: Level -> msg -> Logger msg m () -- TODO(sandy): Inline this definition --- no TH makeSem ''Logger -mapLogger :: - forall msg msg' r a. - Member (Logger msg') r => - (msg -> msg') -> - Sem (Logger msg ': r) a -> - Sem r a -mapLogger f = interpret $ \case - Log lvl msg -> log lvl $ f msg - trace :: Member (Logger msg) r => msg -> Sem r () -trace = log SAML.Trace +trace = log Trace debug :: Member (Logger msg) r => msg -> Sem r () -debug = log SAML.Debug +debug = log Debug info :: Member (Logger msg) r => msg -> Sem r () -info = log SAML.Info +info = log Info warn :: Member (Logger msg) r => msg -> Sem r () -warn = log SAML.Warn +warn = log Warn err :: Member (Logger msg) r => msg -> Sem r () -err = log SAML.Error +err = log Error fatal :: Member (Logger msg) r => msg -> Sem r () -fatal = log SAML.Fatal +fatal = log Fatal + +-------------------------------------------------------------------------------- +-- General interpreters + +mapLogger :: + forall msg msg' r a. + Member (Logger msg') r => + (msg -> msg') -> + Sem (Logger msg ': r) a -> + Sem r a +mapLogger f = interpret $ \case + Log lvl msg -> log lvl $ f msg + +discardLogs :: Sem (Logger msg ': r) a -> Sem r a +discardLogs = interpret $ \(Log _ _) -> pure () diff --git a/services/spar/src/Spar/Sem/Logger/TinyLog.hs b/libs/polysemy-wire-zoo/src/Wire/Sem/Logger/Level.hs similarity index 66% rename from services/spar/src/Spar/Sem/Logger/TinyLog.hs rename to libs/polysemy-wire-zoo/src/Wire/Sem/Logger/Level.hs index 1e6398ac9d0..da6cb93901c 100644 --- a/services/spar/src/Spar/Sem/Logger/TinyLog.hs +++ b/libs/polysemy-wire-zoo/src/Wire/Sem/Logger/Level.hs @@ -15,24 +15,21 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Spar.Sem.Logger.TinyLog (loggerToTinyLog, stringLoggerToTinyLog, toLevel, fromLevel) where +module Wire.Sem.Logger.Level where import Imports -import Polysemy -import Spar.Sem.Logger (Level (..), Logger (..), mapLogger) +import qualified SAML2.WebSSO as SAML import qualified System.Logger as Log -loggerToTinyLog :: - Member (Embed IO) r => - Log.Logger -> - Sem (Logger (Log.Msg -> Log.Msg) ': r) a -> - Sem r a -loggerToTinyLog tinylog = interpret $ \case - Log lvl msg -> - embed @IO $ Log.log tinylog (toLevel lvl) msg - -stringLoggerToTinyLog :: Member (Logger (Log.Msg -> Log.Msg)) r => Sem (Logger String ': r) a -> Sem r a -stringLoggerToTinyLog = mapLogger @String Log.msg +-- | The logging level +data Level + = Fatal + | Error + | Warn + | Info + | Debug + | Trace + deriving (Eq, Show) toLevel :: Level -> Log.Level toLevel = \case @@ -51,3 +48,21 @@ fromLevel = \case Log.Info -> Info Log.Debug -> Debug Log.Trace -> Trace + +samlToLevel :: SAML.Level -> Log.Level +samlToLevel = \case + SAML.Fatal -> Log.Fatal + SAML.Error -> Log.Error + SAML.Warn -> Log.Warn + SAML.Info -> Log.Info + SAML.Debug -> Log.Debug + SAML.Trace -> Log.Trace + +samlFromLevel :: SAML.Level -> Level +samlFromLevel = \case + SAML.Fatal -> Fatal + SAML.Error -> Error + SAML.Warn -> Warn + SAML.Info -> Info + SAML.Debug -> Debug + SAML.Trace -> Trace diff --git a/libs/polysemy-wire-zoo/src/Wire/Sem/Logger/TinyLog.hs b/libs/polysemy-wire-zoo/src/Wire/Sem/Logger/TinyLog.hs new file mode 100644 index 00000000000..69a768ed4bd --- /dev/null +++ b/libs/polysemy-wire-zoo/src/Wire/Sem/Logger/TinyLog.hs @@ -0,0 +1,60 @@ +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2022 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module Wire.Sem.Logger.TinyLog + ( loggerToTinyLog, + loggerToTinyLogReqId, + stringLoggerToTinyLog, + discardTinyLogs, + module Wire.Sem.Logger.Level, + ) +where + +import Data.Id +import Imports +import Polysemy +import qualified System.Logger as Log +import Wire.Sem.Logger +import Wire.Sem.Logger.Level + +loggerToTinyLog :: + Member (Embed IO) r => + Log.Logger -> + Sem (Logger (Log.Msg -> Log.Msg) ': r) a -> + Sem r a +loggerToTinyLog tinylog = interpret $ \case + Log lvl msg -> + embed @IO $ Log.log tinylog (toLevel lvl) msg + +-- | Log the request ID along with the message +loggerToTinyLogReqId :: + Member (Embed IO) r => + RequestId -> + Log.Logger -> + Sem (Logger (Log.Msg -> Log.Msg) ': r) a -> + Sem r a +loggerToTinyLogReqId r tinylog = + loggerToTinyLog tinylog + . mapLogger + (Log.field "request" (unRequestId r) Log.~~) + . raise @(Logger (Log.Msg -> Log.Msg)) + +stringLoggerToTinyLog :: Member (Logger (Log.Msg -> Log.Msg)) r => Sem (Logger String ': r) a -> Sem r a +stringLoggerToTinyLog = mapLogger @String Log.msg + +discardTinyLogs :: Sem (Logger (Log.Msg -> Log.Msg) ': r) a -> Sem r a +discardTinyLogs = discardLogs diff --git a/services/brig/src/Brig/Calling.hs b/services/brig/src/Brig/Calling.hs index 398fdb1a1bc..cce94e7314c 100644 --- a/services/brig/src/Brig/Calling.hs +++ b/services/brig/src/Brig/Calling.hs @@ -63,6 +63,7 @@ import System.Random.MWC (GenIO, createSystemRandom) import System.Random.Shuffle import Wire.Network.DNS.Effect import Wire.Network.DNS.SRV +import Wire.Sem.Logger.TinyLog -- | NOTE SFTServers: -- Retrieving SFTServers should give a 1) randomized and 2) limited list of servers. @@ -162,7 +163,7 @@ mkSFTEnv opts = startSFTServiceDiscovery :: Log.Logger -> SFTEnv -> IO () startSFTServiceDiscovery logger = - runM . runTinyLog logger . runDNSLookupDefault . sftDiscoveryLoop + runM . loggerToTinyLog logger . runDNSLookupDefault . sftDiscoveryLoop -- | >>> diffTimeToMicroseconds 1 -- 1000000 diff --git a/services/brig/src/Brig/Calling/API.hs b/services/brig/src/Brig/Calling/API.hs index 561e494c953..9ec039d218e 100644 --- a/services/brig/src/Brig/Calling/API.hs +++ b/services/brig/src/Brig/Calling/API.hs @@ -56,11 +56,11 @@ import Network.Wai.Utilities hiding (code, message) import Network.Wai.Utilities.Swagger (document) import OpenSSL.EVP.Digest (Digest, hmacBS) import Polysemy -import Polysemy.TinyLog import qualified System.Random.MWC as MWC import Wire.API.Call.Config (SFTServer) import qualified Wire.API.Call.Config as Public import Wire.Network.DNS.SRV (srvTarget) +import Wire.Sem.Logger.TinyLog (loggerToTinyLog) routesPublic :: Routes Doc.ApiBuilder (Handler r) () routesPublic = do @@ -109,7 +109,7 @@ getCallsConfigV2 _ _ limit = do manager <- view httpManager liftIO . runM @IO - . runTinyLog logger + . loggerToTinyLog logger . interpretSFT manager $ newConfig env staticUrl sftEnv' limit sftListAllServers CallsConfigV2 @@ -125,7 +125,7 @@ getCallsConfig _ _ = do fmap dropTransport . liftIO . runM @IO - . runTinyLog logger + . loggerToTinyLog logger . interpretSFT manager $ newConfig env Nothing Nothing Nothing HideAllSFTServers CallsConfigDeprecated where diff --git a/services/brig/test/unit/Test/Brig/Calling.hs b/services/brig/test/unit/Test/Brig/Calling.hs index 83915bcf972..aaaba7e38db 100644 --- a/services/brig/test/unit/Test/Brig/Calling.hs +++ b/services/brig/test/unit/Test/Brig/Calling.hs @@ -48,6 +48,8 @@ import qualified UnliftIO.Async as Async import Wire.API.Call.Config import Wire.Network.DNS.Effect import Wire.Network.DNS.SRV +import Wire.Sem.Logger.Level +import Wire.Sem.Logger.TinyLog data FakeDNSEnv = FakeDNSEnv { fakeLookupSrv :: Domain -> SrvResponse, @@ -64,17 +66,17 @@ runFakeDNSLookup FakeDNSEnv {..} = interpret $ modifyIORef' fakeLookupSrvCalls (++ [domain]) pure $ fakeLookupSrv domain -newtype LogRecorder = LogRecorder {recordedLogs :: IORef [(Log.Level, LByteString)]} +newtype LogRecorder = LogRecorder {recordedLogs :: IORef [(Level, LByteString)]} newLogRecorder :: IO LogRecorder newLogRecorder = LogRecorder <$> newIORef [] recordLogs :: Member (Embed IO) r => LogRecorder -> Sem (TinyLog ': r) a -> Sem r a -recordLogs LogRecorder {..} = interpret $ \(Polylog lvl msg) -> +recordLogs LogRecorder {..} = interpret $ \(Log lvl msg) -> modifyIORef' recordedLogs (++ [(lvl, Log.render (Log.renderDefault ", ") msg)]) ignoreLogs :: Sem (TinyLog ': r) a -> Sem r a -ignoreLogs = interpret $ \(Polylog _ _) -> pure () +ignoreLogs = discardTinyLogs {-# ANN tests ("HLint: ignore" :: String) #-} tests :: TestTree @@ -213,7 +215,7 @@ testSFTDiscoverWhenNotAvailable = do =<< ( runM . recordLogs logRecorder . runFakeDNSLookup fakeDNSEnv $ discoverSFTServers "_sft._tcp.foo.example.com" ) - assertEqual "should warn about it in the logs" [(Log.Warn, "No SFT servers available\n")] + assertEqual "should warn about it in the logs" [(Warn, "No SFT servers available\n")] =<< readIORef (recordedLogs logRecorder) testSFTDiscoverWhenDNSFails :: IO () @@ -225,7 +227,7 @@ testSFTDiscoverWhenDNSFails = do =<< ( runM . recordLogs logRecorder . runFakeDNSLookup fakeDNSEnv $ discoverSFTServers "_sft._tcp.foo.example.com" ) - assertEqual "should warn about it in the logs" [(Log.Error, "DNS Lookup failed for SFT Discovery, Error=IllegalDomain\n")] + assertEqual "should warn about it in the logs" [(Error, "DNS Lookup failed for SFT Discovery, Error=IllegalDomain\n")] =<< readIORef (recordedLogs logRecorder) testSFTManyServers :: IO () @@ -283,7 +285,7 @@ testSFTStaticDeprecatedEndpoint = do env <- fst <$> sftStaticEnv cfg <- runM @IO - . discardLogs + . ignoreLogs . interpretSFTInMemory mempty $ newConfig env Nothing Nothing Nothing HideAllSFTServers CallsConfigDeprecated assertEqual @@ -307,7 +309,7 @@ testSFTStaticV2NoStaticUrl = do <*> pure (unsafeRange 1) cfg <- runM @IO - . discardLogs + . ignoreLogs . interpretSFTInMemory mempty $ newConfig env Nothing (Just sftEnv) (Just . unsafeRange $ 2) ListAllSFTServers CallsConfigV2 assertEqual @@ -321,7 +323,7 @@ testSFTStaticV2StaticUrlError = do (env, staticUrl) <- sftStaticEnv cfg <- runM @IO - . discardLogs + . ignoreLogs . interpretSFTInMemory mempty -- an empty lookup map, meaning there was -- an error $ newConfig env (Just staticUrl) Nothing (Just . unsafeRange $ 2) ListAllSFTServers CallsConfigV2 @@ -339,7 +341,7 @@ testSFTStaticV2StaticUrlList = do servers <- generate $ replicateM 10 arbitrary cfg <- runM @IO - . discardLogs + . ignoreLogs . interpretSFTInMemory (Map.singleton staticUrl (SFTGetResponse . Right $ servers)) $ newConfig env (Just staticUrl) Nothing (Just . unsafeRange $ 3) ListAllSFTServers CallsConfigV2 assertEqual @@ -355,7 +357,7 @@ testSFTStaticV2ListAllServersDisabled = do servers <- generate $ replicateM 10 arbitrary cfg <- runM @IO - . discardLogs + . ignoreLogs . interpretSFTInMemory (Map.singleton staticUrl (SFTGetResponse . Right $ servers)) $ newConfig env (Just staticUrl) Nothing (Just . unsafeRange $ 3) HideAllSFTServers CallsConfigV2 assertEqual diff --git a/services/federator/src/Federator/MockServer.hs b/services/federator/src/Federator/MockServer.hs index ecb1e33fd5e..cad451ba237 100644 --- a/services/federator/src/Federator/MockServer.hs +++ b/services/federator/src/Federator/MockServer.hs @@ -43,9 +43,9 @@ import Network.Wai.Utilities.Error as Wai import Network.Wai.Utilities.MockServer import Polysemy import Polysemy.Error hiding (throw) -import Polysemy.TinyLog import Wire.API.Federation.API (Component) import Wire.API.Federation.Domain +import Wire.Sem.Logger.TinyLog -- | This can be thrown by actions passed to mock federator to simulate -- failures either in federator itself, or in the services it calls. @@ -89,7 +89,7 @@ withTempMockFederator headers resp action = do let app request respond = do response <- runM - . discardLogs + . discardTinyLogs . runWaiErrors @'[ ValidationError, ServerError, diff --git a/services/federator/src/Federator/Monitor/Internal.hs b/services/federator/src/Federator/Monitor/Internal.hs index 771aa031b75..ad93fd76863 100644 --- a/services/federator/src/Federator/Monitor/Internal.hs +++ b/services/federator/src/Federator/Monitor/Internal.hs @@ -46,6 +46,7 @@ import System.Posix.ByteString (RawFilePath) import System.Posix.Files import System.X509 import Wire.API.Arbitrary +import qualified Wire.Sem.Logger.TinyLog as Log data Monitor = Monitor { monINotify :: INotify, @@ -98,7 +99,7 @@ watchPathEvents (WatchedDir _ _) = [MoveIn, Create] type Watches = Map RawFilePath (WatchDescriptor, WatchedPath) runSemDefault :: Logger -> Sem '[TinyLog, Embed IO] a -> IO a -runSemDefault logger = Polysemy.runM . Log.runTinyLog logger +runSemDefault logger = Polysemy.runM . Log.loggerToTinyLog logger logErrors :: Members '[TinyLog, Polysemy.Error FederationSetupError] r => diff --git a/services/federator/src/Federator/Response.hs b/services/federator/src/Federator/Response.hs index cc28b977194..7dac50589d1 100644 --- a/services/federator/src/Federator/Response.hs +++ b/services/federator/src/Federator/Response.hs @@ -50,6 +50,7 @@ import Polysemy.TinyLog import Servant.Client.Core import Servant.Types.SourceT import Wire.Network.DNS.Effect +import Wire.Sem.Logger.TinyLog defaultHeaders :: [HTTP.Header] defaultHeaders = [("Content-Type", "application/json")] @@ -127,7 +128,7 @@ runFederator :: Env -> Sem AllEffects Wai.Response -> Codensity IO Wai.Response runFederator env = runM . runEmbedded @IO @(Codensity IO) liftIO - . runTinyLog (view applog env) -- FUTUREWORK: add request id + . loggerToTinyLogReqId (view requestId env) (view applog env) . runWaiErrors @'[ ValidationError, RemoteError, diff --git a/services/federator/test/unit/Test/Federator/ExternalServer.hs b/services/federator/test/unit/Test/Federator/ExternalServer.hs index 5b561f73f07..dfffa52046e 100644 --- a/services/federator/test/unit/Test/Federator/ExternalServer.hs +++ b/services/federator/test/unit/Test/Federator/ExternalServer.hs @@ -53,7 +53,6 @@ import Polysemy import Polysemy.Error import Polysemy.Input import Polysemy.Output -import Polysemy.TinyLog import qualified Servant.Client.Core as Servant import Servant.Types.SourceT import Test.Federator.Options (noClientCertSettings) @@ -62,6 +61,7 @@ import Test.Federator.Validation (mockDiscoveryTrivial) import Test.Tasty import Test.Tasty.HUnit import Wire.API.Federation.Component +import Wire.Sem.Logger.TinyLog tests :: TestTree tests = @@ -126,7 +126,7 @@ requestBrigSuccess = . assertNoError @ValidationError . assertNoError @DiscoveryFailure . assertNoError @ServerError - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -151,7 +151,7 @@ requestBrigFailure = . assertNoError @ValidationError . assertNoError @DiscoveryFailure . assertNoError @ServerError - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -177,7 +177,7 @@ requestGalleySuccess = . assertNoError @ValidationError . assertNoError @DiscoveryFailure . assertNoError @ServerError - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -205,7 +205,7 @@ requestNoDomain = . runError . assertNoError @ValidationError . assertNoError @DiscoveryFailure - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -230,7 +230,7 @@ requestNoCertificate = . runError . assertNoError @ServerError . assertNoError @DiscoveryFailure - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -281,7 +281,7 @@ testInvalidPaths = do . runError @ServerError . assertNoError @ValidationError . assertNoError @DiscoveryFailure - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -304,7 +304,7 @@ testInvalidComponent = . runError @ServerError . assertNoError @ValidationError . assertNoError @DiscoveryFailure - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request @@ -332,7 +332,7 @@ testMethod = . interpret @ServiceStreaming (\_ -> embed $ assertFailure "unexpected call to service") . assertNoError @ValidationError . assertNoError @DiscoveryFailure - . discardLogs + . discardTinyLogs . mockDiscoveryTrivial . runInputConst noClientCertSettings $ callInward request diff --git a/services/federator/test/unit/Test/Federator/InternalServer.hs b/services/federator/test/unit/Test/Federator/InternalServer.hs index 89e79ff1837..f4d791bfc89 100644 --- a/services/federator/test/unit/Test/Federator/InternalServer.hs +++ b/services/federator/test/unit/Test/Federator/InternalServer.hs @@ -35,7 +35,6 @@ import qualified Network.Wai.Utilities.Server as Wai import Polysemy import Polysemy.Error import Polysemy.Input -import Polysemy.TinyLog import Servant.Client.Core import Servant.Types.SourceT import Test.Federator.Options (noClientCertSettings) @@ -44,6 +43,7 @@ import Test.Tasty import Test.Tasty.HUnit import Wire.API.Federation.Component import Wire.API.Federation.Domain +import Wire.Sem.Logger.TinyLog tests :: TestTree tests = @@ -93,7 +93,7 @@ federatedRequestSuccess = . interpretCall . assertNoError @ValidationError . assertNoError @ServerError - . discardLogs + . discardTinyLogs . runInputConst settings $ callOutward request Wai.responseStatus res @?= HTTP.status200 @@ -134,7 +134,7 @@ federatedRequestFailureAllowList = . void . checkRequest . assertNoError @ServerError - . discardLogs + . discardTinyLogs . runInputConst settings $ callOutward request eith @?= Left (FederationDenied targetDomain) diff --git a/services/federator/test/unit/Test/Federator/Monitor.hs b/services/federator/test/unit/Test/Federator/Monitor.hs index f9fada1f68a..1995379bc99 100644 --- a/services/federator/test/unit/Test/Federator/Monitor.hs +++ b/services/federator/test/unit/Test/Federator/Monitor.hs @@ -30,7 +30,6 @@ import Federator.Options import Imports import qualified Polysemy import qualified Polysemy.Error as Polysemy -import qualified Polysemy.TinyLog as Polysemy import System.FilePath import System.IO.Temp import System.Posix (createSymbolicLink, getWorkingDirectory) @@ -39,6 +38,7 @@ import Test.Federator.Options (defRunSettings) import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck +import qualified Wire.Sem.Logger.TinyLog as Log timeoutMicroseconds :: Int timeoutMicroseconds = 10000000 @@ -123,7 +123,7 @@ withSilentMonitor reloads settings = do (runSem . delMonitor) pure tlsVar where - runSem = Polysemy.runM . Polysemy.discardLogs + runSem = Polysemy.runM . Log.discardTinyLogs runSemE action = do r <- runSem (Polysemy.runError @FederationSetupError action) writeChan reloads (either Just (const Nothing) r) diff --git a/services/federator/test/unit/Test/Federator/Response.hs b/services/federator/test/unit/Test/Federator/Response.hs index 4da3f1788b8..1a5b6f664ad 100644 --- a/services/federator/test/unit/Test/Federator/Response.hs +++ b/services/federator/test/unit/Test/Federator/Response.hs @@ -30,11 +30,11 @@ import qualified Network.Wai.Utilities.Error as Wai import qualified Network.Wai.Utilities.Server as Wai import Polysemy import Polysemy.Error -import qualified Polysemy.TinyLog as TinyLog import Test.Tasty import Test.Tasty.HUnit import Wire.API.Federation.Error import Wire.Network.DNS.SRV +import qualified Wire.Sem.Logger.TinyLog as Log tests :: TestTree tests = @@ -49,7 +49,11 @@ tests = testValidationError :: TestTree testValidationError = testCase "validation errors should be converted to wai error responses" $ do - resp <- runM . TinyLog.discardLogs . runWaiError @ValidationError $ throw NoClientCertificate + resp <- + runM + . Log.discardTinyLogs + . runWaiError @ValidationError + $ throw NoClientCertificate body <- Wai.lazyResponseBody resp let merr = Aeson.decode body Wai.responseStatus resp @?= HTTP.status403 @@ -58,7 +62,11 @@ testValidationError = testServerError :: TestTree testServerError = testCase "server errors should be converted to wai error responses" $ do - resp <- runM . TinyLog.discardLogs . runWaiError @ServerError $ throw InvalidRoute + resp <- + runM + . Log.discardTinyLogs + . runWaiError @ServerError + $ throw InvalidRoute body <- Wai.lazyResponseBody resp let merr = Aeson.decode body Wai.responseStatus resp @?= HTTP.status403 @@ -68,8 +76,10 @@ testDiscoveryFailure :: TestTree testDiscoveryFailure = testCase "discovery failures should be converted to wai error responses" $ do resp <- - runM . TinyLog.discardLogs . runWaiError @DiscoveryFailure $ - throw (DiscoveryFailureDNSError "mock error") + runM + . Log.discardTinyLogs + . runWaiError @DiscoveryFailure + $ throw (DiscoveryFailureDNSError "mock error") body <- Wai.lazyResponseBody resp let merr = Aeson.decode body Wai.responseStatus resp @?= HTTP.status400 @@ -79,8 +89,10 @@ testRemoteError :: TestTree testRemoteError = testCase "remote errors should be converted to wai error responses" $ do resp <- - runM . TinyLog.discardLogs . runWaiError @RemoteError $ - throw + runM + . Log.discardTinyLogs + . runWaiError @RemoteError + $ throw ( RemoteError (SrvTarget "example.com" 7777) FederatorClientNoStatusCode diff --git a/services/galley/src/Galley/App.hs b/services/galley/src/Galley/App.hs index aa0173c53b5..189a569564a 100644 --- a/services/galley/src/Galley/App.hs +++ b/services/galley/src/Galley/App.hs @@ -102,6 +102,7 @@ import qualified UnliftIO.Exception as UnliftIO import Util.Options import Wire.API.Error import Wire.API.Federation.Error +import qualified Wire.Sem.Logger as Log -- Effects needed by the interpretation of other effects type GalleyEffects0 = @@ -195,7 +196,7 @@ interpretTinyLog :: Sem (P.TinyLog ': r) a -> Sem r a interpretTinyLog e = interpret $ \case - P.Polylog l m -> Logger.log (e ^. applog) l (reqIdMsg (e ^. reqId) . m) + P.Log l m -> Logger.log (e ^. applog) (Log.toLevel l) (reqIdMsg (e ^. reqId) . m) toServantHandler :: Env -> Sem GalleyEffects a -> Servant.Handler a toServantHandler e = liftIO . evalGalley e diff --git a/services/spar/spar.cabal b/services/spar/spar.cabal index 56ab6ec4830..768b3d65bda 100644 --- a/services/spar/spar.cabal +++ b/services/spar/spar.cabal @@ -59,8 +59,6 @@ library Spar.Sem.IdPRawMetadataStore.Cassandra Spar.Sem.IdPRawMetadataStore.Mem Spar.Sem.IdPRawMetadataStore.Spec - Spar.Sem.Logger - Spar.Sem.Logger.TinyLog Spar.Sem.Reporter Spar.Sem.Reporter.Wai Spar.Sem.SAML2 diff --git a/services/spar/src/Spar/API.hs b/services/spar/src/Spar/API.hs index aef7fd1b68b..d1c81bbf588 100644 --- a/services/spar/src/Spar/API.hs +++ b/services/spar/src/Spar/API.hs @@ -79,8 +79,6 @@ import Spar.Sem.IdPConfigStore (GetIdPResult (..), IdPConfigStore, Replaced (..) import qualified Spar.Sem.IdPConfigStore as IdPConfigStore import Spar.Sem.IdPRawMetadataStore (IdPRawMetadataStore) import qualified Spar.Sem.IdPRawMetadataStore as IdPRawMetadataStore -import Spar.Sem.Logger (Logger) -import qualified Spar.Sem.Logger as Logger import Spar.Sem.Reporter (Reporter) import Spar.Sem.SAML2 (SAML2) import qualified Spar.Sem.SAML2 as SAML2 @@ -100,6 +98,8 @@ import Wire.API.Cookie import Wire.API.Routes.Public.Spar import Wire.API.User.IdentityProvider import Wire.API.User.Saml +import Wire.Sem.Logger (Logger) +import qualified Wire.Sem.Logger as Logger import Wire.Sem.Now (Now) import Wire.Sem.Random (Random) import qualified Wire.Sem.Random as Random @@ -272,7 +272,7 @@ authreq authreqttl _ zusr msucc merr idpid = do SAML2.authReq authreqttl (SamlProtocolSettings.spIssuer mbtid) idpid VerdictFormatStore.store authreqttl reqid vformat cky <- initializeBindCookie zusr authreqttl - Logger.log SAML.Debug $ "setting bind cookie: " <> show cky + Logger.log Logger.Debug $ "setting bind cookie: " <> show cky pure $ addHeader cky form -- | If the user is already authenticated, create bind cookie with a given life expectancy and our @@ -618,8 +618,8 @@ validateNewIdP apiversion _idpMetadata teamId mReplaces = withDebugLog "validate _idpExtraInfo = WireIdP teamId (Just apiversion) oldIssuers Nothing enforceHttps requri idp <- getIdPConfigByIssuer (_idpMetadata ^. SAML.edIssuer) teamId - Logger.log SAML.Debug $ show (apiversion, _idpMetadata, teamId, mReplaces) - Logger.log SAML.Debug $ show (_idpId, oldIssuers, idp) + Logger.log Logger.Debug $ show (apiversion, _idpMetadata, teamId, mReplaces) + Logger.log Logger.Debug $ show (_idpId, oldIssuers, idp) let handleIdPClash :: Either id idp -> m () -- (HINT: using type vars above instead of the actual types constitutes a proof that @@ -746,10 +746,10 @@ validateIdPUpdate zusr _idpMetadata _idpId = withDebugLog "validateNewIdP" (Just withDebugLog :: Member (Logger String) r => String -> (a -> Maybe String) -> Sem r a -> Sem r a withDebugLog msg showval action = do - Logger.log SAML.Debug $ "entering " ++ msg + Logger.log Logger.Debug $ "entering " ++ msg val <- action let mshowedval = showval val - Logger.log SAML.Debug $ "leaving " ++ msg ++ mconcat [": " ++ fromJust mshowedval | isJust mshowedval] + Logger.log Logger.Debug $ "leaving " ++ msg ++ mconcat [": " ++ fromJust mshowedval | isJust mshowedval] pure val authorizeIdP :: diff --git a/services/spar/src/Spar/App.hs b/services/spar/src/Spar/App.hs index 52787fda3c2..84bad9dd1d2 100644 --- a/services/spar/src/Spar/App.hs +++ b/services/spar/src/Spar/App.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-} @@ -88,8 +87,6 @@ import Spar.Sem.GalleyAccess (GalleyAccess) import qualified Spar.Sem.GalleyAccess as GalleyAccess import Spar.Sem.IdPConfigStore (GetIdPResult (..), IdPConfigStore) import qualified Spar.Sem.IdPConfigStore as IdPConfigStore -import Spar.Sem.Logger (Logger) -import qualified Spar.Sem.Logger as Logger import Spar.Sem.Reporter (Reporter) import qualified Spar.Sem.Reporter as Reporter import Spar.Sem.SAMLUserStore (SAMLUserStore) @@ -108,6 +105,8 @@ import Wire.API.User.Identity (Email (..)) import Wire.API.User.IdentityProvider import Wire.API.User.Saml import Wire.API.User.Scim (ValidExternalId (..)) +import Wire.Sem.Logger (Logger) +import qualified Wire.Sem.Logger as Logger import Wire.Sem.Random (Random) import qualified Wire.Sem.Random as Random @@ -392,7 +391,7 @@ verdictHandler cky mbteam aresp verdict = do -- [3/4.1.4.2] -- [...] If the containing message is in response to an , then -- the InResponseTo attribute MUST match the request's ID. - Logger.log SAML.Debug $ "entering verdictHandler: " <> show (fromBindCookie <$> cky, aresp, verdict) + Logger.log Logger.Debug $ "entering verdictHandler: " <> show (fromBindCookie <$> cky, aresp, verdict) reqid <- either (throwSparSem . SparNoRequestRefInResponse . cs) pure $ SAML.rspInResponseTo aresp format :: Maybe VerdictFormat <- VerdictFormatStore.get reqid resp <- case format of @@ -403,7 +402,7 @@ verdictHandler cky mbteam aresp verdict = do Nothing -> -- (this shouldn't happen too often, see 'storeVerdictFormat') throwSparSem SparNoSuchRequest - Logger.log SAML.Debug $ "leaving verdictHandler: " <> show resp + Logger.log Logger.Debug $ "leaving verdictHandler: " <> show resp pure resp data VerdictHandlerResult @@ -432,9 +431,9 @@ verdictHandlerResult :: SAML.AccessVerdict -> Sem r VerdictHandlerResult verdictHandlerResult bindCky mbteam verdict = do - Logger.log SAML.Debug $ "entering verdictHandlerResult: " <> show (fromBindCookie <$> bindCky) + Logger.log Logger.Debug $ "entering verdictHandlerResult: " <> show (fromBindCookie <$> bindCky) result <- catchVerdictErrors $ verdictHandlerResultCore bindCky mbteam verdict - Logger.log SAML.Debug $ "leaving verdictHandlerResult" <> show result + Logger.log Logger.Debug $ "leaving verdictHandlerResult" <> show result pure result catchVerdictErrors :: @@ -549,7 +548,7 @@ verdictHandlerResultCore bindCky mbteam = \case (Just _, GetUserFound _, GetUserFound _) -> -- to see why, consider the condition on the call to 'findUserWithOldIssuer' above. error "impossible." - Logger.log SAML.Debug ("granting sso login for " <> show uid) + Logger.log Logger.Debug ("granting sso login for " <> show uid) cky <- BrigAccess.ssoLogin uid pure $ VerifyHandlerGranted cky uid diff --git a/services/spar/src/Spar/CanonicalInterpreter.hs b/services/spar/src/Spar/CanonicalInterpreter.hs index 8ccad0d0029..37c47365246 100644 --- a/services/spar/src/Spar/CanonicalInterpreter.hs +++ b/services/spar/src/Spar/CanonicalInterpreter.hs @@ -50,8 +50,6 @@ import Spar.Sem.IdPConfigStore (IdPConfigStore) import Spar.Sem.IdPConfigStore.Cassandra (idPToCassandra) import Spar.Sem.IdPRawMetadataStore (IdPRawMetadataStore) import Spar.Sem.IdPRawMetadataStore.Cassandra (idpRawMetadataStoreToCassandra) -import Spar.Sem.Logger (Logger) -import Spar.Sem.Logger.TinyLog (loggerToTinyLog, stringLoggerToTinyLog) import Spar.Sem.Reporter (Reporter) import Spar.Sem.Reporter.Wai (reporterToTinyLogWai) import Spar.Sem.SAML2 (SAML2) @@ -71,6 +69,8 @@ import Spar.Sem.VerdictFormatStore (VerdictFormatStore) import Spar.Sem.VerdictFormatStore.Cassandra (verdictFormatStoreToCassandra) import qualified System.Logger as TinyLog import Wire.API.User.Saml +import Wire.Sem.Logger (Logger) +import Wire.Sem.Logger.TinyLog (loggerToTinyLog, stringLoggerToTinyLog) import Wire.Sem.Now (Now) import Wire.Sem.Now.IO (nowToIO) import Wire.Sem.Random (Random) diff --git a/services/spar/src/Spar/Run.hs b/services/spar/src/Spar/Run.hs index 8087cf65107..d72fd2e241d 100644 --- a/services/spar/src/Spar/Run.hs +++ b/services/spar/src/Spar/Run.hs @@ -51,12 +51,12 @@ import Spar.App import qualified Spar.Data as Data import Spar.Data.Instances () import Spar.Orphans () -import Spar.Sem.Logger.TinyLog (toLevel) import System.Logger.Class (Logger) import qualified System.Logger.Extended as Log import Util.Options (casEndpoint, casFilterNodesByDatacentre, casKeyspace, epHost, epPort) import Wire.API.Routes.Version.Wai import Wire.API.User.Saml as Types +import Wire.Sem.Logger.TinyLog ---------------------------------------------------------------------- -- cassandra @@ -103,7 +103,7 @@ runServer sparCtxOpts = do mkApp :: Opts -> IO (Application, Env) mkApp sparCtxOpts = do - let logLevel = toLevel $ saml sparCtxOpts ^. SAML.cfgLogLevel + let logLevel = samlToLevel $ saml sparCtxOpts ^. SAML.cfgLogLevel sparCtxLogger <- Log.mkLogger logLevel (logNetStrings sparCtxOpts) (logFormat sparCtxOpts) sparCtxCas <- initCassandra sparCtxOpts sparCtxLogger sparCtxHttpManager <- newManager defaultManagerSettings diff --git a/services/spar/src/Spar/Scim.hs b/services/spar/src/Spar/Scim.hs index 29dde1daa63..313987866dc 100644 --- a/services/spar/src/Spar/Scim.hs +++ b/services/spar/src/Spar/Scim.hs @@ -1,6 +1,5 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedLists #-} -{-# LANGUAGE RecordWildCards #-} {-# OPTIONS_GHC -Wno-orphans #-} -- This file is part of the Wire Server implementation. @@ -83,7 +82,6 @@ import Spar.Scim.User import Spar.Sem.BrigAccess (BrigAccess) import Spar.Sem.GalleyAccess (GalleyAccess) import Spar.Sem.IdPConfigStore (IdPConfigStore) -import Spar.Sem.Logger (Logger) import Spar.Sem.Reporter (Reporter) import Spar.Sem.SAMLUserStore (SAMLUserStore) import Spar.Sem.ScimExternalIdStore (ScimExternalIdStore) @@ -100,6 +98,7 @@ import qualified Web.Scim.Server as Scim import Wire.API.Routes.Public.Spar import Wire.API.User.Saml (Opts) import Wire.API.User.Scim +import Wire.Sem.Logger (Logger) import Wire.Sem.Now (Now) import Wire.Sem.Random (Random) diff --git a/services/spar/src/Spar/Scim/User.hs b/services/spar/src/Spar/Scim/User.hs index 551f6c279f9..7e465d83593 100644 --- a/services/spar/src/Spar/Scim/User.hs +++ b/services/spar/src/Spar/Scim/User.hs @@ -75,8 +75,6 @@ import Spar.Sem.BrigAccess as BrigAccess import Spar.Sem.GalleyAccess (GalleyAccess) import Spar.Sem.IdPConfigStore (IdPConfigStore) import qualified Spar.Sem.IdPConfigStore as IdPConfigStore -import Spar.Sem.Logger (Logger) -import qualified Spar.Sem.Logger as Logger import Spar.Sem.SAMLUserStore (SAMLUserStore) import qualified Spar.Sem.SAMLUserStore as SAMLUserStore import Spar.Sem.ScimExternalIdStore (ScimExternalIdStore) @@ -104,6 +102,8 @@ import qualified Wire.API.User.RichInfo as RI import Wire.API.User.Saml (Opts, derivedOpts, derivedOptsScimBaseURI, richInfoLimit) import Wire.API.User.Scim (ScimTokenInfo (..)) import qualified Wire.API.User.Scim as ST +import Wire.Sem.Logger (Logger) +import qualified Wire.Sem.Logger as Logger import Wire.Sem.Now (Now) import qualified Wire.Sem.Now as Now import Wire.Sem.Random (Random) diff --git a/services/spar/src/Spar/Sem/BrigAccess/Http.hs b/services/spar/src/Spar/Sem/BrigAccess/Http.hs index 3f63bc1d600..a155aad3d78 100644 --- a/services/spar/src/Spar/Sem/BrigAccess/Http.hs +++ b/services/spar/src/Spar/Sem/BrigAccess/Http.hs @@ -27,9 +27,9 @@ import Polysemy.Error (Error) import Spar.Error (SparError) import qualified Spar.Intra.Brig as Intra import Spar.Sem.BrigAccess -import Spar.Sem.Logger (Logger) import Spar.Sem.Utils (RunHttpEnv (..), viaRunHttp) import qualified System.Logger as TinyLog +import Wire.Sem.Logger (Logger) brigAccessToHttp :: Members '[Logger (TinyLog.Msg -> TinyLog.Msg), Error SparError, Embed IO] r => diff --git a/services/spar/src/Spar/Sem/GalleyAccess/Http.hs b/services/spar/src/Spar/Sem/GalleyAccess/Http.hs index 34024e2e5a3..4b4d40576c2 100644 --- a/services/spar/src/Spar/Sem/GalleyAccess/Http.hs +++ b/services/spar/src/Spar/Sem/GalleyAccess/Http.hs @@ -29,9 +29,9 @@ import Polysemy.Error import Spar.Error (SparError) import qualified Spar.Intra.Galley as Intra import Spar.Sem.GalleyAccess -import Spar.Sem.Logger (Logger) import Spar.Sem.Utils import qualified System.Logger as TinyLog +import Wire.Sem.Logger (Logger) galleyAccessToHttp :: Members '[Logger (TinyLog.Msg -> TinyLog.Msg), Error SparError, Embed IO] r => diff --git a/services/spar/src/Spar/Sem/SAML2/Library.hs b/services/spar/src/Spar/Sem/SAML2/Library.hs index 176152b475f..fe7436ce482 100644 --- a/services/spar/src/Spar/Sem/SAML2/Library.hs +++ b/services/spar/src/Spar/Sem/SAML2/Library.hs @@ -40,11 +40,11 @@ import qualified Spar.Sem.AReqIDStore as AReqIDStore import Spar.Sem.AssIDStore (AssIDStore) import qualified Spar.Sem.AssIDStore as AssIDStore import Spar.Sem.IdPConfigStore (IdPConfigStore) -import Spar.Sem.Logger (Logger) -import qualified Spar.Sem.Logger as Logger import Spar.Sem.SAML2 import Wire.API.User.IdentityProvider (WireIdP) import Wire.API.User.Saml +import Wire.Sem.Logger (Logger) +import qualified Wire.Sem.Logger as Logger wrapMonadClientSPImpl :: Members '[Error SparError, Final IO] r => Sem r a -> SPImpl r a wrapMonadClientSPImpl action = @@ -69,7 +69,7 @@ instance Member (Input Opts) r => HasConfig (SPImpl r) where getConfig = SPImpl $ inputs saml instance Members '[Input Opts, Logger String] r => HasLogger (SPImpl r) where - logger lvl = SPImpl . Logger.log lvl + logger lvl = SPImpl . Logger.log (Logger.samlFromLevel lvl) instance Member (Embed IO) r => MonadIO (SPImpl r) where liftIO = SPImpl . embed @IO diff --git a/services/spar/src/Spar/Sem/Utils.hs b/services/spar/src/Spar/Sem/Utils.hs index b082e57142a..c7aba34aa8f 100644 --- a/services/spar/src/Spar/Sem/Utils.hs +++ b/services/spar/src/Spar/Sem/Utils.hs @@ -33,12 +33,11 @@ import Spar.Error import Spar.Intra.Brig (MonadSparToBrig (..)) import Spar.Intra.Galley (MonadSparToGalley) import qualified Spar.Intra.Galley as Intra -import Spar.Sem.Logger (Logger) -import qualified Spar.Sem.Logger as Logger -import Spar.Sem.Logger.TinyLog (fromLevel) import qualified System.Logger as TinyLog import qualified System.Logger.Class as TinyLog import Wire.API.User.Saml +import Wire.Sem.Logger (Logger) +import qualified Wire.Sem.Logger as Logger -- | Run an embedded Cassandra 'Client' in @Final IO@. interpretClientToIO :: @@ -91,7 +90,7 @@ viaRunHttp env m = do Right a -> pure a instance Member (Logger (TinyLog.Msg -> TinyLog.Msg)) r => TinyLog.MonadLogger (RunHttp r) where - log lvl msg = semToRunHttp $ Logger.log (fromLevel lvl) msg + log lvl msg = semToRunHttp $ Logger.log (Logger.fromLevel lvl) msg instance Members '[Logger (TinyLog.Msg -> TinyLog.Msg), Embed IO] r => MonadSparToGalley (RunHttp r) where call modreq = do diff --git a/services/spar/test-integration/Util/Core.hs b/services/spar/test-integration/Util/Core.hs index 151045517a1..22535c9dbaa 100644 --- a/services/spar/test-integration/Util/Core.hs +++ b/services/spar/test-integration/Util/Core.hs @@ -183,7 +183,6 @@ import Spar.CanonicalInterpreter import qualified Spar.Intra.BrigApp as Intra import qualified Spar.Options import Spar.Run -import Spar.Sem.Logger.TinyLog (toLevel) import qualified Spar.Sem.SAMLUserStore as SAMLUserStore import qualified Spar.Sem.ScimExternalIdStore as ScimExternalIdStore import qualified System.Logger.Extended as Log @@ -212,6 +211,7 @@ import Wire.API.User.Identity (mkSampleUref) import Wire.API.User.IdentityProvider import Wire.API.User.Saml import Wire.API.User.Scim (runValidExternalIdEither) +import Wire.Sem.Logger.TinyLog -- | Call 'mkEnv' with options from config files. mkEnvFromOptions :: IO TestEnv @@ -257,7 +257,7 @@ cliOptsParser = mkEnv :: HasCallStack => IntegrationConfig -> Opts -> IO TestEnv mkEnv _teTstOpts _teOpts = do _teMgr :: Manager <- newManager defaultManagerSettings - sparCtxLogger <- Log.mkLogger (toLevel $ saml _teOpts ^. SAML.cfgLogLevel) (logNetStrings _teOpts) (logFormat _teOpts) + sparCtxLogger <- Log.mkLogger (samlToLevel $ saml _teOpts ^. SAML.cfgLogLevel) (logNetStrings _teOpts) (logFormat _teOpts) _teCql :: ClientState <- initCassandra _teOpts sparCtxLogger let _teBrig = endpointToReq (cfgBrig _teTstOpts) _teGalley = endpointToReq (cfgGalley _teTstOpts)