Skip to content

Commit dc7b54a

Browse files
authored
Add option to collect logs inside ContractEnvironment. (#113)
* Add option to collect logs inside ContractEnvironment. Adds additional interpretetion for PrintLog effect, that saves the log inside TVar in ContractEnviroment. This is turned on/off by flag in PABConfig.
1 parent 405bfc9 commit dc7b54a

File tree

10 files changed

+60
-4
lines changed

10 files changed

+60
-4
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ Top-level configuration file fields:
126126
collectStats: `true` or `false`
127127
Save some stats during contract run (only transactions execution
128128
budgets supported atm) (default: false)
129+
collectLogs: `true` or `false`
130+
Save logs from contract execution: pab request logs and contract
131+
logs (default: false)
129132
budgetMultiplier: rational multiplier in form `1` or `1 % 2`
130133
(default: 1)
131134
```

examples/plutus-game/pabConfig.value

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ enableTxEndpoint: true
2929

3030
-- Save some stats during contract run (only transactions execution budgets supported atm)
3131
collectStats: false
32+
33+
-- Save logs from contract execution: pab request logs and contract logs
34+
collectLogs: false

examples/plutus-nft/pabConfig.value

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ enableTxEndpoint: true
2929

3030
-- Save some stats during contract run (only transactions execution budgets supported atm)
3131
collectStats: false
32+
33+
-- Save logs from contract execution: pab request logs and contract logs
34+
collectLogs: false

examples/plutus-transfer/pabConfig.value

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ enableTxEndpoint: true
2929

3030
-- Save some stats during contract run (only transactions execution budgets supported atm)
3131
collectStats: false
32+
33+
-- Save logs from contract execution: pab request logs and contract logs
34+
collectLogs: false

src/BotPlutusInterface/Config.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ instance ToValue PABConfig where
9696
pcPort
9797
pcEnableTxEndpoint
9898
pcCollectStats
99+
pcCollectLogs
99100
pcBudgetMultiplier
100101
) =
101102
Sections
@@ -118,6 +119,7 @@ instance ToValue PABConfig where
118119
, Section () "port" $ toValue pcPort
119120
, Section () "enableTxEndpoint" $ toValue pcEnableTxEndpoint
120121
, Section () "collectStats" $ toValue pcCollectStats
122+
, Section () "collectLogs" $ toValue pcCollectLogs
121123
, Section () "budgetMultiplier" $ toValue pcBudgetMultiplier
122124
]
123125
{- ORMOLU_ENABLE -}
@@ -209,6 +211,13 @@ pabConfigSpec = sectionsSpec "PABConfig" $ do
209211
trueOrFalseSpec
210212
"Save some stats during contract run (only transactions execution budgets supported atm)"
211213

214+
pcCollectLogs <-
215+
sectionWithDefault'
216+
(pcCollectLogs def)
217+
"collectLogs"
218+
trueOrFalseSpec
219+
"Save logs from contract execution: pab request logs and contract logs"
220+
212221
pcBudgetMultiplier <-
213222
sectionWithDefault'
214223
(pcBudgetMultiplier def)

src/BotPlutusInterface/Effects.hs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ import BotPlutusInterface.Types (
4040
ContractState (ContractState),
4141
LogContext (BpiLog, ContractLog),
4242
LogLevel (..),
43+
LogsList (LogsList),
4344
TxBudget,
4445
TxFile,
4546
addBudget,
4647
)
4748
import Cardano.Api (AsType, FileError (FileIOError), HasTextEnvelope, TextEnvelopeDescr, TextEnvelopeError)
4849
import Cardano.Api qualified
4950
import Control.Concurrent qualified as Concurrent
50-
import Control.Concurrent.STM (atomically, modifyTVar, modifyTVar')
51+
import Control.Concurrent.STM (TVar, atomically, modifyTVar, modifyTVar')
5152
import Control.Lens ((^.))
5253
import Control.Monad (void, when)
5354
import Control.Monad.Freer (Eff, LastMember, Member, interpretM, reinterpret, send, subsume, type (~>))
@@ -138,7 +139,12 @@ handlePABEffect contractEnv =
138139
case contractEnv.cePABConfig.pcCliLocation of
139140
Local -> Directory.createDirectoryIfMissing createParents filePath
140141
Remote ipAddr -> createDirectoryIfMissingRemote ipAddr createParents filePath
141-
PrintLog logCtx logLevel txt -> printLog' contractEnv.cePABConfig.pcLogLevel logCtx logLevel txt
142+
PrintLog logCtx logLevel txt ->
143+
let logMsg = prettyLog logCtx logLevel txt
144+
in do
145+
printLog' contractEnv.cePABConfig.pcLogLevel logCtx logLevel logMsg
146+
when contractEnv.cePABConfig.pcCollectLogs $
147+
collectLog contractEnv.ceContractLogs logCtx logLevel logMsg
142148
UpdateInstanceState s -> do
143149
atomically $
144150
modifyTVar contractEnv.ceContractState $
@@ -181,7 +187,15 @@ printLog' logLevelSetting msgCtx msgLogLvl msg =
181187
where
182188
target =
183189
Render.renderString . layoutPretty defaultLayoutOptions $
184-
pretty msgCtx <+> pretty msgLogLvl <+> msg
190+
prettyLog msgCtx msgLogLvl msg
191+
192+
prettyLog :: LogContext -> LogLevel -> PP.Doc () -> PP.Doc ()
193+
prettyLog msgCtx msgLogLvl msg = pretty msgCtx <+> pretty msgLogLvl <+> msg
194+
195+
collectLog :: TVar LogsList -> LogContext -> LogLevel -> PP.Doc () -> IO ()
196+
collectLog logs logCtx logLvl msg = atomically $ modifyTVar' logs appendLog
197+
where
198+
appendLog (LogsList ls) = LogsList $ (logCtx, logLvl, msg) : ls
185199

186200
-- | Reinterpret contract logs to be handled by PABEffect later down the line.
187201
handleContractLog :: forall w a effs. Member (PABEffect w) effs => Pretty a => Eff (LogMsg a ': effs) ~> Eff effs

src/BotPlutusInterface/Server.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ handleContract pabConf state@(AppState st) contract = liftIO $ do
273273
contractInstanceID <- liftIO $ ContractInstanceId <$> UUID.nextRandom
274274
contractState <- newTVarIO (ContractState Active mempty)
275275
contractStats <- newTVarIO mempty
276+
contractLogs <- newTVarIO mempty
276277

277278
atomically $ modifyTVar st (Map.insert contractInstanceID (SomeContractState contractState))
278279

@@ -282,6 +283,7 @@ handleContract pabConf state@(AppState st) contract = liftIO $ do
282283
, ceContractState = contractState
283284
, ceContractInstanceId = contractInstanceID
284285
, ceContractStats = contractStats
286+
, ceContractLogs = contractLogs
285287
}
286288
void $
287289
forkIO $ do

src/BotPlutusInterface/Types.hs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module BotPlutusInterface.Types (
2222
SpendBudgets,
2323
MintBudgets,
2424
ContractStats (..),
25+
LogsList (..),
2526
addBudget,
2627
) where
2728

@@ -54,6 +55,7 @@ import Plutus.PAB.Effects.Contract.Builtin (
5455
endpointsToSchemas,
5556
)
5657
import Prettyprinter (Pretty (pretty))
58+
import Prettyprinter qualified as PP
5759
import Servant.Client (BaseUrl (BaseUrl), Scheme (Http))
5860
import Wallet.Types (ContractInstanceId (..))
5961
import Prelude
@@ -82,7 +84,10 @@ data PABConfig = PABConfig
8284
, pcTipPollingInterval :: !Natural
8385
, pcPort :: !Port
8486
, pcEnableTxEndpoint :: !Bool
85-
, pcCollectStats :: !Bool
87+
, -- | Collect contract execution stats inside ContractEnvironment
88+
pcCollectStats :: !Bool
89+
, -- | Collect logs inside ContractEnvironment, doesn't depend on log level
90+
pcCollectLogs :: !Bool
8691
, pcBudgetMultiplier :: !Rational
8792
}
8893
deriving stock (Show, Eq)
@@ -144,11 +149,22 @@ newtype ContractStats = ContractStats
144149
instance Show (TVar ContractStats) where
145150
show _ = "<ContractStats>"
146151

152+
-- | List of string logs.
153+
newtype LogsList = LogsList
154+
{ getLogsList :: [(LogContext, LogLevel, PP.Doc ())]
155+
}
156+
deriving stock (Show)
157+
deriving newtype (Semigroup, Monoid)
158+
159+
instance Show (TVar LogsList) where
160+
show _ = "<ContractLogs>"
161+
147162
data ContractEnvironment w = ContractEnvironment
148163
{ cePABConfig :: PABConfig
149164
, ceContractInstanceId :: ContractInstanceId
150165
, ceContractState :: TVar (ContractState w)
151166
, ceContractStats :: TVar ContractStats
167+
, ceContractLogs :: TVar LogsList
152168
}
153169
deriving stock (Show)
154170

@@ -222,6 +238,7 @@ instance Default PABConfig where
222238
, pcPort = 9080
223239
, pcEnableTxEndpoint = False
224240
, pcCollectStats = False
241+
, pcCollectLogs = False
225242
, pcBudgetMultiplier = 1
226243
}
227244

test/Spec/BotPlutusInterface/Config.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,6 @@ pabConfigExample =
113113
, pcPort = 1021
114114
, pcEnableTxEndpoint = True
115115
, pcCollectStats = False
116+
, pcCollectLogs = False
116117
, pcBudgetMultiplier = 1
117118
}

test/Spec/MockContract.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ instance Monoid w => Default (ContractEnvironment w) where
255255
, ceContractInstanceId = ContractInstanceId UUID.nil
256256
, ceContractState = unsafePerformIO $ newTVarIO def
257257
, ceContractStats = unsafePerformIO $ newTVarIO mempty
258+
, ceContractLogs = unsafePerformIO $ newTVarIO mempty
258259
}
259260

260261
instance Monoid w => Default (ContractState w) where

0 commit comments

Comments
 (0)