/
RobotConsensusTracers.scala
124 lines (102 loc) · 4.08 KB
/
RobotConsensusTracers.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package io.iohk.metronome.examples.robot.app.tracing
import monix.eval.Task
import io.iohk.metronome.examples.robot.RobotAgreement
import io.iohk.metronome.hotstuff.service.tracing.{
ConsensusEvent,
ConsensusTracers
}
import io.iohk.metronome.tracer.Tracer
import io.iohk.metronome.logging.{HybridLog, HybridLogObject, LogTracer}
import io.circe.{Encoder, JsonObject}
import io.iohk.metronome.crypto.hash.Hash
import io.iohk.metronome.hotstuff.consensus.ViewNumber
import io.iohk.metronome.hotstuff.consensus.basic.VotingPhase
import io.iohk.metronome.crypto.ECPublicKey
object RobotConsensusTracers {
type RobotConsensusEvent = ConsensusEvent[RobotAgreement]
implicit val consensusEventHybridLog
: HybridLog[ConsensusEvent[RobotAgreement]] = {
import ConsensusEvent._
import io.circe.syntax._
implicit val viewNumberEncoder: Encoder[ViewNumber] =
Encoder[Long].contramap[ViewNumber](identity)
implicit val hashEncoder: Encoder[Hash] =
Encoder[String].contramap[Hash](_.toHex)
implicit val phaseEncoder: Encoder[VotingPhase] =
Encoder[String].contramap[VotingPhase](_.toString)
implicit val publicKeyEncoder: Encoder[ECPublicKey] =
Encoder[String].contramap[ECPublicKey](_.bytes.toHex)
HybridLog.instance[RobotConsensusEvent](
level = {
case e: Error if e.message.contains("SendMessage") =>
HybridLogObject.Level.Debug
case _: Error => HybridLogObject.Level.Error
case _: Timeout => HybridLogObject.Level.Warn
case _: Rejected[_] => HybridLogObject.Level.Warn
case _: ViewSync => HybridLogObject.Level.Info
case _: AdoptView[_] => HybridLogObject.Level.Info
case _ => HybridLogObject.Level.Debug
},
message = _.getClass.getSimpleName,
event = {
case e: Timeout =>
JsonObject("viewNumber" -> e.viewNumber.asJson)
case e: ViewSync =>
JsonObject("viewNumber" -> e.viewNumber.asJson)
case e: AdoptView[_] =>
JsonObject(
"viewNumber" -> e.status.viewNumber.asJson,
"blockHash" -> e.status.commitQC.blockHash.asJson
)
case e: NewView =>
JsonObject("viewNumber" -> e.viewNumber.asJson)
case e: Quorum[_] =>
JsonObject(
"viewNumber" -> e.quorumCertificate.viewNumber.asJson,
"phase" -> e.quorumCertificate.phase.asJson,
"blockHash" -> e.quorumCertificate.blockHash.asJson
)
case e: FromPast[_] =>
JsonObject(
"viewNumber" -> e.message.message.viewNumber.asJson,
"messageType" -> e.message.message.getClass.getSimpleName.asJson,
"sender" -> e.message.sender.asJson
)
case e: FromFuture[_] =>
JsonObject(
"viewNumber" -> e.message.message.viewNumber.asJson,
"messageType" -> e.message.message.getClass.getSimpleName.asJson,
"sender" -> e.message.sender.asJson
)
case e: Stashed[_] =>
JsonObject(
"viewNumber" -> e.error.event.message.viewNumber.asJson,
"messageType" -> e.error.event.message.getClass.getSimpleName.asJson,
"sender" -> e.error.event.sender.asJson
)
case e: Rejected[_] =>
JsonObject(
"errorType" -> e.error.getClass.getSimpleName.asJson,
"error" -> e.error.toString.asJson
)
case e: ExecutionSkipped[_] =>
JsonObject(
"blockHash" -> e.blockHash.asJson
)
case e: BlockExecuted[_] =>
JsonObject(
"blockHash" -> e.blockHash.asJson
)
case e: Error =>
JsonObject(
"message" -> e.message.asJson,
"error" -> e.error.getMessage.asJson
)
}
)
}
implicit val consensusEventTracer: Tracer[Task, RobotConsensusEvent] =
LogTracer.hybrid[Task, RobotConsensusEvent]
implicit val consensusTracers: ConsensusTracers[Task, RobotAgreement] =
ConsensusTracers(consensusEventTracer)
}