qlog: align with spec removal of categories
diff --git a/h3i/src/client/mod.rs b/h3i/src/client/mod.rs
index eaf07f4..bfacb76 100644
--- a/h3i/src/client/mod.rs
+++ b/h3i/src/client/mod.rs
@@ -34,8 +34,8 @@
 pub mod sync_client;
 
 use connection_summary::*;
-use qlog::events::http::h3::FrameParsed;
-use qlog::events::http::h3::HttpHeader;
+use qlog::events::http3::FrameParsed;
+use qlog::events::http3::HttpHeader;
 use quiche::ConnectionError;
 
 use std::collections::HashMap;
@@ -51,7 +51,7 @@
 use crate::frame_parser::InterruptCause;
 use crate::recordreplay::qlog::QlogEvent;
 use crate::recordreplay::qlog::*;
-use qlog::events::http::h3::Http3Frame;
+use qlog::events::http3::Http3Frame;
 use qlog::events::EventData;
 use qlog::streamer::QlogStreamer;
 
@@ -471,7 +471,7 @@
             let qlog_headers: Vec<HttpHeader> = enriched_headers
                 .headers()
                 .iter()
-                .map(|h| qlog::events::http::h3::HttpHeader {
+                .map(|h| qlog::events::http3::HttpHeader {
                     name: String::from_utf8_lossy(h.name()).into_owned(),
                     value: String::from_utf8_lossy(h.value()).into_owned(),
                 })
diff --git a/h3i/src/lib.rs b/h3i/src/lib.rs
index 2dd8e23..38bfbd7 100644
--- a/h3i/src/lib.rs
+++ b/h3i/src/lib.rs
@@ -44,9 +44,9 @@
 //! [RFC 9204]: https://www.rfc-editor.org/rfc/rfc9204.html
 
 use qlog::events::quic::PacketHeader;
-use qlog::events::quic::quic::PacketSent;
+use qlog::events::quic::PacketSent;
 use qlog::events::quic::PacketType;
-use qlog::events::quic::quic::QuicFrame;
+use qlog::events::quic::QuicFrame;
 use qlog::events::EventData;
 pub use quiche;
 use quiche::h3::NameValue;
diff --git a/h3i/src/prompts/h3/errors.rs b/h3i/src/prompts/h3/errors.rs
index 50cb2fd..dac4a37 100644
--- a/h3i/src/prompts/h3/errors.rs
+++ b/h3i/src/prompts/h3/errors.rs
@@ -30,7 +30,7 @@
 use inquire::CustomUserError;
 use inquire::Select;
 use inquire::Text;
-use qlog::events::quic::quic::ErrorSpace;
+use qlog::events::quic::ErrorSpace;
 
 use crate::prompts::h3;
 
diff --git a/h3i/src/prompts/h3/mod.rs b/h3i/src/prompts/h3/mod.rs
index 4e39fe9..f5389cc 100644
--- a/h3i/src/prompts/h3/mod.rs
+++ b/h3i/src/prompts/h3/mod.rs
@@ -33,7 +33,7 @@
 use inquire::InquireError;
 use inquire::Select;
 use inquire::Text;
-use qlog::events::quic::quic::ErrorSpace;
+use qlog::events::quic::ErrorSpace;
 use quiche::ConnectionError;
 
 use crate::actions::h3::Action;
diff --git a/h3i/src/recordreplay/qlog.rs b/h3i/src/recordreplay/qlog.rs
index 40cd2f4..1b2de3f 100644
--- a/h3i/src/recordreplay/qlog.rs
+++ b/h3i/src/recordreplay/qlog.rs
@@ -26,13 +26,13 @@
 
 use std::collections::BTreeMap;
 
-use qlog::events::http::h3::FrameCreated;
-use qlog::events::http::h3::Owner;
-use qlog::events::http::h3::StreamTypeSet;
-use qlog::events::http::h3::Http3Frame;
-use qlog::events::quic::quic::ErrorSpace;
-use qlog::events::quic::quic::PacketSent;
-use qlog::events::quic::quic::QuicFrame;
+use qlog::events::http3::FrameCreated;
+use qlog::events::http3::Http3Frame;
+use qlog::events::http3::Owner;
+use qlog::events::http3::StreamTypeSet;
+use qlog::events::quic::ErrorSpace;
+use qlog::events::quic::PacketSent;
+use qlog::events::quic::QuicFrame;
 use qlog::events::Event;
 use qlog::events::EventData;
 use qlog::events::ExData;
@@ -112,7 +112,7 @@
             } => {
                 let qlog_headers = headers
                     .iter()
-                    .map(|h| qlog::events::http::h3::HttpHeader {
+                    .map(|h| qlog::events::http3::HttpHeader {
                         name: String::from_utf8_lossy(h.name()).into_owned(),
                         value: String::from_utf8_lossy(h.value()).into_owned(),
                     })
@@ -148,18 +148,18 @@
             } => {
                 let ty = match *stream_type {
                     HTTP3_CONTROL_STREAM_TYPE_ID =>
-                        qlog::events::http::h3::StreamType::Control,
+                        qlog::events::http3::StreamType::Control,
                     HTTP3_PUSH_STREAM_TYPE_ID =>
-                        qlog::events::http::h3::StreamType::Push,
+                        qlog::events::http3::StreamType::Push,
                     QPACK_ENCODER_STREAM_TYPE_ID =>
-                        qlog::events::http::h3::StreamType::QpackEncode,
+                        qlog::events::http3::StreamType::QpackEncode,
                     QPACK_DECODER_STREAM_TYPE_ID =>
-                        qlog::events::http::h3::StreamType::QpackDecode,
+                        qlog::events::http3::StreamType::QpackDecode,
 
-                    _ => qlog::events::http::h3::StreamType::Unknown,
+                    _ => qlog::events::http3::StreamType::Unknown,
                 };
                 let ty_val =
-                    if matches!(ty, qlog::events::http::h3::StreamType::Unknown) {
+                    if matches!(ty, qlog::events::http3::StreamType::Unknown) {
                         Some(*stream_type)
                     } else {
                         None
@@ -534,12 +534,12 @@
     let mut actions = vec![];
     let fin_stream = parse_ex_data(ex_data);
     let stream_type = match st.stream_type {
-        qlog::events::http::h3::StreamType::Control => Some(0x0),
-        qlog::events::http::h3::StreamType::Push => Some(0x1),
-        qlog::events::http::h3::StreamType::QpackEncode => Some(0x2),
-        qlog::events::http::h3::StreamType::QpackDecode => Some(0x3),
-        qlog::events::http::h3::StreamType::Reserved |
-        qlog::events::http::h3::StreamType::Unknown => st.stream_type_value,
+        qlog::events::http3::StreamType::Control => Some(0x0),
+        qlog::events::http3::StreamType::Push => Some(0x1),
+        qlog::events::http3::StreamType::QpackEncode => Some(0x2),
+        qlog::events::http3::StreamType::QpackDecode => Some(0x3),
+        qlog::events::http3::StreamType::Reserved |
+        qlog::events::http3::StreamType::Unknown => st.stream_type_value,
         _ => None,
     };
 
diff --git a/qlog/src/events/http/mod.rs b/qlog/src/events/http/mod.rs
deleted file mode 100644
index 87758ca..0000000
--- a/qlog/src/events/http/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod h3;
diff --git a/qlog/src/events/http/h3.rs b/qlog/src/events/http3.rs
similarity index 100%
rename from qlog/src/events/http/h3.rs
rename to qlog/src/events/http3.rs
diff --git a/qlog/src/events/mod.rs b/qlog/src/events/mod.rs
index a601762..3188a5a 100644
--- a/qlog/src/events/mod.rs
+++ b/qlog/src/events/mod.rs
@@ -26,14 +26,8 @@
 
 use crate::Bytes;
 use crate::Token;
-use http::h3;
-use http::h3::*;
-use quic::connectivity;
-use quic::connectivity::*;
-use quic::quic::*;
-use quic::recovery;
-use quic::recovery::*;
-use quic::security;
+use http3::*;
+use quic::*;
 
 use serde::Deserialize;
 use serde::Serialize;
@@ -42,27 +36,18 @@
 
 pub type ExData = BTreeMap<String, serde_json::Value>;
 
-pub const LOGLEVEL_URI: &str = "urn:ietf:params:qlog:events:gen#loglevel-09";
+pub const LOGLEVEL_URI: &str = "urn:ietf:params:qlog:events:loglevel-09";
 
-pub const CONNECTIVITY_URI: &str =
-    "urn:ietf:params:qlog:events:quic#connectivity-08";
-pub const SECURITY_URI: &str = "urn:ietf:params:qlog:events:quic#security-08";
-pub const QUIC_URI: &str = "urn:ietf:params:qlog:events:quic#quic-08";
-pub const RECOVERY_URI: &str = "urn:ietf:params:qlog:events:quic#recovery-08";
-
-pub const H3_URI: &str = "urn:ietf:params:qlog:events:http#h3-08";
+pub const QUIC_URI: &str = "urn:ietf:params:qlog:events:quic-08";
+pub const HTTP3_URI: &str = "urn:ietf:params:qlog:events:http3-08";
 
 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug, Default)]
 #[serde(untagged)]
 pub enum EventType {
-    ConnectivityEventType(ConnectivityEventType),
-
     QuicEventType(QuicEventType),
 
     SecurityEventType(SecurityEventType),
 
-    RecoveryEventType(RecoveryEventType),
-
     Http3EventType(Http3EventType),
 
     LogLevelEventType(LogLevelEventType),
@@ -207,30 +192,22 @@
 impl From<EventType> for EventImportance {
     fn from(ty: EventType) -> Self {
         match ty {
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::ServerListening,
-            ) => EventImportance::Extra,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::ConnectionStarted,
-            ) => EventImportance::Base,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::ConnectionClosed,
-            ) => EventImportance::Base,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::ConnectionIdUpdated,
-            ) => EventImportance::Base,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::SpinBitUpdated,
-            ) => EventImportance::Base,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::ConnectionStateUpdated,
-            ) => EventImportance::Base,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::PathAssigned,
-            ) => EventImportance::Extra,
-            EventType::ConnectivityEventType(
-                ConnectivityEventType::MtuUpdated,
-            ) => EventImportance::Extra,
+            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::PathAssigned) =>
+                EventImportance::Extra,
+            EventType::QuicEventType(QuicEventType::MtuUpdated) =>
+                EventImportance::Extra,
 
             EventType::SecurityEventType(SecurityEventType::KeyUpdated) =>
                 EventImportance::Base,
@@ -272,20 +249,18 @@
             EventType::QuicEventType(QuicEventType::MigrationStateUpdated) =>
                 EventImportance::Base,
 
-            EventType::RecoveryEventType(RecoveryEventType::ParametersSet) =>
+            EventType::QuicEventType(QuicEventType::RecoveryParametersSet) =>
                 EventImportance::Base,
-            EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated) =>
+            EventType::QuicEventType(QuicEventType::RecoveryMetricsUpdated) =>
                 EventImportance::Core,
-            EventType::RecoveryEventType(
-                RecoveryEventType::CongestionStateUpdated,
-            ) => EventImportance::Base,
-            EventType::RecoveryEventType(RecoveryEventType::LossTimerUpdated) =>
+            EventType::QuicEventType(QuicEventType::CongestionStateUpdated) =>
+                EventImportance::Base,
+            EventType::QuicEventType(QuicEventType::LossTimerUpdated) =>
                 EventImportance::Extra,
-            EventType::RecoveryEventType(RecoveryEventType::PacketLost) =>
+            EventType::QuicEventType(QuicEventType::PacketLost) =>
                 EventImportance::Core,
-            EventType::RecoveryEventType(
-                RecoveryEventType::MarkedForRetransmit,
-            ) => EventImportance::Extra,
+            EventType::QuicEventType(QuicEventType::MarkedForRetransmit) =>
+                EventImportance::Extra,
 
             EventType::Http3EventType(Http3EventType::ParametersSet) =>
                 EventImportance::Base,
@@ -309,91 +284,25 @@
     fn set_time(&mut self, time: f32);
 }
 
-#[derive(Serialize, Deserialize, Clone, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum EventCategory {
-    Connectivity,
-    Security,
-    Transport,
-    Recovery,
-    Http,
-    Qpack,
-
-    Error,
-    Warning,
-    Info,
-    Debug,
-    Verbose,
-    Simulation,
-}
-
-impl std::fmt::Display for EventCategory {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        let v = match self {
-            EventCategory::Connectivity => "connectivity",
-            EventCategory::Security => "security",
-            EventCategory::Transport => "transport",
-            EventCategory::Recovery => "recovery",
-            EventCategory::Http => "http",
-            EventCategory::Qpack => "qpack",
-            EventCategory::Error => "error",
-            EventCategory::Warning => "warning",
-            EventCategory::Info => "info",
-            EventCategory::Debug => "debug",
-            EventCategory::Verbose => "verbose",
-            EventCategory::Simulation => "simulation",
-        };
-
-        write!(f, "{v}",)
-    }
-}
-
-impl From<EventType> for EventCategory {
-    fn from(ty: EventType) -> Self {
-        match ty {
-            EventType::ConnectivityEventType(_) => EventCategory::Connectivity,
-            EventType::SecurityEventType(_) => EventCategory::Security,
-            EventType::QuicEventType(_) => EventCategory::Transport,
-            EventType::RecoveryEventType(_) => EventCategory::Recovery,
-            EventType::Http3EventType(_) => EventCategory::Http,
-
-            _ => unimplemented!(),
-        }
-    }
-}
-
 impl From<&EventData> for EventType {
     fn from(event_data: &EventData) -> Self {
         match event_data {
             EventData::ServerListening { .. } =>
-                EventType::ConnectivityEventType(
-                    ConnectivityEventType::ServerListening,
-                ),
+                EventType::QuicEventType(QuicEventType::ServerListening),
             EventData::ConnectionStarted { .. } =>
-                EventType::ConnectivityEventType(
-                    ConnectivityEventType::ConnectionStarted,
-                ),
+                EventType::QuicEventType(QuicEventType::ConnectionStarted),
             EventData::ConnectionClosed { .. } =>
-                EventType::ConnectivityEventType(
-                    ConnectivityEventType::ConnectionClosed,
-                ),
+                EventType::QuicEventType(QuicEventType::ConnectionClosed),
             EventData::ConnectionIdUpdated { .. } =>
-                EventType::ConnectivityEventType(
-                    ConnectivityEventType::ConnectionIdUpdated,
-                ),
-            EventData::SpinBitUpdated { .. } => EventType::ConnectivityEventType(
-                ConnectivityEventType::SpinBitUpdated,
-            ),
+                EventType::QuicEventType(QuicEventType::ConnectionIdUpdated),
+            EventData::SpinBitUpdated { .. } =>
+                EventType::QuicEventType(QuicEventType::SpinBitUpdated),
             EventData::ConnectionStateUpdated { .. } =>
-                EventType::ConnectivityEventType(
-                    ConnectivityEventType::ConnectionStateUpdated,
-                ),
-            EventData::PathAssigned { .. } => EventType::ConnectivityEventType(
-                ConnectivityEventType::PathAssigned,
-            ),
-            EventData::MtuUpdated { .. } => EventType::ConnectivityEventType(
-                ConnectivityEventType::MtuUpdated,
-            ),
+                EventType::QuicEventType(QuicEventType::ConnectionStateUpdated),
+            EventData::PathAssigned { .. } =>
+                EventType::QuicEventType(QuicEventType::PathAssigned),
+            EventData::MtuUpdated { .. } =>
+                EventType::QuicEventType(QuicEventType::MtuUpdated),
 
             EventData::KeyUpdated { .. } =>
                 EventType::SecurityEventType(SecurityEventType::KeyUpdated),
@@ -436,21 +345,17 @@
                 EventType::QuicEventType(QuicEventType::MigrationStateUpdated),
 
             EventData::RecoveryParametersSet { .. } =>
-                EventType::RecoveryEventType(RecoveryEventType::ParametersSet),
+                EventType::QuicEventType(QuicEventType::RecoveryParametersSet),
             EventData::MetricsUpdated { .. } =>
-                EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated),
+                EventType::QuicEventType(QuicEventType::RecoveryMetricsUpdated),
             EventData::CongestionStateUpdated { .. } =>
-                EventType::RecoveryEventType(
-                    RecoveryEventType::CongestionStateUpdated,
-                ),
+                EventType::QuicEventType(QuicEventType::CongestionStateUpdated),
             EventData::LossTimerUpdated { .. } =>
-                EventType::RecoveryEventType(RecoveryEventType::LossTimerUpdated),
+                EventType::QuicEventType(QuicEventType::LossTimerUpdated),
             EventData::PacketLost { .. } =>
-                EventType::RecoveryEventType(RecoveryEventType::PacketLost),
+                EventType::QuicEventType(QuicEventType::PacketLost),
             EventData::MarkedForRetransmit { .. } =>
-                EventType::RecoveryEventType(
-                    RecoveryEventType::MarkedForRetransmit,
-                ),
+                EventType::QuicEventType(QuicEventType::MarkedForRetransmit),
 
             EventData::H3ParametersSet { .. } =>
                 EventType::Http3EventType(Http3EventType::ParametersSet),
@@ -504,126 +409,126 @@
 #[allow(clippy::large_enum_variant)]
 pub enum EventData {
     // Connectivity
-    #[serde(rename = "connectivity:server_listening")]
-    ServerListening(connectivity::ServerListening),
+    #[serde(rename = "quic:server_listening")]
+    ServerListening(quic::ServerListening),
 
-    #[serde(rename = "connectivity:connection_started")]
-    ConnectionStarted(connectivity::ConnectionStarted),
+    #[serde(rename = "quic:connection_started")]
+    ConnectionStarted(quic::ConnectionStarted),
 
-    #[serde(rename = "connectivity:connection_closed")]
-    ConnectionClosed(connectivity::ConnectionClosed),
+    #[serde(rename = "quic:connection_closed")]
+    ConnectionClosed(quic::ConnectionClosed),
 
-    #[serde(rename = "connectivity:connection_id_updated")]
-    ConnectionIdUpdated(connectivity::ConnectionIdUpdated),
+    #[serde(rename = "quic:connection_id_updated")]
+    ConnectionIdUpdated(quic::ConnectionIdUpdated),
 
-    #[serde(rename = "connectivity:spin_bit_updated")]
-    SpinBitUpdated(connectivity::SpinBitUpdated),
+    #[serde(rename = "quic:spin_bit_updated")]
+    SpinBitUpdated(quic::SpinBitUpdated),
 
-    #[serde(rename = "connectivity:connection_state_updated")]
-    ConnectionStateUpdated(connectivity::ConnectionStateUpdated),
+    #[serde(rename = "quic:connection_state_updated")]
+    ConnectionStateUpdated(quic::ConnectionStateUpdated),
 
-    #[serde(rename = "connectivity:path_assigned")]
-    PathAssigned(connectivity::PathAssigned),
+    #[serde(rename = "quic:path_assigned")]
+    PathAssigned(quic::PathAssigned),
 
-    #[serde(rename = "connectivity:mtu_updated")]
-    MtuUpdated(connectivity::MtuUpdated),
+    #[serde(rename = "quic:mtu_updated")]
+    MtuUpdated(quic::MtuUpdated),
 
     // Security
-    #[serde(rename = "security:key_updated")]
-    KeyUpdated(security::KeyUpdated),
+    #[serde(rename = "quic:key_updated")]
+    KeyUpdated(quic::KeyUpdated),
 
-    #[serde(rename = "security:key_retired")]
-    KeyDiscarded(security::KeyDiscarded),
+    #[serde(rename = "quic:key_retired")]
+    KeyDiscarded(quic::KeyDiscarded),
 
     // Transport
     #[serde(rename = "quic:version_information")]
-    VersionInformation(quic::quic::QuicVersionInformation),
+    VersionInformation(quic::QuicVersionInformation),
 
     #[serde(rename = "quic:alpn_information")]
-    AlpnInformation(quic::quic::AlpnInformation),
+    AlpnInformation(quic::AlpnInformation),
 
     #[serde(rename = "quic:parameters_set")]
-    ParametersSet(quic::quic::ParametersSet),
+    ParametersSet(quic::ParametersSet),
 
     #[serde(rename = "quic:parameters_restored")]
-    ParametersRestored(quic::quic::ParametersRestored),
+    ParametersRestored(quic::ParametersRestored),
 
     #[serde(rename = "quic:datagrams_received")]
-    UdpDatagramsReceived(quic::quic::UdpDatagramsReceived),
+    UdpDatagramsReceived(quic::UdpDatagramsReceived),
 
     #[serde(rename = "quic:datagrams_sent")]
-    UdpDatagramsSent(quic::quic::UdpDatagramsSent),
+    UdpDatagramsSent(quic::UdpDatagramsSent),
 
     #[serde(rename = "quic:datagram_dropped")]
-    UdpDatagramDropped(quic::quic::UdpDatagramDropped),
+    UdpDatagramDropped(quic::UdpDatagramDropped),
 
     #[serde(rename = "quic:packet_received")]
-    PacketReceived(quic::quic::PacketReceived),
+    PacketReceived(quic::PacketReceived),
 
     #[serde(rename = "quic:packet_sent")]
-    PacketSent(quic::quic::PacketSent),
+    PacketSent(quic::PacketSent),
 
     #[serde(rename = "quic:packet_dropped")]
-    PacketDropped(quic::quic::PacketDropped),
+    PacketDropped(quic::PacketDropped),
 
     #[serde(rename = "quic:packet_buffered")]
-    PacketBuffered(quic::quic::PacketBuffered),
+    PacketBuffered(quic::PacketBuffered),
 
     #[serde(rename = "quic:packets_acked")]
-    PacketsAcked(quic::quic::PacketsAcked),
+    PacketsAcked(quic::PacketsAcked),
 
     #[serde(rename = "quic:stream_state_updated")]
-    StreamStateUpdated(quic::quic::StreamStateUpdated),
+    StreamStateUpdated(quic::StreamStateUpdated),
 
     #[serde(rename = "quic:frames_processed")]
-    FramesProcessed(quic::quic::FramesProcessed),
+    FramesProcessed(quic::FramesProcessed),
 
     #[serde(rename = "quic:stream_data_moved")]
-    StreamDataMoved(quic::quic::StreamDataMoved),
+    StreamDataMoved(quic::StreamDataMoved),
 
     #[serde(rename = "quic:datagram_data_moved")]
-    DatagramDataMoved(quic::quic::DatagramDataMoved),
+    DatagramDataMoved(quic::DatagramDataMoved),
 
     #[serde(rename = "quic:migration_state_updated")]
-    MigrationStateUpdated(quic::quic::MigrationStateUpdated),
+    MigrationStateUpdated(quic::MigrationStateUpdated),
 
     // Recovery
-    #[serde(rename = "recovery:parameters_set")]
-    RecoveryParametersSet(recovery::ParametersSet),
+    #[serde(rename = "quic:recovery_parameters_set")]
+    RecoveryParametersSet(quic::RecoveryParametersSet),
 
-    #[serde(rename = "recovery:metrics_updated")]
-    MetricsUpdated(recovery::MetricsUpdated),
+    #[serde(rename = "quic:recovery_metrics_updated")]
+    MetricsUpdated(quic::RecoveryMetricsUpdated),
 
-    #[serde(rename = "recovery:congestion_state_updated")]
-    CongestionStateUpdated(recovery::CongestionStateUpdated),
+    #[serde(rename = "quic:congestion_state_updated")]
+    CongestionStateUpdated(quic::CongestionStateUpdated),
 
-    #[serde(rename = "recovery:loss_timer_updated")]
-    LossTimerUpdated(recovery::LossTimerUpdated),
+    #[serde(rename = "quic:loss_timer_updated")]
+    LossTimerUpdated(quic::LossTimerUpdated),
 
-    #[serde(rename = "recovery:packet_lost")]
-    PacketLost(recovery::PacketLost),
+    #[serde(rename = "quic:packet_lost")]
+    PacketLost(quic::PacketLost),
 
-    #[serde(rename = "recovery:marked_for_retransmit")]
-    MarkedForRetransmit(recovery::MarkedForRetransmit),
+    #[serde(rename = "quic:marked_for_retransmit")]
+    MarkedForRetransmit(quic::MarkedForRetransmit),
 
     // HTTP/3
-    #[serde(rename = "http:parameters_set")]
-    H3ParametersSet(h3::ParametersSet),
+    #[serde(rename = "http3:parameters_set")]
+    H3ParametersSet(http3::ParametersSet),
 
-    #[serde(rename = "http:parameters_restored")]
-    H3ParametersRestored(h3::ParametersRestored),
+    #[serde(rename = "http3:parameters_restored")]
+    H3ParametersRestored(http3::ParametersRestored),
 
-    #[serde(rename = "http:stream_type_set")]
-    H3StreamTypeSet(h3::StreamTypeSet),
+    #[serde(rename = "http3:stream_type_set")]
+    H3StreamTypeSet(http3::StreamTypeSet),
 
-    #[serde(rename = "http:frame_created")]
-    H3FrameCreated(h3::FrameCreated),
+    #[serde(rename = "http3:frame_created")]
+    H3FrameCreated(http3::FrameCreated),
 
-    #[serde(rename = "http:frame_parsed")]
-    H3FrameParsed(h3::FrameParsed),
+    #[serde(rename = "http3:frame_parsed")]
+    H3FrameParsed(http3::FrameParsed),
 
-    #[serde(rename = "http:push_resolved")]
-    H3PushResolved(h3::PushResolved),
+    #[serde(rename = "http3:push_resolved")]
+    H3PushResolved(http3::PushResolved),
 
     // LogLevel
     #[serde(rename = "loglevel:error")]
@@ -721,5 +626,5 @@
     pub connection_ids: Vec<Bytes>,
 }
 
-pub mod http;
+pub mod http3;
 pub mod quic;
diff --git a/qlog/src/events/quic/quic.rs b/qlog/src/events/quic.rs
similarity index 62%
rename from qlog/src/events/quic/quic.rs
rename to qlog/src/events/quic.rs
index b1a0819..6edfc9e 100644
--- a/qlog/src/events/quic/quic.rs
+++ b/qlog/src/events/quic.rs
@@ -29,8 +29,10 @@
 
 use smallvec::SmallVec;
 
-use super::connectivity::TransportOwner;
-use super::PacketHeader;
+use crate::HexSlice;
+
+use crate::events::ApplicationErrorCode;
+use crate::events::ConnectionErrorCode;
 use crate::events::DataRecipient;
 use crate::events::PathEndpointInfo;
 use crate::events::RawInfo;
@@ -40,6 +42,119 @@
 
 #[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
 #[serde(rename_all = "snake_case")]
+pub enum PacketType {
+    Initial,
+    Handshake,
+
+    #[serde(rename = "0RTT")]
+    ZeroRtt,
+
+    #[serde(rename = "1RTT")]
+    OneRtt,
+
+    Retry,
+    VersionNegotiation,
+    Unknown,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug)]
+pub struct PacketHeader {
+    pub packet_type: PacketType,
+    pub packet_number: Option<u64>,
+
+    pub flags: Option<u8>,
+    pub token: Option<Token>,
+
+    pub length: Option<u16>,
+
+    pub version: Option<Bytes>,
+
+    pub scil: Option<u8>,
+    pub dcil: Option<u8>,
+    pub scid: Option<Bytes>,
+    pub dcid: Option<Bytes>,
+}
+
+impl PacketHeader {
+    #[allow(clippy::too_many_arguments)]
+    /// Creates a new PacketHeader.
+    pub fn new(
+        packet_type: PacketType, packet_number: Option<u64>, flags: Option<u8>,
+        token: Option<Token>, length: Option<u16>, version: Option<u32>,
+        scid: Option<&[u8]>, dcid: Option<&[u8]>,
+    ) -> Self {
+        let (scil, scid) = match scid {
+            Some(cid) => (
+                Some(cid.len() as u8),
+                Some(format!("{}", HexSlice::new(&cid))),
+            ),
+
+            None => (None, None),
+        };
+
+        let (dcil, dcid) = match dcid {
+            Some(cid) => (
+                Some(cid.len() as u8),
+                Some(format!("{}", HexSlice::new(&cid))),
+            ),
+
+            None => (None, None),
+        };
+
+        let version = version.map(|v| format!("{v:x?}"));
+
+        PacketHeader {
+            packet_type,
+            packet_number,
+            flags,
+            token,
+            length,
+            version,
+            scil,
+            dcil,
+            scid,
+            dcid,
+        }
+    }
+
+    /// Creates a new PacketHeader.
+    ///
+    /// Once a QUIC connection has formed, version, dcid and scid are stable, so
+    /// there are space benefits to not logging them in every packet, especially
+    /// PacketType::OneRtt.
+    pub fn with_type(
+        ty: PacketType, packet_number: Option<u64>, version: Option<u32>,
+        scid: Option<&[u8]>, dcid: Option<&[u8]>,
+    ) -> Self {
+        match ty {
+            PacketType::OneRtt => PacketHeader::new(
+                ty,
+                packet_number,
+                None,
+                None,
+                None,
+                None,
+                None,
+                None,
+            ),
+
+            _ => PacketHeader::new(
+                ty,
+                packet_number,
+                None,
+                None,
+                None,
+                version,
+                scid,
+                dcid,
+            ),
+        }
+    }
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
 pub enum PacketNumberSpace {
     Initial,
     Handshake,
@@ -114,29 +229,150 @@
 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
 #[serde(rename_all = "snake_case")]
 pub enum QuicEventType {
+    ServerListening,
+    ConnectionStarted,
+    ConnectionClosed,
+    ConnectionIdUpdated,
+    SpinBitUpdated,
+    ConnectionStateUpdated,
+    PathAssigned,
+    MtuUpdated,
+
     VersionInformation,
     AlpnInformation,
-
     ParametersSet,
     ParametersRestored,
-
     UdpDatagramsSent,
     UdpDatagramsReceived,
     UdpDatagramDropped,
-
     PacketSent,
     PacketReceived,
     PacketDropped,
     PacketBuffered,
     PacketsAcked,
-
     FramesProcessed,
-
     StreamStateUpdated,
-
     StreamDataMoved,
     DatagramDataMoved,
     MigrationStateUpdated,
+
+    RecoveryParametersSet,
+    RecoveryMetricsUpdated,
+    CongestionStateUpdated,
+    LossTimerUpdated,
+    PacketLost,
+    MarkedForRetransmit,
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum TransportOwner {
+    Local,
+    Remote,
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum ConnectionState {
+    Attempted,
+    PeerValidated,
+    HandshakeStarted,
+    EarlyWrite,
+    HandshakeCompleted,
+    HandshakeConfirmed,
+    Closing,
+    Draining,
+    Closed,
+}
+
+#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum ConnectionClosedTrigger {
+    Clean,
+    HandshakeTimeout,
+    IdleTimeout,
+    Error,
+    StatelessReset,
+    VersionMismatch,
+    Application,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct ServerListening {
+    pub ip_v4: Option<String>, // human-readable or bytes
+    pub ip_v6: Option<String>, // human-readable or bytes
+    pub port_v4: Option<u16>,
+    pub port_v6: Option<u16>,
+
+    retry_required: Option<bool>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct ConnectionStarted {
+    pub ip_version: Option<String>, // "v4" or "v6"
+    pub src_ip: String,             // human-readable or bytes
+    pub dst_ip: String,             // human-readable or bytes
+
+    pub protocol: Option<String>,
+    pub src_port: Option<u16>,
+    pub dst_port: Option<u16>,
+
+    pub src_cid: Option<Bytes>,
+    pub dst_cid: Option<Bytes>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct ConnectionClosed {
+    pub owner: Option<TransportOwner>,
+
+    pub connection_code: Option<ConnectionErrorCode>,
+    pub application_code: Option<ApplicationErrorCode>,
+    pub internal_code: Option<u32>,
+
+    pub reason: Option<String>,
+
+    pub trigger: Option<ConnectionClosedTrigger>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct ConnectionIdUpdated {
+    pub owner: Option<TransportOwner>,
+
+    pub old: Option<Bytes>,
+    pub new: Option<Bytes>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct SpinBitUpdated {
+    pub state: bool,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct ConnectionStateUpdated {
+    pub old: Option<ConnectionState>,
+    pub new: ConnectionState,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct PathAssigned {
+    pub path_id: String,
+    pub path_remote: Option<PathEndpointInfo>,
+    pub path_local: Option<PathEndpointInfo>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct MtuUpdated {
+    pub old: Option<u32>,
+    pub new: u32,
+    pub done: Option<bool>,
 }
 
 #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
@@ -621,6 +857,159 @@
     pub path_local: Option<PathEndpointInfo>,
 }
 
+#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum CongestionStateUpdatedTrigger {
+    PersistentCongestion,
+    Ecn,
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum TimerType {
+    Ack,
+    Pto,
+}
+
+#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum PacketLostTrigger {
+    ReorderingThreshold,
+    TimeThreshold,
+    PtoExpired,
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum LossTimerEventType {
+    Set,
+    Expired,
+    Cancelled,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
+pub struct RecoveryParametersSet {
+    pub reordering_threshold: Option<u16>,
+    pub time_threshold: Option<f32>,
+    pub timer_granularity: Option<u16>,
+    pub initial_rtt: Option<f32>,
+
+    pub max_datagram_size: Option<u32>,
+    pub initial_congestion_window: Option<u64>,
+    pub minimum_congestion_window: Option<u32>,
+    pub loss_reduction_factor: Option<f32>,
+    pub persistent_congestion_threshold: Option<u16>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
+pub struct RecoveryMetricsUpdated {
+    pub min_rtt: Option<f32>,
+    pub smoothed_rtt: Option<f32>,
+    pub latest_rtt: Option<f32>,
+    pub rtt_variance: Option<f32>,
+
+    pub pto_count: Option<u16>,
+
+    pub congestion_window: Option<u64>,
+    pub bytes_in_flight: Option<u64>,
+
+    pub ssthresh: Option<u64>,
+
+    // qlog defined
+    pub packets_in_flight: Option<u64>,
+
+    pub pacing_rate: Option<u64>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct CongestionStateUpdated {
+    pub old: Option<String>,
+    pub new: String,
+
+    pub trigger: Option<CongestionStateUpdatedTrigger>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
+pub struct LossTimerUpdated {
+    pub timer_type: Option<TimerType>,
+    pub packet_number_space: Option<PacketNumberSpace>,
+
+    pub event_type: LossTimerEventType,
+
+    pub delta: Option<f32>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
+pub struct PacketLost {
+    pub header: Option<PacketHeader>,
+
+    pub frames: Option<Vec<QuicFrame>>,
+
+    pub trigger: Option<PacketLostTrigger>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
+pub struct MarkedForRetransmit {
+    pub frames: Vec<QuicFrame>,
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum KeyType {
+    ServerInitialSecret,
+    ClientInitialSecret,
+
+    ServerHandshakeSecret,
+    ClientHandshakeSecret,
+
+    #[serde(rename = "server_0rtt_secret")]
+    Server0RttSecret,
+    #[serde(rename = "client_0rtt_secret")]
+    Client0RttSecret,
+    #[serde(rename = "server_1rtt_secret")]
+    Server1RttSecret,
+    #[serde(rename = "client_1rtt_secret")]
+    Client1RttSecret,
+}
+
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+#[serde(rename_all = "snake_case")]
+pub enum KeyUpdateOrRetiredTrigger {
+    Tls,
+    RemoteUpdate,
+    LocalUpdate,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct KeyUpdated {
+    pub key_type: KeyType,
+
+    pub old: Option<Bytes>,
+    pub new: Bytes,
+
+    pub generation: Option<u32>,
+
+    pub trigger: Option<KeyUpdateOrRetiredTrigger>,
+}
+
+#[serde_with::skip_serializing_none]
+#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
+pub struct KeyDiscarded {
+    pub key_type: KeyType,
+    pub key: Option<Bytes>,
+
+    pub generation: Option<u32>,
+
+    pub trigger: Option<KeyUpdateOrRetiredTrigger>,
+}
+
 #[cfg(test)]
 mod tests {
 
diff --git a/qlog/src/events/quic/connectivity.rs b/qlog/src/events/quic/connectivity.rs
deleted file mode 100644
index 1972986..0000000
--- a/qlog/src/events/quic/connectivity.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (C) 2021, Cloudflare, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use serde::Deserialize;
-use serde::Serialize;
-
-use crate::events::ApplicationErrorCode;
-use crate::events::Bytes;
-use crate::events::ConnectionErrorCode;
-use crate::events::PathEndpointInfo;
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum TransportOwner {
-    Local,
-    Remote,
-}
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum ConnectionState {
-    Attempted,
-    PeerValidated,
-    HandshakeStarted,
-    EarlyWrite,
-    HandshakeCompleted,
-    HandshakeConfirmed,
-    Closing,
-    Draining,
-    Closed,
-}
-
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum ConnectivityEventType {
-    ServerListening,
-    ConnectionStarted,
-    ConnectionClosed,
-    ConnectionIdUpdated,
-    SpinBitUpdated,
-    ConnectionStateUpdated,
-    PathAssigned,
-    MtuUpdated,
-}
-
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum ConnectionClosedTrigger {
-    Clean,
-    HandshakeTimeout,
-    IdleTimeout,
-    Error,
-    StatelessReset,
-    VersionMismatch,
-    Application,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct ServerListening {
-    pub ip_v4: Option<String>, // human-readable or bytes
-    pub ip_v6: Option<String>, // human-readable or bytes
-    pub port_v4: Option<u16>,
-    pub port_v6: Option<u16>,
-
-    retry_required: Option<bool>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct ConnectionStarted {
-    pub ip_version: Option<String>, // "v4" or "v6"
-    pub src_ip: String,             // human-readable or bytes
-    pub dst_ip: String,             // human-readable or bytes
-
-    pub protocol: Option<String>,
-    pub src_port: Option<u16>,
-    pub dst_port: Option<u16>,
-
-    pub src_cid: Option<Bytes>,
-    pub dst_cid: Option<Bytes>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct ConnectionClosed {
-    pub owner: Option<TransportOwner>,
-
-    pub connection_code: Option<ConnectionErrorCode>,
-    pub application_code: Option<ApplicationErrorCode>,
-    pub internal_code: Option<u32>,
-
-    pub reason: Option<String>,
-
-    pub trigger: Option<ConnectionClosedTrigger>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct ConnectionIdUpdated {
-    pub owner: Option<TransportOwner>,
-
-    pub old: Option<Bytes>,
-    pub new: Option<Bytes>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct SpinBitUpdated {
-    pub state: bool,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct ConnectionStateUpdated {
-    pub old: Option<ConnectionState>,
-    pub new: ConnectionState,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct PathAssigned {
-    pub path_id: String,
-    pub path_remote: Option<PathEndpointInfo>,
-    pub path_local: Option<PathEndpointInfo>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct MtuUpdated {
-    pub old: Option<u32>,
-    pub new: u32,
-    pub done: Option<bool>,
-}
diff --git a/qlog/src/events/quic/mod.rs b/qlog/src/events/quic/mod.rs
deleted file mode 100644
index 4f09087..0000000
--- a/qlog/src/events/quic/mod.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (C) 2024, Cloudflare, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use serde::Deserialize;
-use serde::Serialize;
-
-use crate::events::Bytes;
-use crate::events::Token;
-use crate::HexSlice;
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum PacketType {
-    Initial,
-    Handshake,
-
-    #[serde(rename = "0RTT")]
-    ZeroRtt,
-
-    #[serde(rename = "1RTT")]
-    OneRtt,
-
-    Retry,
-    VersionNegotiation,
-    Unknown,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug)]
-pub struct PacketHeader {
-    pub packet_type: PacketType,
-    pub packet_number: Option<u64>,
-
-    pub flags: Option<u8>,
-    pub token: Option<Token>,
-
-    pub length: Option<u16>,
-
-    pub version: Option<Bytes>,
-
-    pub scil: Option<u8>,
-    pub dcil: Option<u8>,
-    pub scid: Option<Bytes>,
-    pub dcid: Option<Bytes>,
-}
-
-impl PacketHeader {
-    #[allow(clippy::too_many_arguments)]
-    /// Creates a new PacketHeader.
-    pub fn new(
-        packet_type: PacketType, packet_number: Option<u64>, flags: Option<u8>,
-        token: Option<Token>, length: Option<u16>, version: Option<u32>,
-        scid: Option<&[u8]>, dcid: Option<&[u8]>,
-    ) -> Self {
-        let (scil, scid) = match scid {
-            Some(cid) => (
-                Some(cid.len() as u8),
-                Some(format!("{}", HexSlice::new(&cid))),
-            ),
-
-            None => (None, None),
-        };
-
-        let (dcil, dcid) = match dcid {
-            Some(cid) => (
-                Some(cid.len() as u8),
-                Some(format!("{}", HexSlice::new(&cid))),
-            ),
-
-            None => (None, None),
-        };
-
-        let version = version.map(|v| format!("{v:x?}"));
-
-        PacketHeader {
-            packet_type,
-            packet_number,
-            flags,
-            token,
-            length,
-            version,
-            scil,
-            dcil,
-            scid,
-            dcid,
-        }
-    }
-
-    /// Creates a new PacketHeader.
-    ///
-    /// Once a QUIC connection has formed, version, dcid and scid are stable, so
-    /// there are space benefits to not logging them in every packet, especially
-    /// PacketType::OneRtt.
-    pub fn with_type(
-        ty: PacketType, packet_number: Option<u64>, version: Option<u32>,
-        scid: Option<&[u8]>, dcid: Option<&[u8]>,
-    ) -> Self {
-        match ty {
-            PacketType::OneRtt => PacketHeader::new(
-                ty,
-                packet_number,
-                None,
-                None,
-                None,
-                None,
-                None,
-                None,
-            ),
-
-            _ => PacketHeader::new(
-                ty,
-                packet_number,
-                None,
-                None,
-                None,
-                version,
-                scid,
-                dcid,
-            ),
-        }
-    }
-}
-
-pub mod connectivity;
-// qlog has the category quic#quic so the inception lies there
-#[allow(clippy::module_inception)]
-pub mod quic;
-pub mod recovery;
-pub mod security;
diff --git a/qlog/src/events/quic/recovery.rs b/qlog/src/events/quic/recovery.rs
deleted file mode 100644
index 793177f..0000000
--- a/qlog/src/events/quic/recovery.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (C) 2021, Cloudflare, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use serde::Deserialize;
-use serde::Serialize;
-
-use super::PacketHeader;
-use crate::events::PacketNumberSpace;
-use crate::events::QuicFrame;
-
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum RecoveryEventType {
-    ParametersSet,
-    MetricsUpdated,
-    CongestionStateUpdated,
-    LossTimerUpdated,
-    PacketLost,
-    MarkedForRetransmit,
-}
-
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum CongestionStateUpdatedTrigger {
-    PersistentCongestion,
-    Ecn,
-}
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum TimerType {
-    Ack,
-    Pto,
-}
-
-#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum PacketLostTrigger {
-    ReorderingThreshold,
-    TimeThreshold,
-    PtoExpired,
-}
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum LossTimerEventType {
-    Set,
-    Expired,
-    Cancelled,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
-pub struct ParametersSet {
-    pub reordering_threshold: Option<u16>,
-    pub time_threshold: Option<f32>,
-    pub timer_granularity: Option<u16>,
-    pub initial_rtt: Option<f32>,
-
-    pub max_datagram_size: Option<u32>,
-    pub initial_congestion_window: Option<u64>,
-    pub minimum_congestion_window: Option<u32>,
-    pub loss_reduction_factor: Option<f32>,
-    pub persistent_congestion_threshold: Option<u16>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
-pub struct MetricsUpdated {
-    pub min_rtt: Option<f32>,
-    pub smoothed_rtt: Option<f32>,
-    pub latest_rtt: Option<f32>,
-    pub rtt_variance: Option<f32>,
-
-    pub pto_count: Option<u16>,
-
-    pub congestion_window: Option<u64>,
-    pub bytes_in_flight: Option<u64>,
-
-    pub ssthresh: Option<u64>,
-
-    // qlog defined
-    pub packets_in_flight: Option<u64>,
-
-    pub pacing_rate: Option<u64>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct CongestionStateUpdated {
-    pub old: Option<String>,
-    pub new: String,
-
-    pub trigger: Option<CongestionStateUpdatedTrigger>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
-pub struct LossTimerUpdated {
-    pub timer_type: Option<TimerType>,
-    pub packet_number_space: Option<PacketNumberSpace>,
-
-    pub event_type: LossTimerEventType,
-
-    pub delta: Option<f32>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
-pub struct PacketLost {
-    pub header: Option<PacketHeader>,
-
-    pub frames: Option<Vec<QuicFrame>>,
-
-    pub trigger: Option<PacketLostTrigger>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
-pub struct MarkedForRetransmit {
-    pub frames: Vec<QuicFrame>,
-}
diff --git a/qlog/src/events/quic/security.rs b/qlog/src/events/quic/security.rs
deleted file mode 100644
index 284aba6..0000000
--- a/qlog/src/events/quic/security.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (C) 2021, Cloudflare, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-use serde::Deserialize;
-use serde::Serialize;
-
-use crate::Bytes;
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum KeyType {
-    ServerInitialSecret,
-    ClientInitialSecret,
-
-    ServerHandshakeSecret,
-    ClientHandshakeSecret,
-
-    #[serde(rename = "server_0rtt_secret")]
-    Server0RttSecret,
-    #[serde(rename = "client_0rtt_secret")]
-    Client0RttSecret,
-    #[serde(rename = "server_1rtt_secret")]
-    Server1RttSecret,
-    #[serde(rename = "client_1rtt_secret")]
-    Client1RttSecret,
-}
-
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-#[serde(rename_all = "snake_case")]
-pub enum KeyUpdateOrRetiredTrigger {
-    Tls,
-    RemoteUpdate,
-    LocalUpdate,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct KeyUpdated {
-    pub key_type: KeyType,
-
-    pub old: Option<Bytes>,
-    pub new: Bytes,
-
-    pub generation: Option<u32>,
-
-    pub trigger: Option<KeyUpdateOrRetiredTrigger>,
-}
-
-#[serde_with::skip_serializing_none]
-#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
-pub struct KeyDiscarded {
-    pub key_type: KeyType,
-    pub key: Option<Bytes>,
-
-    pub generation: Option<u32>,
-
-    pub trigger: Option<KeyUpdateOrRetiredTrigger>,
-}
diff --git a/qlog/src/lib.rs b/qlog/src/lib.rs
index 487973c..72fe5d8 100644
--- a/qlog/src/lib.rs
+++ b/qlog/src/lib.rs
@@ -120,7 +120,7 @@
 //!     Some(&dcid),
 //! );
 //!
-//! let frames = vec![qlog::events::quic::quic::QuicFrame::Crypto {
+//! let frames = vec![qlog::events::quic::QuicFrame::Crypto {
 //!     offset: 0,
 //!     length: 0,
 //! }];
@@ -131,8 +131,8 @@
 //!     data: None,
 //! };
 //!
-//! let event_data = qlog::events::EventData::PacketSent(
-//!     qlog::events::quic::quic::PacketSent {
+//! let event_data =
+//!     qlog::events::EventData::PacketSent(qlog::events::quic::PacketSent {
 //!         header: pkt_hdr,
 //!         frames: Some(frames.into()),
 //!         stateless_reset_token: None,
@@ -142,8 +142,7 @@
 //!         is_mtu_probe_packet: None,
 //!         send_at_time: None,
 //!         trigger: None,
-//!     },
-//! );
+//!     });
 //!
 //! trace.push_event(qlog::events::Event::with_time(0.0, event_data));
 //! ```
@@ -328,17 +327,17 @@
 //!     Some(&dcid),
 //! );
 //!
-//! let ping = qlog::events::quic::quic::QuicFrame::Ping {
+//! let ping = qlog::events::quic::QuicFrame::Ping {
 //!     length: None,
 //!     payload_length: None,
 //! };
-//! let padding = qlog::events::quic::quic::QuicFrame::Padding {
+//! let padding = qlog::events::quic::QuicFrame::Padding {
 //!     length: None,
 //!     payload_length: 1234,
 //! };
 //!
-//! let event_data = qlog::events::EventData::PacketSent(
-//!     qlog::events::quic::quic::PacketSent {
+//! let event_data =
+//!     qlog::events::EventData::PacketSent(qlog::events::quic::PacketSent {
 //!         header: pkt_hdr,
 //!         frames: Some(vec![ping, padding].into()),
 //!         stateless_reset_token: None,
@@ -348,8 +347,7 @@
 //!         is_mtu_probe_packet: None,
 //!         send_at_time: None,
 //!         trigger: None,
-//!     },
-//! );
+//!     });
 //!
 //! let event = qlog::events::Event::with_time(0.0, event_data);
 //!
@@ -718,9 +716,9 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::events::quic::quic::PacketSent;
-    use crate::events::quic::quic::QuicFrame;
+    use crate::events::quic::PacketSent;
     use crate::events::quic::PacketType;
+    use crate::events::quic::QuicFrame;
     use crate::events::EventData;
     use crate::events::RawInfo;
     use testing::*;
diff --git a/qlog/src/streamer.rs b/qlog/src/streamer.rs
index 1f793e7..77c7476 100644
--- a/qlog/src/streamer.rs
+++ b/qlog/src/streamer.rs
@@ -24,11 +24,8 @@
 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-use events::CONNECTIVITY_URI;
-use events::H3_URI;
+use events::HTTP3_URI;
 use events::QUIC_URI;
-use events::RECOVERY_URI;
-use events::SECURITY_URI;
 
 use crate::events::EventData;
 use crate::events::EventImportance;
@@ -87,11 +84,8 @@
             description,
             trace,
             event_schemas: vec![
-                CONNECTIVITY_URI.to_string(),
-                SECURITY_URI.to_string(),
                 QUIC_URI.to_string(),
-                RECOVERY_URI.to_string(),
-                H3_URI.to_string(),
+                HTTP3_URI.to_string(),
             ],
         };
 
@@ -277,7 +271,7 @@
 
     use super::*;
     use crate::events::quic;
-    use crate::events::quic::quic::QuicFrame;
+    use crate::events::quic::QuicFrame;
     use crate::events::RawInfo;
     use smallvec::smallvec;
     use testing::*;
@@ -306,7 +300,7 @@
             raw: None,
         };
 
-        let event_data1 = EventData::PacketSent(quic::quic::PacketSent {
+        let event_data1 = EventData::PacketSent(quic::PacketSent {
             header: pkt_hdr.clone(),
             frames: Some(smallvec![frame1]),
             stateless_reset_token: None,
@@ -336,7 +330,7 @@
             raw: None,
         };
 
-        let event_data2 = EventData::PacketSent(quic::quic::PacketSent {
+        let event_data2 = EventData::PacketSent(quic::PacketSent {
             header: pkt_hdr.clone(),
             frames: Some(smallvec![frame2]),
             stateless_reset_token: None,
@@ -350,7 +344,7 @@
 
         let ev2 = Event::with_time(0.0, event_data2);
 
-        let event_data3 = EventData::PacketSent(quic::quic::PacketSent {
+        let event_data3 = EventData::PacketSent(quic::PacketSent {
             header: pkt_hdr,
             frames: Some(smallvec![frame3]),
             stateless_reset_token: Some("reset_token".to_string()),
@@ -398,7 +392,7 @@
         #[allow(clippy::borrowed_box)]
         let w: &Box<std::io::Cursor<Vec<u8>>> = unsafe { std::mem::transmute(r) };
 
-        let log_string = r#"{"file_schema":"urn:ietf:params:qlog:file:sequential","serialization_format":"JSON-SEQ","title":"title","description":"description","event_schemas":["urn:ietf:params:qlog:events:quic#connectivity-08","urn:ietf:params:qlog:events:quic#security-08","urn:ietf:params:qlog:events:quic#quic-08","urn:ietf:params:qlog:events:quic#recovery-08","urn:ietf:params:qlog:events:http#h3-08"],"trace":{"vantage_point":{"type":"server"},"title":"Quiche qlog trace","description":"Quiche qlog trace description","configuration":{"time_offset":0.0}}}
+        let log_string = r#"{"file_schema":"urn:ietf:params:qlog:file:sequential","serialization_format":"JSON-SEQ","title":"title","description":"description","event_schemas":["urn:ietf:params:qlog:events:quic-08","urn:ietf:params:qlog:events:http3-08"],"trace":{"vantage_point":{"type":"server"},"title":"Quiche qlog trace","description":"Quiche qlog trace description","configuration":{"time_offset":0.0}}}
 {"time":0.0,"name":"quic:packet_sent","data":{"header":{"packet_type":"handshake","packet_number":0,"version":"1","scil":8,"dcil":8,"scid":"7e37e4dcc6682da8","dcid":"36ce104eee50101c"},"raw":{"length":1251,"payload_length":1224},"frames":[{"frame_type":"stream","stream_id":40,"offset":40,"length":400,"fin":true}]}}
 {"time":0.0,"name":"quic:packet_sent","data":{"header":{"packet_type":"handshake","packet_number":0,"version":"1","scil":8,"dcil":8,"scid":"7e37e4dcc6682da8","dcid":"36ce104eee50101c"},"raw":{"length":1251,"payload_length":1224},"frames":[{"frame_type":"stream","stream_id":0,"offset":0,"length":100,"fin":true}]}}
 {"time":0.0,"name":"quic:packet_sent","data":{"header":{"packet_type":"handshake","packet_number":0,"version":"1","scil":8,"dcil":8,"scid":"7e37e4dcc6682da8","dcid":"36ce104eee50101c"},"stateless_reset_token":"reset_token","raw":{"length":1251,"payload_length":1224},"frames":[{"frame_type":"stream","stream_id":0,"offset":0,"length":100,"fin":true}]}}
@@ -443,7 +437,7 @@
         #[allow(clippy::borrowed_box)]
         let w: &Box<std::io::Cursor<Vec<u8>>> = unsafe { std::mem::transmute(r) };
 
-        let log_string = r#"{"file_schema":"urn:ietf:params:qlog:file:sequential","serialization_format":"JSON-SEQ","title":"title","description":"description","event_schemas":["urn:ietf:params:qlog:events:quic#connectivity-08","urn:ietf:params:qlog:events:quic#security-08","urn:ietf:params:qlog:events:quic#quic-08","urn:ietf:params:qlog:events:quic#recovery-08","urn:ietf:params:qlog:events:http#h3-08"],"trace":{"vantage_point":{"type":"server"},"title":"Quiche qlog trace","description":"Quiche qlog trace description","configuration":{"time_offset":0.0}}}
+        let log_string = r#"{"file_schema":"urn:ietf:params:qlog:file:sequential","serialization_format":"JSON-SEQ","title":"title","description":"description","event_schemas":["urn:ietf:params:qlog:events:quic-08","urn:ietf:params:qlog:events:http3-08"],"trace":{"vantage_point":{"type":"server"},"title":"Quiche qlog trace","description":"Quiche qlog trace description","configuration":{"time_offset":0.0}}}
 {"time":0.0,"name":"jsonevent:sample","data":{"foo":"Bar","hello":123}}
 "#;
 
@@ -474,7 +468,7 @@
             raw: None,
         };
 
-        let event_data1 = EventData::PacketSent(quic::quic::PacketSent {
+        let event_data1 = EventData::PacketSent(quic::PacketSent {
             header: pkt_hdr.clone(),
             frames: Some(smallvec![frame1]),
             stateless_reset_token: None,
@@ -501,7 +495,7 @@
             raw: None,
         };
 
-        let event_data2 = EventData::PacketSent(quic::quic::PacketSent {
+        let event_data2 = EventData::PacketSent(quic::PacketSent {
             header: pkt_hdr.clone(),
             frames: Some(smallvec![frame2]),
             stateless_reset_token: None,
@@ -533,7 +527,7 @@
         #[allow(clippy::borrowed_box)]
         let w: &Box<std::io::Cursor<Vec<u8>>> = unsafe { std::mem::transmute(r) };
 
-        let log_string = r#"{"file_schema":"urn:ietf:params:qlog:file:sequential","serialization_format":"JSON-SEQ","title":"title","description":"description","event_schemas":["urn:ietf:params:qlog:events:quic#connectivity-08","urn:ietf:params:qlog:events:quic#security-08","urn:ietf:params:qlog:events:quic#quic-08","urn:ietf:params:qlog:events:quic#recovery-08","urn:ietf:params:qlog:events:http#h3-08"],"trace":{"vantage_point":{"type":"server"},"title":"Quiche qlog trace","description":"Quiche qlog trace description","configuration":{"time_offset":0.0}}}
+        let log_string = r#"{"file_schema":"urn:ietf:params:qlog:file:sequential","serialization_format":"JSON-SEQ","title":"title","description":"description","event_schemas":["urn:ietf:params:qlog:events:quic-08","urn:ietf:params:qlog:events:http3-08"],"trace":{"vantage_point":{"type":"server"},"title":"Quiche qlog trace","description":"Quiche qlog trace description","configuration":{"time_offset":0.0}}}
 {"time":0.0,"name":"quic:packet_sent","data":{"header":{"packet_type":"handshake","packet_number":0,"version":"1","scil":8,"dcil":8,"scid":"7e37e4dcc6682da8","dcid":"36ce104eee50101c"},"raw":{"length":1251,"payload_length":1224},"frames":[{"frame_type":"stream","stream_id":40,"offset":40,"length":400,"fin":true}]},"first":{"foo":"Bar","hello":123},"second":{"baz":[1,2,3,4]}}
 {"time":0.0,"name":"quic:packet_sent","data":{"header":{"packet_type":"handshake","packet_number":0,"version":"1","scil":8,"dcil":8,"scid":"7e37e4dcc6682da8","dcid":"36ce104eee50101c"},"raw":{"length":1251,"payload_length":1224},"frames":[{"frame_type":"stream","stream_id":1,"offset":0,"length":100,"fin":true}]}}
 "#;
diff --git a/quiche/src/frame.rs b/quiche/src/frame.rs
index 13b4a47..a590619 100644
--- a/quiche/src/frame.rs
+++ b/quiche/src/frame.rs
@@ -34,13 +34,13 @@
 use crate::stream;
 
 #[cfg(feature = "qlog")]
-use qlog::events::quic::quic::AckedRanges;
+use qlog::events::quic::AckedRanges;
 #[cfg(feature = "qlog")]
-use qlog::events::quic::quic::ErrorSpace;
+use qlog::events::quic::ErrorSpace;
 #[cfg(feature = "qlog")]
-use qlog::events::quic::quic::QuicFrame;
+use qlog::events::quic::QuicFrame;
 #[cfg(feature = "qlog")]
-use qlog::events::quic::quic::StreamType;
+use qlog::events::quic::StreamType;
 
 pub const MAX_CRYPTO_OVERHEAD: usize = 8;
 pub const MAX_DGRAM_OVERHEAD: usize = 2;
diff --git a/quiche/src/h3/frame.rs b/quiche/src/h3/frame.rs
index 2e3d8ea..e1b9bca 100644
--- a/quiche/src/h3/frame.rs
+++ b/quiche/src/h3/frame.rs
@@ -27,7 +27,7 @@
 use super::Result;
 
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::Http3Frame;
+use qlog::events::http3::Http3Frame;
 
 pub const DATA_FRAME_TYPE_ID: u64 = 0x0;
 pub const HEADERS_FRAME_TYPE_ID: u64 = 0x1;
@@ -362,42 +362,42 @@
                 let mut settings = vec![];
 
                 if let Some(v) = max_field_section_size {
-                    settings.push(qlog::events::http::h3::Setting {
+                    settings.push(qlog::events::http3::Setting {
                         name: "MAX_FIELD_SECTION_SIZE".to_string(),
                         value: *v,
                     });
                 }
 
                 if let Some(v) = qpack_max_table_capacity {
-                    settings.push(qlog::events::http::h3::Setting {
+                    settings.push(qlog::events::http3::Setting {
                         name: "QPACK_MAX_TABLE_CAPACITY".to_string(),
                         value: *v,
                     });
                 }
 
                 if let Some(v) = qpack_blocked_streams {
-                    settings.push(qlog::events::http::h3::Setting {
+                    settings.push(qlog::events::http3::Setting {
                         name: "QPACK_BLOCKED_STREAMS".to_string(),
                         value: *v,
                     });
                 }
 
                 if let Some(v) = connect_protocol_enabled {
-                    settings.push(qlog::events::http::h3::Setting {
+                    settings.push(qlog::events::http3::Setting {
                         name: "SETTINGS_ENABLE_CONNECT_PROTOCOL".to_string(),
                         value: *v,
                     });
                 }
 
                 if let Some(v) = h3_datagram {
-                    settings.push(qlog::events::http::h3::Setting {
+                    settings.push(qlog::events::http3::Setting {
                         name: "H3_DATAGRAM".to_string(),
                         value: *v,
                     });
                 }
 
                 if let Some((k, v)) = grease {
-                    settings.push(qlog::events::http::h3::Setting {
+                    settings.push(qlog::events::http3::Setting {
                         name: k.to_string(),
                         value: *v,
                     });
@@ -405,14 +405,14 @@
 
                 if let Some(additional_settings) = additional_settings {
                     for (k, v) in additional_settings {
-                        settings.push(qlog::events::http::h3::Setting {
+                        settings.push(qlog::events::http3::Setting {
                             name: k.to_string(),
                             value: *v,
                         });
                     }
                 }
 
-                qlog::events::http::h3::Http3Frame::Settings { settings }
+                qlog::events::http3::Http3Frame::Settings { settings }
             },
 
             // Qlog expects the `headers` to be represented as an array of
@@ -433,7 +433,7 @@
                 priority_field_value,
             } => Http3Frame::PriorityUpdate {
                 target_stream_type:
-                    qlog::events::http::h3::PriorityTargetStreamType::Request,
+                    qlog::events::http3::PriorityTargetStreamType::Request,
                 prioritized_element_id: *prioritized_element_id,
                 priority_field_value: String::from_utf8_lossy(
                     priority_field_value,
@@ -446,7 +446,7 @@
                 priority_field_value,
             } => Http3Frame::PriorityUpdate {
                 target_stream_type:
-                    qlog::events::http::h3::PriorityTargetStreamType::Request,
+                    qlog::events::http3::PriorityTargetStreamType::Request,
                 prioritized_element_id: *prioritized_element_id,
                 priority_field_value: String::from_utf8_lossy(
                     priority_field_value,
diff --git a/quiche/src/h3/mod.rs b/quiche/src/h3/mod.rs
index bc49503..16be448 100644
--- a/quiche/src/h3/mod.rs
+++ b/quiche/src/h3/mod.rs
@@ -291,21 +291,21 @@
 use std::fmt::Write;
 
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::FrameCreated;
+use qlog::events::http3::FrameCreated;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::FrameParsed;
+use qlog::events::http3::FrameParsed;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::Http3EventType;
+use qlog::events::http3::Http3EventType;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::Http3Frame;
+use qlog::events::http3::Http3Frame;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::Owner;
+use qlog::events::http3::Owner;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::PriorityTargetStreamType;
+use qlog::events::http3::PriorityTargetStreamType;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::StreamType;
+use qlog::events::http3::StreamType;
 #[cfg(feature = "qlog")]
-use qlog::events::http::h3::StreamTypeSet;
+use qlog::events::http3::StreamTypeSet;
 #[cfg(feature = "qlog")]
 use qlog::events::EventData;
 #[cfg(feature = "qlog")]
@@ -1403,7 +1403,7 @@
         qlog_with_type!(QLOG_FRAME_CREATED, conn.qlog, q, {
             let qlog_headers = headers
                 .iter()
-                .map(|h| qlog::events::http::h3::HttpHeader {
+                .map(|h| qlog::events::http3::HttpHeader {
                     name: String::from_utf8_lossy(h.name()).into_owned(),
                     value: String::from_utf8_lossy(h.value()).into_owned(),
                 })
@@ -2762,7 +2762,7 @@
                 qlog_with_type!(QLOG_FRAME_PARSED, conn.qlog, q, {
                     let qlog_headers = headers
                         .iter()
-                        .map(|h| qlog::events::http::h3::HttpHeader {
+                        .map(|h| qlog::events::http3::HttpHeader {
                             name: String::from_utf8_lossy(h.name()).into_owned(),
                             value: String::from_utf8_lossy(h.value())
                                 .into_owned(),
diff --git a/quiche/src/h3/stream.rs b/quiche/src/h3/stream.rs
index c65d4d9..6c3bdc5 100644
--- a/quiche/src/h3/stream.rs
+++ b/quiche/src/h3/stream.rs
@@ -48,14 +48,14 @@
 
 impl Type {
     #[cfg(feature = "qlog")]
-    pub fn to_qlog(self) -> qlog::events::http::h3::StreamType {
+    pub fn to_qlog(self) -> qlog::events::http3::StreamType {
         match self {
-            Type::Control => qlog::events::http::h3::StreamType::Control,
-            Type::Request => qlog::events::http::h3::StreamType::Request,
-            Type::Push => qlog::events::http::h3::StreamType::Push,
-            Type::QpackEncoder => qlog::events::http::h3::StreamType::QpackEncode,
-            Type::QpackDecoder => qlog::events::http::h3::StreamType::QpackDecode,
-            Type::Unknown => qlog::events::http::h3::StreamType::Unknown,
+            Type::Control => qlog::events::http3::StreamType::Control,
+            Type::Request => qlog::events::http3::StreamType::Request,
+            Type::Push => qlog::events::http3::StreamType::Push,
+            Type::QpackEncoder => qlog::events::http3::StreamType::QpackEncode,
+            Type::QpackDecoder => qlog::events::http3::StreamType::QpackDecode,
+            Type::Unknown => qlog::events::http3::StreamType::Unknown,
         }
     }
 }
diff --git a/quiche/src/lib.rs b/quiche/src/lib.rs
index 33ba47f..f418a7d 100644
--- a/quiche/src/lib.rs
+++ b/quiche/src/lib.rs
@@ -383,15 +383,11 @@
 extern crate log;
 
 #[cfg(feature = "qlog")]
-use qlog::events::quic::connectivity::ConnectivityEventType;
+use qlog::events::quic::DataMovedAdditionalInfo;
 #[cfg(feature = "qlog")]
-use qlog::events::quic::connectivity::TransportOwner;
+use qlog::events::quic::QuicEventType;
 #[cfg(feature = "qlog")]
-use qlog::events::quic::quic::DataMovedAdditionalInfo;
-#[cfg(feature = "qlog")]
-use qlog::events::quic::quic::QuicEventType;
-#[cfg(feature = "qlog")]
-use qlog::events::quic::recovery::RecoveryEventType;
+use qlog::events::quic::TransportOwner;
 #[cfg(feature = "qlog")]
 use qlog::events::DataRecipient;
 #[cfg(feature = "qlog")]
@@ -1789,11 +1785,11 @@
 
 #[cfg(feature = "qlog")]
 const QLOG_METRICS: EventType =
-    EventType::RecoveryEventType(RecoveryEventType::MetricsUpdated);
+    EventType::QuicEventType(QuicEventType::RecoveryMetricsUpdated);
 
 #[cfg(feature = "qlog")]
 const QLOG_CONNECTION_CLOSED: EventType =
-    EventType::ConnectivityEventType(ConnectivityEventType::ConnectionClosed);
+    EventType::QuicEventType(QuicEventType::ConnectionClosed);
 
 #[cfg(feature = "qlog")]
 struct QlogInfo {
@@ -2105,6 +2101,8 @@
         &mut self, writer: Box<dyn std::io::Write + Send + Sync>, title: String,
         description: String, qlog_level: QlogLevel,
     ) {
+        use qlog::events::quic::TransportOwner;
+
         let vp = if self.is_server {
             qlog::VantagePointType::Server
         } else {
@@ -2794,13 +2792,12 @@
 
             qlog_with_type!(QLOG_PACKET_RX, self.qlog, q, {
                 let trigger = Some(
-                    qlog::events::quic::security::KeyUpdateOrRetiredTrigger::RemoteUpdate,
+                    qlog::events::quic::KeyUpdateOrRetiredTrigger::RemoteUpdate,
                 );
 
                 let ev_data_client =
-                    EventData::KeyUpdated(qlog::events::quic::security::KeyUpdated {
-                        key_type:
-                            qlog::events::quic::security::KeyType::Client1RttSecret,
+                    EventData::KeyUpdated(qlog::events::quic::KeyUpdated {
+                        key_type: qlog::events::quic::KeyType::Client1RttSecret,
                         old: None,
                         new: String::new(),
                         generation: None,
@@ -2810,9 +2807,8 @@
                 q.add_event_data_with_instant(ev_data_client, now).ok();
 
                 let ev_data_server =
-                    EventData::KeyUpdated(qlog::events::quic::security::KeyUpdated {
-                        key_type:
-                            qlog::events::quic::security::KeyType::Server1RttSecret,
+                    EventData::KeyUpdated(qlog::events::quic::KeyUpdated {
+                        key_type: qlog::events::quic::KeyType::Server1RttSecret,
                         old: None,
                         new: String::new(),
                         generation: None,
@@ -2906,16 +2902,15 @@
                 data: None,
             };
 
-            let ev_data = EventData::PacketReceived(
-                qlog::events::quic::quic::PacketReceived {
+            let ev_data =
+                EventData::PacketReceived(qlog::events::quic::PacketReceived {
                     header: qlog_pkt_hdr,
                     frames: Some(qlog_frames),
                     stateless_reset_token: None,
                     raw: Some(qlog_raw_info),
                     datagram_id: None,
                     trigger: None,
-                },
-            );
+                });
 
             q.add_event_data_with_instant(ev_data, now).ok();
         });
@@ -3011,7 +3006,7 @@
 
                         qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
                             let ev_data = EventData::StreamDataMoved(
-                                qlog::events::quic::quic::StreamDataMoved {
+                                qlog::events::quic::StreamDataMoved {
                                     stream_id: Some(stream_id),
                                     offset: Some(offset),
                                     length: Some(length as u64),
@@ -3071,14 +3066,12 @@
                 );
 
                 qlog_with_type!(
-                    EventType::ConnectivityEventType(
-                        ConnectivityEventType::MtuUpdated
-                    ),
+                    EventType::QuicEventType(QuicEventType::MtuUpdated),
                     self.qlog,
                     q,
                     {
                         let pmtu_data = EventData::MtuUpdated(
-                            qlog::events::quic::connectivity::MtuUpdated {
+                            qlog::events::quic::MtuUpdated {
                                 old: Some(p.recovery.max_datagram_size() as u32),
                                 new: p.pmtud.get_current() as u32,
                                 done: Some(pmtud_probe),
@@ -4520,7 +4513,7 @@
 
         #[cfg(feature = "qlog")]
         let mut qlog_frames: SmallVec<
-            [qlog::events::quic::quic::QuicFrame; 1],
+            [qlog::events::quic::QuicFrame; 1],
         > = SmallVec::with_capacity(frames.len());
 
         for frame in &mut frames {
@@ -4548,7 +4541,7 @@
                     now.duration_since(q.start_time()).as_secs_f32() * 1000.0;
 
                 let ev_data =
-                    EventData::PacketSent(qlog::events::quic::quic::PacketSent {
+                    EventData::PacketSent(qlog::events::quic::PacketSent {
                         header,
                         frames: Some(qlog_frames),
                         stateless_reset_token: None,
@@ -4796,8 +4789,8 @@
         }
 
         qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
-            let ev_data = EventData::StreamDataMoved(
-                qlog::events::quic::quic::StreamDataMoved {
+            let ev_data =
+                EventData::StreamDataMoved(qlog::events::quic::StreamDataMoved {
                     stream_id: Some(stream_id),
                     offset: Some(offset),
                     length: Some(read as u64),
@@ -4806,8 +4799,7 @@
                     additional_info: fin
                         .then_some(DataMovedAdditionalInfo::FinSet),
                     raw: None,
-                },
-            );
+                });
 
             let now = time::Instant::now();
             q.add_event_data_with_instant(ev_data, now).ok();
@@ -4989,8 +4981,8 @@
         self.tx_buffered += sent;
 
         qlog_with_type!(QLOG_DATA_MV, self.qlog, q, {
-            let ev_data = EventData::StreamDataMoved(
-                qlog::events::quic::quic::StreamDataMoved {
+            let ev_data =
+                EventData::StreamDataMoved(qlog::events::quic::StreamDataMoved {
                     stream_id: Some(stream_id),
                     offset: Some(offset),
                     length: Some(sent as u64),
@@ -4999,8 +4991,7 @@
                     additional_info: fin
                         .then_some(DataMovedAdditionalInfo::FinSet),
                     raw: None,
-                },
-            );
+                });
 
             let now = time::Instant::now();
             q.add_event_data_with_instant(ev_data, now).ok();
@@ -7789,22 +7780,22 @@
         #[cfg(feature = "qlog")]
         {
             let cc = match (self.is_established(), self.timed_out, &self.peer_error, &self.local_error) {
-                (false, _, _, _) => qlog::events::quic::connectivity::ConnectionClosed {
+                (false, _, _, _) => qlog::events::quic::ConnectionClosed {
                     owner: Some(TransportOwner::Local),
                     connection_code: None,
                     application_code: None,
                     internal_code: None,
                     reason: Some("Failed to establish connection".to_string()),
-                    trigger: Some(qlog::events::quic::connectivity::ConnectionClosedTrigger::HandshakeTimeout)
+                    trigger: Some(qlog::events::quic::ConnectionClosedTrigger::HandshakeTimeout)
                 },
 
-                (true, true, _, _) => qlog::events::quic::connectivity::ConnectionClosed {
+                (true, true, _, _) => qlog::events::quic::ConnectionClosed {
                     owner: Some(TransportOwner::Local),
                     connection_code: None,
                     application_code: None,
                     internal_code: None,
                     reason: Some("Idle timeout".to_string()),
-                    trigger: Some(qlog::events::quic::connectivity::ConnectionClosedTrigger::IdleTimeout)
+                    trigger: Some(qlog::events::quic::ConnectionClosedTrigger::IdleTimeout)
                 },
 
                 (true, false, Some(peer_error), None) => {
@@ -7814,13 +7805,13 @@
                         (Some(qlog::events::ConnectionErrorCode::Value(peer_error.error_code)), None)
                     };
 
-                    qlog::events::quic::connectivity::ConnectionClosed {
+                    qlog::events::quic::ConnectionClosed {
                         owner: Some(TransportOwner::Remote),
                         connection_code,
                         application_code,
                         internal_code: None,
                         reason: Some(String::from_utf8_lossy(&peer_error.reason).to_string()),
-                        trigger: Some(qlog::events::quic::connectivity::ConnectionClosedTrigger::Error),
+                        trigger: Some(qlog::events::quic::ConnectionClosedTrigger::Error),
                     }
                 },
 
@@ -7831,17 +7822,17 @@
                         (Some(qlog::events::ConnectionErrorCode::Value(local_error.error_code)), None)
                     };
 
-                    qlog::events::quic::connectivity::ConnectionClosed {
+                    qlog::events::quic::ConnectionClosed {
                         owner: Some(TransportOwner::Local),
                         connection_code,
                         application_code,
                         internal_code: None,
                         reason: Some(String::from_utf8_lossy(&local_error.reason).to_string()),
-                        trigger: Some(qlog::events::quic::connectivity::ConnectionClosedTrigger::Error),
+                        trigger: Some(qlog::events::quic::ConnectionClosedTrigger::Error),
                     }
                 },
 
-                _ => qlog::events::quic::connectivity::ConnectionClosed {
+                _ => qlog::events::quic::ConnectionClosed {
                     owner: None,
                     connection_code: None,
                     application_code: None,
@@ -8382,7 +8373,7 @@
             self.stateless_reset_token.map(|s| s.to_be_bytes()).as_ref(),
         );
 
-        EventData::ParametersSet(qlog::events::quic::quic::ParametersSet {
+        EventData::ParametersSet(qlog::events::quic::ParametersSet {
             owner: Some(owner),
             resumption_allowed: None,
             early_data_enabled: None,
diff --git a/quiche/src/recovery/mod.rs b/quiche/src/recovery/mod.rs
index d998db9..1584e26 100644
--- a/quiche/src/recovery/mod.rs
+++ b/quiche/src/recovery/mod.rs
@@ -1173,7 +1173,7 @@
         if emit_event {
             // QVis can't use all these fields and they can be large.
             return Some(EventData::MetricsUpdated(
-                qlog::events::quic::recovery::MetricsUpdated {
+                qlog::events::quic::RecoveryMetricsUpdated {
                     min_rtt: new_min_rtt,
                     smoothed_rtt: new_smoothed_rtt,
                     latest_rtt: new_latest_rtt,