@@ -9,32 +9,38 @@ import Hydra.Prelude qualified as P
9
9
10
10
import Conduit
11
11
import Control.Lens ((^?) )
12
+ import Control.Monad (foldM )
12
13
import Data.Aeson (eitherDecode' )
13
14
import Data.Aeson.Lens (key , _String )
14
15
import Data.ByteString.Lazy.Char8 qualified as C8
15
- import Data.Text qualified as T
16
16
import Data.Text.Encoding (encodeUtf8 )
17
- import GHC.Show (show )
18
17
import Hydra.Chain (ChainEvent (.. ))
19
- import Hydra.HeadLogic (Effect (.. ), Input (.. ), Outcome (.. ))
18
+ import Hydra.HeadLogic (Effect (.. ), Input (.. ), Outcome (.. ), StateChanged ( .. ) )
20
19
import Hydra.Logging (Envelope (.. ))
21
20
import Hydra.Logging.Messages (HydraLog (.. ))
22
21
import Hydra.Node (HydraNodeLog (.. ))
23
22
23
+ data InfoLine = InfoLine { header :: Text , line :: Text , color :: Text } deriving (Eq , Show )
24
+
24
25
data Decoded tx
25
- = DecodedHydraLog Text
26
+ = DecodedHydraLog { t :: UTCTime , n :: Text , info :: InfoLine }
26
27
| DropLog
27
- deriving (Eq )
28
+ deriving (Eq , Show )
28
29
29
- instance Show (Decoded tx ) where
30
- show (DecodedHydraLog txt) = T. unpack txt
31
- show DropLog = " "
30
+ instance Ord (Decoded tx ) where
31
+ compare DropLog DropLog = EQ
32
+ compare DropLog DecodedHydraLog {} = LT
33
+ compare DecodedHydraLog {} DropLog = GT
34
+ compare (DecodedHydraLog t1 _ _) (DecodedHydraLog t2 _ _) = compare t1 t2
32
35
33
36
main :: IO ()
34
- main = do
37
+ main = visualize [" ../devnet/alice-logs.txt" , " ../devnet/bob-logs.txt" ]
38
+
39
+ visualize :: [FilePath ] -> IO ()
40
+ visualize paths = do
35
41
decodedLines <-
36
42
runConduitRes $
37
- sourceFileBS " ../devnet/alice-logs.txt "
43
+ mapM_ sourceFileBS paths
38
44
.| linesUnboundedAsciiC
39
45
.| mapMC
40
46
( \ l ->
@@ -43,50 +49,75 @@ main = do
43
49
Just line ->
44
50
let envelope = fromStrict $ encodeUtf8 line
45
51
in case decodeAs envelope (undefined :: Envelope (HydraLog Tx )) of
46
- Left e -> P. error $ P. show e <> line
52
+ Left e -> P. error $ show e <> line
47
53
Right decoded ->
48
54
case decoded. message of
49
- NodeOptions opt -> pure $ DecodedHydraLog $ " NODE STARTING: \n " <> P. show opt
55
+ NodeOptions opt -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " NODE OPTIONS " ( show opt) green)
50
56
Node msg ->
51
57
case msg of
52
58
BeginInput {input} ->
53
59
case input of
54
60
ClientInput {clientInput} ->
55
- pure $ DecodedHydraLog $ " NODE LOG: \n " <> P. show clientInput
61
+ pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " CLIENT SENT " ( show clientInput) green)
56
62
NetworkInput {} -> pure DropLog
57
63
ChainInput {chainEvent} ->
58
64
case chainEvent of
59
- Observation {observedTx} -> pure $ DecodedHydraLog $ " OBESERVATION: " <> P. show observedTx
65
+ Observation {observedTx} -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " OBESERVATION" ( show observedTx) blue)
60
66
Rollback {} -> pure DropLog
61
67
Tick {} -> pure DropLog
62
68
PostTxError {postTxError} ->
63
- pure $ DecodedHydraLog $ " ERROR: " <> P. show postTxError
69
+ pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " ERROR" ( show postTxError) red)
64
70
EndInput {} -> pure DropLog
65
71
BeginEffect {effect} ->
66
72
case effect of
67
73
ClientEffect {} -> pure DropLog
68
- NetworkEffect {message} -> pure $ DecodedHydraLog $ P. show message
69
- OnChainEffect {postChainTx} -> pure $ DecodedHydraLog $ " POSTING: " <> P. show postChainTx
74
+ NetworkEffect {message} -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " NETWORK EFFECT " ( show message) green)
75
+ OnChainEffect {postChainTx} -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " POSTING" ( show postChainTx) blue)
70
76
EndEffect {} -> pure DropLog
71
77
LogicOutcome {outcome} ->
72
78
case outcome of
73
- Continue {} -> pure DropLog
79
+ Continue {stateChanges} ->
80
+ foldM
81
+ ( \ b a -> case a of
82
+ HeadOpened {} -> pure $ DecodedHydraLog decoded. timestamp decoded. namespace (InfoLine " HeadOpened" " " green)
83
+ _ -> pure b
84
+ )
85
+ DropLog
86
+ stateChanges
74
87
Wait {} -> pure DropLog
75
- Error {error = err} -> pure $ DecodedHydraLog $ " LOGIC ERROR: " <> P. show err
88
+ Error {error = err} -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " LOGIC ERROR" ( show err) red)
76
89
DroppedFromQueue {} -> pure DropLog
77
- LoadingState -> pure $ DecodedHydraLog " Loading state..."
78
- LoadedState {} -> pure $ DecodedHydraLog " Loaded."
79
- ReplayingState -> pure $ DecodedHydraLog " Replaying state..."
80
- Misconfiguration {} -> pure $ DecodedHydraLog " MISCONFIG!"
90
+ LoadingState -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " Loading state..." " " green)
91
+ LoadedState {} -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " Loaded." " " green)
92
+ ReplayingState -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " Replaying state..." " " green)
93
+ Misconfiguration {} -> pure $ DecodedHydraLog decoded . timestamp decoded . namespace ( InfoLine " MISCONFIG!" " " red)
81
94
_ -> pure DropLog
82
95
)
83
- .| filterC (\ a -> P. show a /= ( " " :: Text ) )
96
+ .| filterC (/= DropLog )
84
97
.| sinkList
85
- forM_ decodedLines $ \ l ->
86
- putTextLn ( P. show l)
98
+ forM_ (sort decodedLines) $ \ l ->
99
+ render l
87
100
88
101
decodeAs :: forall a . FromJSON a => C8. ByteString -> a -> Either String a
89
102
decodeAs l _ =
90
103
case eitherDecode' l :: Either String a of
91
104
Left e -> Left e
92
105
Right decoded -> pure decoded
106
+
107
+ render :: Decoded tx -> IO ()
108
+ render = \ case
109
+ DecodedHydraLog {t, n, info = InfoLine {header, line, color}} -> putTextLn $ color <> unlines [" [" <> show t <> " ]" , " NAMESPACE:" <> show n, header, line]
110
+ DropLog -> putTextLn " "
111
+
112
+ -- ANSI escape codes for colors
113
+ red :: Text
114
+ red = " \ESC [31m"
115
+
116
+ green :: Text
117
+ green = " \ESC [32m"
118
+
119
+ blue :: Text
120
+ blue = " \ESC [34m"
121
+
122
+ reset :: Text
123
+ reset = " \ESC [0m"
0 commit comments