use crate::Bytes;
use crate::Token;
use http3::*;
use quic::*;
use serde::Deserialize;
use serde::Serialize;
use std::collections::BTreeMap;
pub type ExData = BTreeMap<String, serde_json::Value>;
pub const LOGLEVEL_URI: &str = "urn:ietf:params:qlog:events:loglevel-13";
pub const QUIC_URI: &str = "urn:ietf:params:qlog:events:quic-12";
pub const HTTP3_URI: &str = "urn:ietf:params:qlog:events:http3-12";
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug, Default)]
#[serde(untagged)]
pub enum EventType {
QuicEventType(QuicEventType),
Http3EventType(Http3EventType),
LogLevelEventType(LogLevelEventType),
#[default]
None,
}
use crate::TimeFormat;
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Event {
pub time: f64,
#[serde(flatten)]
pub data: EventData,
#[serde(flatten)]
pub ex_data: Box<ExData>,
pub group_id: Option<Box<String>>,
pub time_format: Option<TimeFormat>,
#[serde(skip)]
ty: EventType,
}
impl Event {
pub fn with_time(time: f64, data: EventData) -> Self {
Self::with_time_ex(time, data, Default::default())
}
pub fn with_time_ex(time: f64, data: EventData, ex_data: ExData) -> Self {
let ty = EventType::from(&data);
Event {
time,
data,
ex_data: Box::new(ex_data),
group_id: Default::default(),
time_format: Default::default(),
ty,
}
}
}
impl Eventable for Event {
fn importance(&self) -> EventImportance {
self.ty.into()
}
fn set_time(&mut self, time: f64) {
self.time = time;
}
}
impl PartialEq for Event {
fn eq(&self, other: &Event) -> bool {
self.time == other.time &&
self.data == other.data &&
self.ex_data == other.ex_data &&
self.group_id == other.group_id &&
self.time_format == other.time_format
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct JsonEvent {
pub time: f64,
#[serde(skip)]
pub importance: EventImportance,
pub name: String,
pub data: serde_json::Value,
}
impl Eventable for JsonEvent {
fn importance(&self) -> EventImportance {
self.importance
}
fn set_time(&mut self, time: f64) {
self.time = time;
}
}
#[derive(Clone, Copy, Debug, Default)]
pub enum EventImportance {
#[default]
Core,
Base,
Extra,
}
impl EventImportance {
pub fn is_contained_in(&self, other: &EventImportance) -> bool {
match (other, self) {
(EventImportance::Core, EventImportance::Core) => true,
(EventImportance::Base, EventImportance::Core) |
(EventImportance::Base, EventImportance::Base) => true,
(EventImportance::Extra, EventImportance::Core) |
(EventImportance::Extra, EventImportance::Base) |
(EventImportance::Extra, EventImportance::Extra) => true,
(..) => false,
}
}
}
impl From<EventType> for EventImportance {
fn from(ty: EventType) -> Self {
match ty {
EventType::QuicEventType(QuicEventType::ServerListening) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::ConnectionStarted) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::ConnectionClosed) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::ConnectionIdUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::SpinBitUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::ConnectionStateUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::TupleAssigned) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::MtuUpdated) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::VersionInformation) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::AlpnInformation) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::ParametersSet) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::ParametersRestored) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::PacketSent) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::PacketReceived) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::PacketDropped) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::PacketBuffered) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::PacketsAcked) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::UdpDatagramsSent) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::UdpDatagramsReceived) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::UdpDatagramDropped) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::StreamStateUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::FramesProcessed) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::StreamDataMoved) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::DatagramDataMoved) =>
EventImportance::Base,
EventType::QuicEventType(
QuicEventType::ConnectionDataBlockedUpdated,
) => EventImportance::Extra,
EventType::QuicEventType(QuicEventType::StreamDataBlockedUpdated) =>
EventImportance::Extra,
EventType::QuicEventType(
QuicEventType::DatagramDataBlockedUpdated,
) => EventImportance::Extra,
EventType::QuicEventType(QuicEventType::MigrationStateUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::KeyUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::KeyDiscarded) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::RecoveryParametersSet) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::RecoveryMetricsUpdated) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::CongestionStateUpdated) =>
EventImportance::Base,
EventType::QuicEventType(QuicEventType::TimerUpdated) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::PacketLost) =>
EventImportance::Core,
EventType::QuicEventType(QuicEventType::MarkedForRetransmit) =>
EventImportance::Extra,
EventType::QuicEventType(QuicEventType::EcnStateUpdated) =>
EventImportance::Extra,
EventType::Http3EventType(Http3EventType::ParametersSet) =>
EventImportance::Base,
EventType::Http3EventType(Http3EventType::StreamTypeSet) =>
EventImportance::Base,
EventType::Http3EventType(Http3EventType::PriorityUpdated) =>
EventImportance::Base,
EventType::Http3EventType(Http3EventType::FrameCreated) =>
EventImportance::Core,
EventType::Http3EventType(Http3EventType::FrameParsed) =>
EventImportance::Core,
EventType::Http3EventType(Http3EventType::DatagramCreated) =>
EventImportance::Base,
EventType::Http3EventType(Http3EventType::DatagramParsed) =>
EventImportance::Base,
EventType::Http3EventType(Http3EventType::PushResolved) =>
EventImportance::Extra,
_ => unimplemented!(),
}
}
}
pub trait Eventable {
fn importance(&self) -> EventImportance;
fn set_time(&mut self, time: f64);
}
impl From<&EventData> for EventType {
fn from(event_data: &EventData) -> Self {
match event_data {
EventData::QuicServerListening { .. } =>
EventType::QuicEventType(QuicEventType::ServerListening),
EventData::QuicConnectionStarted { .. } =>
EventType::QuicEventType(QuicEventType::ConnectionStarted),
EventData::QuicConnectionClosed { .. } =>
EventType::QuicEventType(QuicEventType::ConnectionClosed),
EventData::QuicConnectionIdUpdated { .. } =>
EventType::QuicEventType(QuicEventType::ConnectionIdUpdated),
EventData::QuicSpinBitUpdated { .. } =>
EventType::QuicEventType(QuicEventType::SpinBitUpdated),
EventData::QuicConnectionStateUpdated { .. } =>
EventType::QuicEventType(QuicEventType::ConnectionStateUpdated),
EventData::QuicTupleAssigned { .. } =>
EventType::QuicEventType(QuicEventType::TupleAssigned),
EventData::QuicMtuUpdated { .. } =>
EventType::QuicEventType(QuicEventType::MtuUpdated),
EventData::QuicVersionInformation { .. } =>
EventType::QuicEventType(QuicEventType::VersionInformation),
EventData::QuicAlpnInformation { .. } =>
EventType::QuicEventType(QuicEventType::AlpnInformation),
EventData::QuicParametersSet { .. } =>
EventType::QuicEventType(QuicEventType::ParametersSet),
EventData::QuicParametersRestored { .. } =>
EventType::QuicEventType(QuicEventType::ParametersRestored),
EventData::QuicPacketSent { .. } =>
EventType::QuicEventType(QuicEventType::PacketSent),
EventData::QuicPacketReceived { .. } =>
EventType::QuicEventType(QuicEventType::PacketReceived),
EventData::QuicPacketDropped { .. } =>
EventType::QuicEventType(QuicEventType::PacketDropped),
EventData::QuicPacketBuffered { .. } =>
EventType::QuicEventType(QuicEventType::PacketBuffered),
EventData::QuicPacketsAcked { .. } =>
EventType::QuicEventType(QuicEventType::PacketsAcked),
EventData::QuicUdpDatagramsSent { .. } =>
EventType::QuicEventType(QuicEventType::UdpDatagramsSent),
EventData::QuicUdpDatagramsReceived { .. } =>
EventType::QuicEventType(QuicEventType::UdpDatagramsReceived),
EventData::QuicUdpDatagramDropped { .. } =>
EventType::QuicEventType(QuicEventType::UdpDatagramDropped),
EventData::QuicStreamStateUpdated { .. } =>
EventType::QuicEventType(QuicEventType::StreamStateUpdated),
EventData::QuicFramesProcessed { .. } =>
EventType::QuicEventType(QuicEventType::FramesProcessed),
EventData::QuicStreamDataMoved { .. } =>
EventType::QuicEventType(QuicEventType::StreamDataMoved),
EventData::QuicDatagramDataMoved { .. } =>
EventType::QuicEventType(QuicEventType::DatagramDataMoved),
EventData::QuicConnectionDataBlockedUpdated { .. } =>
EventType::QuicEventType(
QuicEventType::ConnectionDataBlockedUpdated,
),
EventData::QuicStreamDataBlockedUpdated { .. } =>
EventType::QuicEventType(QuicEventType::StreamDataBlockedUpdated),
EventData::QuicDatagramDataBlockedUpdated { .. } =>
EventType::QuicEventType(
QuicEventType::DatagramDataBlockedUpdated,
),
EventData::QuicMigrationStateUpdated { .. } =>
EventType::QuicEventType(QuicEventType::MigrationStateUpdated),
EventData::QuicKeyUpdated { .. } =>
EventType::QuicEventType(QuicEventType::KeyUpdated),
EventData::QuicKeyDiscarded { .. } =>
EventType::QuicEventType(QuicEventType::KeyDiscarded),
EventData::QuicRecoveryParametersSet { .. } =>
EventType::QuicEventType(QuicEventType::RecoveryParametersSet),
EventData::QuicMetricsUpdated { .. } =>
EventType::QuicEventType(QuicEventType::RecoveryMetricsUpdated),
EventData::QuicCongestionStateUpdated { .. } =>
EventType::QuicEventType(QuicEventType::CongestionStateUpdated),
EventData::QuicTimerUpdated { .. } =>
EventType::QuicEventType(QuicEventType::TimerUpdated),
EventData::QuicPacketLost { .. } =>
EventType::QuicEventType(QuicEventType::PacketLost),
EventData::QuicMarkedForRetransmit { .. } =>
EventType::QuicEventType(QuicEventType::MarkedForRetransmit),
EventData::QuicEcnStateUpdated { .. } =>
EventType::QuicEventType(QuicEventType::EcnStateUpdated),
EventData::Http3ParametersSet { .. } =>
EventType::Http3EventType(Http3EventType::ParametersSet),
EventData::Http3ParametersRestored { .. } =>
EventType::Http3EventType(Http3EventType::ParametersRestored),
EventData::Http3StreamTypeSet { .. } =>
EventType::Http3EventType(Http3EventType::StreamTypeSet),
EventData::Http3PriorityUpdated { .. } =>
EventType::Http3EventType(Http3EventType::PriorityUpdated),
EventData::Http3FrameCreated { .. } =>
EventType::Http3EventType(Http3EventType::FrameCreated),
EventData::Http3FrameParsed { .. } =>
EventType::Http3EventType(Http3EventType::FrameParsed),
EventData::Http3DatagramCreated { .. } =>
EventType::Http3EventType(Http3EventType::DatagramCreated),
EventData::Http3DatagramParsed { .. } =>
EventType::Http3EventType(Http3EventType::DatagramParsed),
EventData::Http3PushResolved { .. } =>
EventType::Http3EventType(Http3EventType::PushResolved),
EventData::LogLevelError { .. } =>
EventType::LogLevelEventType(LogLevelEventType::Error),
EventData::LogLevelWarning { .. } =>
EventType::LogLevelEventType(LogLevelEventType::Warning),
EventData::LogLevelInfo { .. } =>
EventType::LogLevelEventType(LogLevelEventType::Info),
EventData::LogLevelDebug { .. } =>
EventType::LogLevelEventType(LogLevelEventType::Debug),
EventData::LogLevelVerbose { .. } =>
EventType::LogLevelEventType(LogLevelEventType::Verbose),
}
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum DataRecipient {
User,
Application,
Transport,
Network,
Dropped,
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Default)]
pub struct RawInfo {
pub length: Option<u64>,
pub payload_length: Option<u64>,
pub data: Option<Box<Bytes>>,
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
#[serde(tag = "name", content = "data")]
#[allow(clippy::large_enum_variant)]
pub enum EventData {
#[serde(rename = "quic:server_listening")]
QuicServerListening(quic::ServerListening),
#[serde(rename = "quic:connection_started")]
QuicConnectionStarted(quic::ConnectionStarted),
#[serde(rename = "quic:connection_closed")]
QuicConnectionClosed(quic::ConnectionClosed),
#[serde(rename = "quic:connection_id_updated")]
QuicConnectionIdUpdated(quic::ConnectionIdUpdated),
#[serde(rename = "quic:spin_bit_updated")]
QuicSpinBitUpdated(quic::SpinBitUpdated),
#[serde(rename = "quic:connection_state_updated")]
QuicConnectionStateUpdated(quic::ConnectionStateUpdated),
#[serde(rename = "quic:tuple_assigned")]
QuicTupleAssigned(quic::TupleAssigned),
#[serde(rename = "quic:mtu_updated")]
QuicMtuUpdated(quic::MtuUpdated),
#[serde(rename = "quic:version_information")]
QuicVersionInformation(quic::QuicVersionInformation),
#[serde(rename = "quic:alpn_information")]
QuicAlpnInformation(quic::AlpnInformation),
#[serde(rename = "quic:parameters_set")]
QuicParametersSet(Box<quic::ParametersSet>),
#[serde(rename = "quic:parameters_restored")]
QuicParametersRestored(quic::ParametersRestored),
#[serde(rename = "quic:packet_sent")]
QuicPacketSent(quic::PacketSent),
#[serde(rename = "quic:packet_received")]
QuicPacketReceived(quic::PacketReceived),
#[serde(rename = "quic:packet_dropped")]
QuicPacketDropped(quic::PacketDropped),
#[serde(rename = "quic:packet_buffered")]
QuicPacketBuffered(quic::PacketBuffered),
#[serde(rename = "quic:packets_acked")]
QuicPacketsAcked(quic::PacketsAcked),
#[serde(rename = "quic:datagrams_sent")]
QuicUdpDatagramsSent(quic::UdpDatagramsSent),
#[serde(rename = "quic:datagrams_received")]
QuicUdpDatagramsReceived(quic::UdpDatagramsReceived),
#[serde(rename = "quic:datagram_dropped")]
QuicUdpDatagramDropped(quic::UdpDatagramDropped),
#[serde(rename = "quic:stream_state_updated")]
QuicStreamStateUpdated(quic::StreamStateUpdated),
#[serde(rename = "quic:frames_processed")]
QuicFramesProcessed(quic::FramesProcessed),
#[serde(rename = "quic:stream_data_moved")]
QuicStreamDataMoved(quic::StreamDataMoved),
#[serde(rename = "quic:datagram_data_moved")]
QuicDatagramDataMoved(quic::DatagramDataMoved),
#[serde(rename = "quic:connection_data_blocked_updated")]
QuicConnectionDataBlockedUpdated(quic::ConnectionDataBlockedUpdated),
#[serde(rename = "quic:stream_data_blocked_updated")]
QuicStreamDataBlockedUpdated(quic::StreamDataBlockedUpdated),
#[serde(rename = "quic:datagram_data_blocked_updated")]
QuicDatagramDataBlockedUpdated(quic::DatagramDataBlockedUpdated),
#[serde(rename = "quic:migration_state_updated")]
QuicMigrationStateUpdated(quic::MigrationStateUpdated),
#[serde(rename = "quic:key_updated")]
QuicKeyUpdated(quic::KeyUpdated),
#[serde(rename = "quic:key_retired")]
QuicKeyDiscarded(quic::KeyDiscarded),
#[serde(rename = "quic:recovery_parameters_set")]
QuicRecoveryParametersSet(quic::RecoveryParametersSet),
#[serde(rename = "quic:recovery_metrics_updated")]
QuicMetricsUpdated(quic::RecoveryMetricsUpdated),
#[serde(rename = "quic:congestion_state_updated")]
QuicCongestionStateUpdated(quic::CongestionStateUpdated),
#[serde(rename = "quic:timer_updated")]
QuicTimerUpdated(quic::TimerUpdated),
#[serde(rename = "quic:packet_lost")]
QuicPacketLost(quic::PacketLost),
#[serde(rename = "quic:marked_for_retransmit")]
QuicMarkedForRetransmit(quic::MarkedForRetransmit),
#[serde(rename = "quic:ecn_state_updated")]
QuicEcnStateUpdated(quic::EcnStateUpdated),
#[serde(rename = "http3:parameters_set")]
Http3ParametersSet(http3::ParametersSet),
#[serde(rename = "http3:parameters_restored")]
Http3ParametersRestored(http3::ParametersRestored),
#[serde(rename = "http3:stream_type_set")]
Http3StreamTypeSet(http3::StreamTypeSet),
#[serde(rename = "http3:priority_updated")]
Http3PriorityUpdated(http3::PriorityUpdated),
#[serde(rename = "http3:frame_created")]
Http3FrameCreated(http3::FrameCreated),
#[serde(rename = "http3:frame_parsed")]
Http3FrameParsed(http3::FrameParsed),
#[serde(rename = "http3:datagram_created")]
Http3DatagramCreated(http3::DatagramCreated),
#[serde(rename = "http3:datagram_parsed")]
Http3DatagramParsed(http3::DatagramParsed),
#[serde(rename = "http3:push_resolved")]
Http3PushResolved(http3::PushResolved),
#[serde(rename = "loglevel:error")]
LogLevelError {
code: Option<u64>,
message: Option<String>,
},
#[serde(rename = "loglevel:warning")]
LogLevelWarning {
code: Option<u64>,
message: Option<String>,
},
#[serde(rename = "loglevel:info")]
LogLevelInfo {
code: Option<u64>,
message: Option<String>,
},
#[serde(rename = "loglevel:debug")]
LogLevelDebug {
code: Option<u64>,
message: Option<String>,
},
#[serde(rename = "loglevel:verbose")]
LogLevelVerbose {
code: Option<u64>,
message: Option<String>,
},
}
impl EventData {
pub fn contains_quic_frames(&self) -> Option<usize> {
match self {
EventData::QuicPacketSent(pkt) =>
pkt.frames.as_ref().map(|f| f.len()),
EventData::QuicPacketReceived(pkt) =>
pkt.frames.as_ref().map(|f| f.len()),
EventData::QuicPacketLost(pkt) =>
pkt.frames.as_ref().map(|f| f.len()),
EventData::QuicMarkedForRetransmit(ev) => Some(ev.frames.len()),
EventData::QuicFramesProcessed(ev) => Some(ev.frames.len()),
_ => None,
}
}
}
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum LogLevelEventType {
Error,
Warning,
Info,
Debug,
Verbose,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(untagged)]
pub enum ConnectionClosedEventError {
TransportError(TransportError),
CryptoError(CryptoError),
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(untagged)]
pub enum ConnectionClosedFrameError {
TransportError(TransportError),
ApplicationError(ApplicationError),
CryptoError(CryptoError),
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum ApplicationError {
HttpNoError,
HttpGeneralProtocolError,
HttpInternalError,
HttpRequestCancelled,
HttpIncompleteRequest,
HttpConnectError,
HttpFrameError,
HttpExcessiveLoad,
HttpVersionFallback,
HttpIdError,
HttpStreamCreationError,
HttpClosedCriticalStream,
HttpEarlyResponse,
HttpMissingSettings,
HttpUnexpectedFrame,
HttpRequestRejection,
HttpSettingsError,
Unknown,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum CryptoError {
Prefix,
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct TupleEndpointInfo {
pub ip_v4: Option<String>,
pub port_v4: Option<u16>,
pub ip_v6: Option<String>,
pub port_v6: Option<u16>,
pub connection_ids: Option<Vec<Bytes>>,
}
pub mod http3;
pub mod quic;