add tracing and qlogging of state transitions for ECN validation

This commit is contained in:
Marten Seemann
2023-09-01 14:17:59 +07:00
parent ad63e2a40a
commit ffe6546833
11 changed files with 174 additions and 13 deletions

View File

@@ -524,6 +524,20 @@ func (e eventCongestionStateUpdated) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("new", e.state.String())
}
type eventECNStateUpdated struct {
state logging.ECNState
trigger logging.ECNStateTrigger
}
func (e eventECNStateUpdated) Category() category { return categoryRecovery }
func (e eventECNStateUpdated) Name() string { return "ecn_state_updated" }
func (e eventECNStateUpdated) IsNil() bool { return false }
func (e eventECNStateUpdated) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("new", ecnState(e.state).String())
enc.StringKeyOmitEmpty("trigger", ecnStateTrigger(e.trigger).String())
}
type eventGeneric struct {
name string
msg string

View File

@@ -503,6 +503,12 @@ func (t *connectionTracer) LossTimerCanceled() {
t.mutex.Unlock()
}
func (t *connectionTracer) ECNStateUpdated(state logging.ECNState, trigger logging.ECNStateTrigger) {
t.mutex.Lock()
t.recordEvent(time.Now(), &eventECNStateUpdated{state: state, trigger: trigger})
t.mutex.Unlock()
}
func (t *connectionTracer) Debug(name, msg string) {
t.mutex.Lock()
t.recordEvent(time.Now(), &eventGeneric{

View File

@@ -865,6 +865,27 @@ var _ = Describe("Tracing", func() {
Expect(ev).To(HaveKeyWithValue("event_type", "cancelled"))
})
It("records an ECN state transition, without a trigger", func() {
tracer.ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)
entry := exportAndParseSingle()
Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond)))
Expect(entry.Name).To(Equal("recovery:ecn_state_updated"))
ev := entry.Event
Expect(ev).To(HaveLen(1))
Expect(ev).To(HaveKeyWithValue("new", "unknown"))
})
It("records an ECN state transition, with a trigger", func() {
tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts)
entry := exportAndParseSingle()
Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond)))
Expect(entry.Name).To(Equal("recovery:ecn_state_updated"))
ev := entry.Event
Expect(ev).To(HaveLen(2))
Expect(ev).To(HaveKeyWithValue("new", "failed"))
Expect(ev).To(HaveKeyWithValue("trigger", "ACK doesn't contain ECN marks"))
})
It("records a generic event", func() {
tracer.Debug("foo", "bar")
entry := exportAndParseSingle()

View File

@@ -330,3 +330,41 @@ func (e ecn) String() string {
return "unknown ECN"
}
}
type ecnState logging.ECNState
func (e ecnState) String() string {
switch logging.ECNState(e) {
case logging.ECNStateTesting:
return "testing"
case logging.ECNStateUnknown:
return "unknown"
case logging.ECNStateCapable:
return "capable"
case logging.ECNStateFailed:
return "failed"
default:
return "unknown ECN state"
}
}
type ecnStateTrigger logging.ECNStateTrigger
func (e ecnStateTrigger) String() string {
switch logging.ECNStateTrigger(e) {
case logging.ECNTriggerNoTrigger:
return ""
case logging.ECNFailedNoECNCounts:
return "ACK doesn't contain ECN marks"
case logging.ECNFailedDecreasedECNCounts:
return "ACK decreases ECN counts"
case logging.ECNFailedLostAllTestingPackets:
return "all ECN testing packets declared lost"
case logging.ECNFailedMoreECNCountsThanSent:
return "ACK contains more ECN counts than ECN-marked packets sent"
case logging.ECNFailedTooFewECNCounts:
return "ACK contains fewer new ECN counts than acknowledged ECN-marked packets"
default:
return "unknown ECN state trigger"
}
}

View File

@@ -135,4 +135,22 @@ var _ = Describe("Types", func() {
Expect(ecn(logging.ECTNot).String()).To(Equal("Not-ECT"))
Expect(ecn(42).String()).To(Equal("unknown ECN"))
})
It("has a string representation for the ECN state", func() {
Expect(ecnState(logging.ECNStateTesting).String()).To(Equal("testing"))
Expect(ecnState(logging.ECNStateUnknown).String()).To(Equal("unknown"))
Expect(ecnState(logging.ECNStateFailed).String()).To(Equal("failed"))
Expect(ecnState(logging.ECNStateCapable).String()).To(Equal("capable"))
Expect(ecnState(42).String()).To(Equal("unknown ECN state"))
})
It("has a string representation for the ECN state trigger", func() {
Expect(ecnStateTrigger(logging.ECNTriggerNoTrigger).String()).To(Equal(""))
Expect(ecnStateTrigger(logging.ECNFailedNoECNCounts).String()).To(Equal("ACK doesn't contain ECN marks"))
Expect(ecnStateTrigger(logging.ECNFailedDecreasedECNCounts).String()).To(Equal("ACK decreases ECN counts"))
Expect(ecnStateTrigger(logging.ECNFailedLostAllTestingPackets).String()).To(Equal("all ECN testing packets declared lost"))
Expect(ecnStateTrigger(logging.ECNFailedMoreECNCountsThanSent).String()).To(Equal("ACK contains more ECN counts than ECN-marked packets sent"))
Expect(ecnStateTrigger(logging.ECNFailedTooFewECNCounts).String()).To(Equal("ACK contains fewer new ECN counts than acknowledged ECN-marked packets"))
Expect(ecnStateTrigger(42).String()).To(Equal("unknown ECN state trigger"))
})
})