github.com/daeuniverse/quic-go@v0.0.0-20240413031024-943f218e0810/qlog/event.go (about)

     1  package qlog
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net"
     7  	"net/netip"
     8  	"time"
     9  
    10  	"github.com/daeuniverse/quic-go"
    11  	"github.com/daeuniverse/quic-go/internal/protocol"
    12  	"github.com/daeuniverse/quic-go/internal/utils"
    13  	"github.com/daeuniverse/quic-go/logging"
    14  
    15  	"github.com/francoispqt/gojay"
    16  )
    17  
    18  func milliseconds(dur time.Duration) float64 { return float64(dur.Nanoseconds()) / 1e6 }
    19  
    20  type eventDetails interface {
    21  	Category() category
    22  	Name() string
    23  	gojay.MarshalerJSONObject
    24  }
    25  
    26  type event struct {
    27  	RelativeTime time.Duration
    28  	eventDetails
    29  }
    30  
    31  var _ gojay.MarshalerJSONObject = event{}
    32  
    33  func (e event) IsNil() bool { return false }
    34  func (e event) MarshalJSONObject(enc *gojay.Encoder) {
    35  	enc.Float64Key("time", milliseconds(e.RelativeTime))
    36  	enc.StringKey("name", e.Category().String()+":"+e.Name())
    37  	enc.ObjectKey("data", e.eventDetails)
    38  }
    39  
    40  type versions []versionNumber
    41  
    42  func (v versions) IsNil() bool { return false }
    43  func (v versions) MarshalJSONArray(enc *gojay.Encoder) {
    44  	for _, e := range v {
    45  		enc.AddString(e.String())
    46  	}
    47  }
    48  
    49  type rawInfo struct {
    50  	Length        logging.ByteCount // full packet length, including header and AEAD authentication tag
    51  	PayloadLength logging.ByteCount // length of the packet payload, excluding AEAD tag
    52  }
    53  
    54  func (i rawInfo) IsNil() bool { return false }
    55  func (i rawInfo) MarshalJSONObject(enc *gojay.Encoder) {
    56  	enc.Uint64Key("length", uint64(i.Length))
    57  	enc.Uint64KeyOmitEmpty("payload_length", uint64(i.PayloadLength))
    58  }
    59  
    60  type eventConnectionStarted struct {
    61  	SrcAddr  *net.UDPAddr
    62  	DestAddr *net.UDPAddr
    63  
    64  	SrcConnectionID  protocol.ConnectionID
    65  	DestConnectionID protocol.ConnectionID
    66  }
    67  
    68  var _ eventDetails = &eventConnectionStarted{}
    69  
    70  func (e eventConnectionStarted) Category() category { return categoryTransport }
    71  func (e eventConnectionStarted) Name() string       { return "connection_started" }
    72  func (e eventConnectionStarted) IsNil() bool        { return false }
    73  
    74  func (e eventConnectionStarted) MarshalJSONObject(enc *gojay.Encoder) {
    75  	if utils.IsIPv4(e.SrcAddr.IP) {
    76  		enc.StringKey("ip_version", "ipv4")
    77  	} else {
    78  		enc.StringKey("ip_version", "ipv6")
    79  	}
    80  	enc.StringKey("src_ip", e.SrcAddr.IP.String())
    81  	enc.IntKey("src_port", e.SrcAddr.Port)
    82  	enc.StringKey("dst_ip", e.DestAddr.IP.String())
    83  	enc.IntKey("dst_port", e.DestAddr.Port)
    84  	enc.StringKey("src_cid", e.SrcConnectionID.String())
    85  	enc.StringKey("dst_cid", e.DestConnectionID.String())
    86  }
    87  
    88  type eventVersionNegotiated struct {
    89  	clientVersions, serverVersions []versionNumber
    90  	chosenVersion                  versionNumber
    91  }
    92  
    93  func (e eventVersionNegotiated) Category() category { return categoryTransport }
    94  func (e eventVersionNegotiated) Name() string       { return "version_information" }
    95  func (e eventVersionNegotiated) IsNil() bool        { return false }
    96  
    97  func (e eventVersionNegotiated) MarshalJSONObject(enc *gojay.Encoder) {
    98  	if len(e.clientVersions) > 0 {
    99  		enc.ArrayKey("client_versions", versions(e.clientVersions))
   100  	}
   101  	if len(e.serverVersions) > 0 {
   102  		enc.ArrayKey("server_versions", versions(e.serverVersions))
   103  	}
   104  	enc.StringKey("chosen_version", e.chosenVersion.String())
   105  }
   106  
   107  type eventConnectionClosed struct {
   108  	e error
   109  }
   110  
   111  func (e eventConnectionClosed) Category() category { return categoryTransport }
   112  func (e eventConnectionClosed) Name() string       { return "connection_closed" }
   113  func (e eventConnectionClosed) IsNil() bool        { return false }
   114  
   115  func (e eventConnectionClosed) MarshalJSONObject(enc *gojay.Encoder) {
   116  	var (
   117  		statelessResetErr     *quic.StatelessResetError
   118  		handshakeTimeoutErr   *quic.HandshakeTimeoutError
   119  		idleTimeoutErr        *quic.IdleTimeoutError
   120  		applicationErr        *quic.ApplicationError
   121  		transportErr          *quic.TransportError
   122  		versionNegotiationErr *quic.VersionNegotiationError
   123  	)
   124  	switch {
   125  	case errors.As(e.e, &statelessResetErr):
   126  		enc.StringKey("owner", ownerRemote.String())
   127  		enc.StringKey("trigger", "stateless_reset")
   128  		enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", statelessResetErr.Token))
   129  	case errors.As(e.e, &handshakeTimeoutErr):
   130  		enc.StringKey("owner", ownerLocal.String())
   131  		enc.StringKey("trigger", "handshake_timeout")
   132  	case errors.As(e.e, &idleTimeoutErr):
   133  		enc.StringKey("owner", ownerLocal.String())
   134  		enc.StringKey("trigger", "idle_timeout")
   135  	case errors.As(e.e, &applicationErr):
   136  		owner := ownerLocal
   137  		if applicationErr.Remote {
   138  			owner = ownerRemote
   139  		}
   140  		enc.StringKey("owner", owner.String())
   141  		enc.Uint64Key("application_code", uint64(applicationErr.ErrorCode))
   142  		enc.StringKey("reason", applicationErr.ErrorMessage)
   143  	case errors.As(e.e, &transportErr):
   144  		owner := ownerLocal
   145  		if transportErr.Remote {
   146  			owner = ownerRemote
   147  		}
   148  		enc.StringKey("owner", owner.String())
   149  		enc.StringKey("connection_code", transportError(transportErr.ErrorCode).String())
   150  		enc.StringKey("reason", transportErr.ErrorMessage)
   151  	case errors.As(e.e, &versionNegotiationErr):
   152  		enc.StringKey("trigger", "version_mismatch")
   153  	}
   154  }
   155  
   156  type eventPacketSent struct {
   157  	Header        gojay.MarshalerJSONObject // either a shortHeader or a packetHeader
   158  	Length        logging.ByteCount
   159  	PayloadLength logging.ByteCount
   160  	Frames        frames
   161  	IsCoalesced   bool
   162  	ECN           logging.ECN
   163  	Trigger       string
   164  }
   165  
   166  var _ eventDetails = eventPacketSent{}
   167  
   168  func (e eventPacketSent) Category() category { return categoryTransport }
   169  func (e eventPacketSent) Name() string       { return "packet_sent" }
   170  func (e eventPacketSent) IsNil() bool        { return false }
   171  
   172  func (e eventPacketSent) MarshalJSONObject(enc *gojay.Encoder) {
   173  	enc.ObjectKey("header", e.Header)
   174  	enc.ObjectKey("raw", rawInfo{Length: e.Length, PayloadLength: e.PayloadLength})
   175  	enc.ArrayKeyOmitEmpty("frames", e.Frames)
   176  	enc.BoolKeyOmitEmpty("is_coalesced", e.IsCoalesced)
   177  	if e.ECN != logging.ECNUnsupported {
   178  		enc.StringKey("ecn", ecn(e.ECN).String())
   179  	}
   180  	enc.StringKeyOmitEmpty("trigger", e.Trigger)
   181  }
   182  
   183  type eventPacketReceived struct {
   184  	Header        gojay.MarshalerJSONObject // either a shortHeader or a packetHeader
   185  	Length        logging.ByteCount
   186  	PayloadLength logging.ByteCount
   187  	Frames        frames
   188  	ECN           logging.ECN
   189  	IsCoalesced   bool
   190  	Trigger       string
   191  }
   192  
   193  var _ eventDetails = eventPacketReceived{}
   194  
   195  func (e eventPacketReceived) Category() category { return categoryTransport }
   196  func (e eventPacketReceived) Name() string       { return "packet_received" }
   197  func (e eventPacketReceived) IsNil() bool        { return false }
   198  
   199  func (e eventPacketReceived) MarshalJSONObject(enc *gojay.Encoder) {
   200  	enc.ObjectKey("header", e.Header)
   201  	enc.ObjectKey("raw", rawInfo{Length: e.Length, PayloadLength: e.PayloadLength})
   202  	enc.ArrayKeyOmitEmpty("frames", e.Frames)
   203  	enc.BoolKeyOmitEmpty("is_coalesced", e.IsCoalesced)
   204  	if e.ECN != logging.ECNUnsupported {
   205  		enc.StringKey("ecn", ecn(e.ECN).String())
   206  	}
   207  	enc.StringKeyOmitEmpty("trigger", e.Trigger)
   208  }
   209  
   210  type eventRetryReceived struct {
   211  	Header packetHeader
   212  }
   213  
   214  func (e eventRetryReceived) Category() category { return categoryTransport }
   215  func (e eventRetryReceived) Name() string       { return "packet_received" }
   216  func (e eventRetryReceived) IsNil() bool        { return false }
   217  
   218  func (e eventRetryReceived) MarshalJSONObject(enc *gojay.Encoder) {
   219  	enc.ObjectKey("header", e.Header)
   220  }
   221  
   222  type eventVersionNegotiationReceived struct {
   223  	Header            packetHeaderVersionNegotiation
   224  	SupportedVersions []versionNumber
   225  }
   226  
   227  func (e eventVersionNegotiationReceived) Category() category { return categoryTransport }
   228  func (e eventVersionNegotiationReceived) Name() string       { return "packet_received" }
   229  func (e eventVersionNegotiationReceived) IsNil() bool        { return false }
   230  
   231  func (e eventVersionNegotiationReceived) MarshalJSONObject(enc *gojay.Encoder) {
   232  	enc.ObjectKey("header", e.Header)
   233  	enc.ArrayKey("supported_versions", versions(e.SupportedVersions))
   234  }
   235  
   236  type eventVersionNegotiationSent struct {
   237  	Header            packetHeaderVersionNegotiation
   238  	SupportedVersions []versionNumber
   239  }
   240  
   241  func (e eventVersionNegotiationSent) Category() category { return categoryTransport }
   242  func (e eventVersionNegotiationSent) Name() string       { return "packet_sent" }
   243  func (e eventVersionNegotiationSent) IsNil() bool        { return false }
   244  
   245  func (e eventVersionNegotiationSent) MarshalJSONObject(enc *gojay.Encoder) {
   246  	enc.ObjectKey("header", e.Header)
   247  	enc.ArrayKey("supported_versions", versions(e.SupportedVersions))
   248  }
   249  
   250  type eventPacketBuffered struct {
   251  	PacketType logging.PacketType
   252  	PacketSize protocol.ByteCount
   253  }
   254  
   255  func (e eventPacketBuffered) Category() category { return categoryTransport }
   256  func (e eventPacketBuffered) Name() string       { return "packet_buffered" }
   257  func (e eventPacketBuffered) IsNil() bool        { return false }
   258  
   259  func (e eventPacketBuffered) MarshalJSONObject(enc *gojay.Encoder) {
   260  	//nolint:gosimple
   261  	enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType, PacketNumber: protocol.InvalidPacketNumber})
   262  	enc.ObjectKey("raw", rawInfo{Length: e.PacketSize})
   263  	enc.StringKey("trigger", "keys_unavailable")
   264  }
   265  
   266  type eventPacketDropped struct {
   267  	PacketType   logging.PacketType
   268  	PacketSize   protocol.ByteCount
   269  	PacketNumber logging.PacketNumber
   270  	Trigger      packetDropReason
   271  }
   272  
   273  func (e eventPacketDropped) Category() category { return categoryTransport }
   274  func (e eventPacketDropped) Name() string       { return "packet_dropped" }
   275  func (e eventPacketDropped) IsNil() bool        { return false }
   276  
   277  func (e eventPacketDropped) MarshalJSONObject(enc *gojay.Encoder) {
   278  	enc.ObjectKey("header", packetHeaderWithType{
   279  		PacketType:   e.PacketType,
   280  		PacketNumber: e.PacketNumber,
   281  	})
   282  	enc.ObjectKey("raw", rawInfo{Length: e.PacketSize})
   283  	enc.StringKey("trigger", e.Trigger.String())
   284  }
   285  
   286  type metrics struct {
   287  	MinRTT      time.Duration
   288  	SmoothedRTT time.Duration
   289  	LatestRTT   time.Duration
   290  	RTTVariance time.Duration
   291  
   292  	CongestionWindow protocol.ByteCount
   293  	BytesInFlight    protocol.ByteCount
   294  	PacketsInFlight  int
   295  }
   296  
   297  type eventMetricsUpdated struct {
   298  	Last    *metrics
   299  	Current *metrics
   300  }
   301  
   302  func (e eventMetricsUpdated) Category() category { return categoryRecovery }
   303  func (e eventMetricsUpdated) Name() string       { return "metrics_updated" }
   304  func (e eventMetricsUpdated) IsNil() bool        { return false }
   305  
   306  func (e eventMetricsUpdated) MarshalJSONObject(enc *gojay.Encoder) {
   307  	if e.Last == nil || e.Last.MinRTT != e.Current.MinRTT {
   308  		enc.FloatKey("min_rtt", milliseconds(e.Current.MinRTT))
   309  	}
   310  	if e.Last == nil || e.Last.SmoothedRTT != e.Current.SmoothedRTT {
   311  		enc.FloatKey("smoothed_rtt", milliseconds(e.Current.SmoothedRTT))
   312  	}
   313  	if e.Last == nil || e.Last.LatestRTT != e.Current.LatestRTT {
   314  		enc.FloatKey("latest_rtt", milliseconds(e.Current.LatestRTT))
   315  	}
   316  	if e.Last == nil || e.Last.RTTVariance != e.Current.RTTVariance {
   317  		enc.FloatKey("rtt_variance", milliseconds(e.Current.RTTVariance))
   318  	}
   319  
   320  	if e.Last == nil || e.Last.CongestionWindow != e.Current.CongestionWindow {
   321  		enc.Uint64Key("congestion_window", uint64(e.Current.CongestionWindow))
   322  	}
   323  	if e.Last == nil || e.Last.BytesInFlight != e.Current.BytesInFlight {
   324  		enc.Uint64Key("bytes_in_flight", uint64(e.Current.BytesInFlight))
   325  	}
   326  	if e.Last == nil || e.Last.PacketsInFlight != e.Current.PacketsInFlight {
   327  		enc.Uint64KeyOmitEmpty("packets_in_flight", uint64(e.Current.PacketsInFlight))
   328  	}
   329  }
   330  
   331  type eventUpdatedPTO struct {
   332  	Value uint32
   333  }
   334  
   335  func (e eventUpdatedPTO) Category() category { return categoryRecovery }
   336  func (e eventUpdatedPTO) Name() string       { return "metrics_updated" }
   337  func (e eventUpdatedPTO) IsNil() bool        { return false }
   338  
   339  func (e eventUpdatedPTO) MarshalJSONObject(enc *gojay.Encoder) {
   340  	enc.Uint32Key("pto_count", e.Value)
   341  }
   342  
   343  type eventPacketLost struct {
   344  	PacketType   logging.PacketType
   345  	PacketNumber protocol.PacketNumber
   346  	Trigger      packetLossReason
   347  }
   348  
   349  func (e eventPacketLost) Category() category { return categoryRecovery }
   350  func (e eventPacketLost) Name() string       { return "packet_lost" }
   351  func (e eventPacketLost) IsNil() bool        { return false }
   352  
   353  func (e eventPacketLost) MarshalJSONObject(enc *gojay.Encoder) {
   354  	enc.ObjectKey("header", packetHeaderWithTypeAndPacketNumber{
   355  		PacketType:   e.PacketType,
   356  		PacketNumber: e.PacketNumber,
   357  	})
   358  	enc.StringKey("trigger", e.Trigger.String())
   359  }
   360  
   361  type eventKeyUpdated struct {
   362  	Trigger  keyUpdateTrigger
   363  	KeyType  keyType
   364  	KeyPhase protocol.KeyPhase
   365  	// we don't log the keys here, so we don't need `old` and `new`.
   366  }
   367  
   368  func (e eventKeyUpdated) Category() category { return categorySecurity }
   369  func (e eventKeyUpdated) Name() string       { return "key_updated" }
   370  func (e eventKeyUpdated) IsNil() bool        { return false }
   371  
   372  func (e eventKeyUpdated) MarshalJSONObject(enc *gojay.Encoder) {
   373  	enc.StringKey("trigger", e.Trigger.String())
   374  	enc.StringKey("key_type", e.KeyType.String())
   375  	if e.KeyType == keyTypeClient1RTT || e.KeyType == keyTypeServer1RTT {
   376  		enc.Uint64Key("key_phase", uint64(e.KeyPhase))
   377  	}
   378  }
   379  
   380  type eventKeyDiscarded struct {
   381  	KeyType  keyType
   382  	KeyPhase protocol.KeyPhase
   383  }
   384  
   385  func (e eventKeyDiscarded) Category() category { return categorySecurity }
   386  func (e eventKeyDiscarded) Name() string       { return "key_discarded" }
   387  func (e eventKeyDiscarded) IsNil() bool        { return false }
   388  
   389  func (e eventKeyDiscarded) MarshalJSONObject(enc *gojay.Encoder) {
   390  	if e.KeyType != keyTypeClient1RTT && e.KeyType != keyTypeServer1RTT {
   391  		enc.StringKey("trigger", "tls")
   392  	}
   393  	enc.StringKey("key_type", e.KeyType.String())
   394  	if e.KeyType == keyTypeClient1RTT || e.KeyType == keyTypeServer1RTT {
   395  		enc.Uint64Key("key_phase", uint64(e.KeyPhase))
   396  	}
   397  }
   398  
   399  type eventTransportParameters struct {
   400  	Restore bool
   401  	Owner   owner
   402  	SentBy  protocol.Perspective
   403  
   404  	OriginalDestinationConnectionID protocol.ConnectionID
   405  	InitialSourceConnectionID       protocol.ConnectionID
   406  	RetrySourceConnectionID         *protocol.ConnectionID
   407  
   408  	StatelessResetToken     *protocol.StatelessResetToken
   409  	DisableActiveMigration  bool
   410  	MaxIdleTimeout          time.Duration
   411  	MaxUDPPayloadSize       protocol.ByteCount
   412  	AckDelayExponent        uint8
   413  	MaxAckDelay             time.Duration
   414  	ActiveConnectionIDLimit uint64
   415  
   416  	InitialMaxData                 protocol.ByteCount
   417  	InitialMaxStreamDataBidiLocal  protocol.ByteCount
   418  	InitialMaxStreamDataBidiRemote protocol.ByteCount
   419  	InitialMaxStreamDataUni        protocol.ByteCount
   420  	InitialMaxStreamsBidi          int64
   421  	InitialMaxStreamsUni           int64
   422  
   423  	PreferredAddress *preferredAddress
   424  
   425  	MaxDatagramFrameSize protocol.ByteCount
   426  }
   427  
   428  func (e eventTransportParameters) Category() category { return categoryTransport }
   429  func (e eventTransportParameters) Name() string {
   430  	if e.Restore {
   431  		return "parameters_restored"
   432  	}
   433  	return "parameters_set"
   434  }
   435  func (e eventTransportParameters) IsNil() bool { return false }
   436  
   437  func (e eventTransportParameters) MarshalJSONObject(enc *gojay.Encoder) {
   438  	if !e.Restore {
   439  		enc.StringKey("owner", e.Owner.String())
   440  		if e.SentBy == protocol.PerspectiveServer {
   441  			enc.StringKey("original_destination_connection_id", e.OriginalDestinationConnectionID.String())
   442  			if e.StatelessResetToken != nil {
   443  				enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", e.StatelessResetToken[:]))
   444  			}
   445  			if e.RetrySourceConnectionID != nil {
   446  				enc.StringKey("retry_source_connection_id", (*e.RetrySourceConnectionID).String())
   447  			}
   448  		}
   449  		enc.StringKey("initial_source_connection_id", e.InitialSourceConnectionID.String())
   450  	}
   451  	enc.BoolKey("disable_active_migration", e.DisableActiveMigration)
   452  	enc.FloatKeyOmitEmpty("max_idle_timeout", milliseconds(e.MaxIdleTimeout))
   453  	enc.Int64KeyNullEmpty("max_udp_payload_size", int64(e.MaxUDPPayloadSize))
   454  	enc.Uint8KeyOmitEmpty("ack_delay_exponent", e.AckDelayExponent)
   455  	enc.FloatKeyOmitEmpty("max_ack_delay", milliseconds(e.MaxAckDelay))
   456  	enc.Uint64KeyOmitEmpty("active_connection_id_limit", e.ActiveConnectionIDLimit)
   457  
   458  	enc.Int64KeyOmitEmpty("initial_max_data", int64(e.InitialMaxData))
   459  	enc.Int64KeyOmitEmpty("initial_max_stream_data_bidi_local", int64(e.InitialMaxStreamDataBidiLocal))
   460  	enc.Int64KeyOmitEmpty("initial_max_stream_data_bidi_remote", int64(e.InitialMaxStreamDataBidiRemote))
   461  	enc.Int64KeyOmitEmpty("initial_max_stream_data_uni", int64(e.InitialMaxStreamDataUni))
   462  	enc.Int64KeyOmitEmpty("initial_max_streams_bidi", e.InitialMaxStreamsBidi)
   463  	enc.Int64KeyOmitEmpty("initial_max_streams_uni", e.InitialMaxStreamsUni)
   464  
   465  	if e.PreferredAddress != nil {
   466  		enc.ObjectKey("preferred_address", e.PreferredAddress)
   467  	}
   468  	if e.MaxDatagramFrameSize != protocol.InvalidByteCount {
   469  		enc.Int64Key("max_datagram_frame_size", int64(e.MaxDatagramFrameSize))
   470  	}
   471  }
   472  
   473  type preferredAddress struct {
   474  	IPv4, IPv6          netip.AddrPort
   475  	ConnectionID        protocol.ConnectionID
   476  	StatelessResetToken protocol.StatelessResetToken
   477  }
   478  
   479  var _ gojay.MarshalerJSONObject = &preferredAddress{}
   480  
   481  func (a preferredAddress) IsNil() bool { return false }
   482  func (a preferredAddress) MarshalJSONObject(enc *gojay.Encoder) {
   483  	enc.StringKey("ip_v4", a.IPv4.Addr().String())
   484  	enc.Uint16Key("port_v4", a.IPv4.Port())
   485  	enc.StringKey("ip_v6", a.IPv6.Addr().String())
   486  	enc.Uint16Key("port_v6", a.IPv6.Port())
   487  	enc.StringKey("connection_id", a.ConnectionID.String())
   488  	enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", a.StatelessResetToken))
   489  }
   490  
   491  type eventLossTimerSet struct {
   492  	TimerType timerType
   493  	EncLevel  protocol.EncryptionLevel
   494  	Delta     time.Duration
   495  }
   496  
   497  func (e eventLossTimerSet) Category() category { return categoryRecovery }
   498  func (e eventLossTimerSet) Name() string       { return "loss_timer_updated" }
   499  func (e eventLossTimerSet) IsNil() bool        { return false }
   500  
   501  func (e eventLossTimerSet) MarshalJSONObject(enc *gojay.Encoder) {
   502  	enc.StringKey("event_type", "set")
   503  	enc.StringKey("timer_type", e.TimerType.String())
   504  	enc.StringKey("packet_number_space", encLevelToPacketNumberSpace(e.EncLevel))
   505  	enc.Float64Key("delta", milliseconds(e.Delta))
   506  }
   507  
   508  type eventLossTimerExpired struct {
   509  	TimerType timerType
   510  	EncLevel  protocol.EncryptionLevel
   511  }
   512  
   513  func (e eventLossTimerExpired) Category() category { return categoryRecovery }
   514  func (e eventLossTimerExpired) Name() string       { return "loss_timer_updated" }
   515  func (e eventLossTimerExpired) IsNil() bool        { return false }
   516  
   517  func (e eventLossTimerExpired) MarshalJSONObject(enc *gojay.Encoder) {
   518  	enc.StringKey("event_type", "expired")
   519  	enc.StringKey("timer_type", e.TimerType.String())
   520  	enc.StringKey("packet_number_space", encLevelToPacketNumberSpace(e.EncLevel))
   521  }
   522  
   523  type eventLossTimerCanceled struct{}
   524  
   525  func (e eventLossTimerCanceled) Category() category { return categoryRecovery }
   526  func (e eventLossTimerCanceled) Name() string       { return "loss_timer_updated" }
   527  func (e eventLossTimerCanceled) IsNil() bool        { return false }
   528  
   529  func (e eventLossTimerCanceled) MarshalJSONObject(enc *gojay.Encoder) {
   530  	enc.StringKey("event_type", "cancelled")
   531  }
   532  
   533  type eventCongestionStateUpdated struct {
   534  	state congestionState
   535  }
   536  
   537  func (e eventCongestionStateUpdated) Category() category { return categoryRecovery }
   538  func (e eventCongestionStateUpdated) Name() string       { return "congestion_state_updated" }
   539  func (e eventCongestionStateUpdated) IsNil() bool        { return false }
   540  
   541  func (e eventCongestionStateUpdated) MarshalJSONObject(enc *gojay.Encoder) {
   542  	enc.StringKey("new", e.state.String())
   543  }
   544  
   545  type eventECNStateUpdated struct {
   546  	state   logging.ECNState
   547  	trigger logging.ECNStateTrigger
   548  }
   549  
   550  func (e eventECNStateUpdated) Category() category { return categoryRecovery }
   551  func (e eventECNStateUpdated) Name() string       { return "ecn_state_updated" }
   552  func (e eventECNStateUpdated) IsNil() bool        { return false }
   553  
   554  func (e eventECNStateUpdated) MarshalJSONObject(enc *gojay.Encoder) {
   555  	enc.StringKey("new", ecnState(e.state).String())
   556  	enc.StringKeyOmitEmpty("trigger", ecnStateTrigger(e.trigger).String())
   557  }
   558  
   559  type eventGeneric struct {
   560  	name string
   561  	msg  string
   562  }
   563  
   564  func (e eventGeneric) Category() category { return categoryTransport }
   565  func (e eventGeneric) Name() string       { return e.name }
   566  func (e eventGeneric) IsNil() bool        { return false }
   567  
   568  func (e eventGeneric) MarshalJSONObject(enc *gojay.Encoder) {
   569  	enc.StringKey("details", e.msg)
   570  }
   571  
   572  type eventALPNInformation struct {
   573  	chosenALPN string
   574  }
   575  
   576  func (e eventALPNInformation) Category() category { return categoryTransport }
   577  func (e eventALPNInformation) Name() string       { return "alpn_information" }
   578  func (e eventALPNInformation) IsNil() bool        { return false }
   579  
   580  func (e eventALPNInformation) MarshalJSONObject(enc *gojay.Encoder) {
   581  	enc.StringKey("chosen_alpn", e.chosenALPN)
   582  }