Skip to content

Qlog Event Coverage Report

Qlog Version: draft-02 (draft-ietf-quic-qlog-main-schema-02)
Format: JSON-SEQ (RFC 7464; record separator 0x1E, line-feed terminated)
File Extension: .sqlog
Compatibility: Directly uploadable to qvis

CategoryDefined EventsImplementedCoverage
Connectivity55100%
Transport6583%
Recovery44100%
Security22100%
HTTP/322100%
Total191894.7%

Note: 18 of the 19 events already have macro definitions and actual instrumentation calls. The only uncalled one, QLOG_PACKET_BUFFERED, is marked N/A because the current architecture has no genuine packet-buffering scenario.

EventStatusMacroSource File(s)Call CountNotes
quic:connection_started✅QLOG_CONNECTION_STARTEDconnection_client.cpp, connection_server.cpp2Client / server connection establishment
quic:connection_closed✅QLOG_CONNECTION_CLOSEDconnection_base.cpp1With error_code, reason, trigger
quic:connection_id_updated✅QLOG_CONNECTION_ID_UPDATEDconnection_frame_processor.cpp, connection_id_coordinator.cpp4NEW_CONNECTION_ID、RETIRE_CONNECTION_ID、pool_replenish、cid_rotation
quic:server_listening✅QLOG_SERVER_LISTENINGquic_server.cpp1Server starts listening (uses QlogManager& rather than a trace)
quic:connection_state_updated✅QLOG_EVENT (generic)connection_base.cpp3handshake→connected, connected→closing, closing→draining
EventStatusMacroSource File(s)Call CountNotes
quic:packet_sent✅QLOG_PACKET_SENTsend_control.cpp1With packet_number, type, size, frames
quic:packet_received✅QLOG_PACKET_RECEIVEDconnection_base.cpp1With packet_number, type, size, frames
quic:packets_acked✅QLOG_EVENT (generic)send_control.cpp1With ack_ranges, ack_delay
quic:packet_dropped✅QLOG_PACKET_DROPPEDconnection_base.cpp, version_negotiator.cpp7closing_state_decrypt_failure, key_unavailable×2, draining_state, unsupported_version, decryption_failed, version_negotiation_downgrade
quic:stream_state_updated✅QLOG_STREAM_STATE_UPDATEDconnection_stream_manager.cpp1Stream state change
quic:packet_buffered⬜ N/AQLOG_PACKET_BUFFERED—0Macro defined; no genuine packet-buffering scenario in the current architecture
EventStatusMacroSource File(s)Call CountNotes
recovery:metrics_updated✅QLOG_METRICS_UPDATEDsend_control.cpp1RTT, cwnd, bytes_in_flight, ssthresh, pacing_rate
recovery:congestion_state_updated✅QLOG_CONGESTION_STATE_UPDATED5 CC algorithm files22Reno(3), CUBIC(6), BBRv1(4), BBRv2(4), BBRv3(5)
recovery:packet_lost✅QLOG_PACKET_LOSTsend_control.cpp1Packet loss detected
recovery:marked_for_retransmit✅QLOG_MARKED_FOR_RETRANSMITsend_control.cpp2Retransmit triggered by loss_detected and pto_expired
EventStatusMacroSource File(s)Call CountNotes
security:key_updated✅QLOG_KEY_UPDATEDconnection_crypto.cpp9SetReadSecret(1), SetWriteSecret(1), v2 version-negotiation Initial reinstall(2), RekeyInitialForVersion(2), initiating key update(1), peer key-update response(2)
security:key_discarded✅QLOG_KEY_DISCARDEDconnection_base.cpp2Discard initial & handshake keys after handshake_done
EventStatusMacroSource File(s)Call CountNotes
http3:frame_created✅QLOG_HTTP3_FRAME_CREATEDreq_resp_base_stream.cpp3DATA frames, HEADERS frames, batched DATA frame sends
http3:frame_parsed✅QLOG_HTTP3_FRAME_PARSEDframe_decoder.cpp1H3 frame decoding completed
Algorithmslow_start → congestion_avoidance→ recoveryrecovery → congestion_avoidance→ application_limitedTotal Events
Reno✅ (ssthresh)✅ (loss/ECN)✅ (ack after recovery)❌ N/A3
CUBIC✅ (ssthresh + HyStart)✅ (loss + ECN)✅ (ack after recovery)❌ N/A6
BBR v1✅ (startup exit)✅ (loss in startup)❌ N/A✅ (ProbeRtt enter/exit)4
BBR v2✅ (startup exit)✅ (loss in startup)❌ N/A✅ (ProbeRtt enter/exit)4
BBR v3✅ (startup exit + ECN)✅ (loss in startup)❌ N/A✅ (ProbeRtt enter/exit)5

State Mapping for BBR (qlog standard → BBR mode):

  • slow_start → Mode::kStartup
  • congestion_avoidance → Mode::kProbeBw (steady-state probing)
  • recovery → Mode::kDrain (after loss in startup)
  • application_limited → Mode::kProbeRtt (min_rtt probing)
MacroCall CountFiles
QLOG_CONGESTION_STATE_UPDATED22reno(3), cubic(6), bbr_v1(4), bbr_v2(4), bbr_v3(5)
QLOG_KEY_UPDATED9connection_crypto.cpp
QLOG_PACKET_DROPPED7connection_base.cpp(6), version_negotiator.cpp(1)
QLOG_CONNECTION_ID_UPDATED4connection_frame_processor.cpp(2), connection_id_coordinator.cpp(2)
QLOG_KEY_DISCARDED2connection_base.cpp
QLOG_EVENT (generic)4send_control.cpp(1), connection_base.cpp(3)
QLOG_HTTP3_FRAME_CREATED3req_resp_base_stream.cpp
QLOG_CONNECTION_STARTED2connection_client.cpp, connection_server.cpp
QLOG_MARKED_FOR_RETRANSMIT2send_control.cpp
QLOG_PACKET_SENT1send_control.cpp
QLOG_PACKET_RECEIVED1connection_base.cpp
QLOG_METRICS_UPDATED1send_control.cpp
QLOG_CONNECTION_CLOSED1connection_base.cpp
QLOG_PACKET_LOST1send_control.cpp
QLOG_STREAM_STATE_UPDATED1connection_stream_manager.cpp
QLOG_HTTP3_FRAME_PARSED1frame_decoder.cpp
QLOG_SERVER_LISTENING1quic_server.cpp
QLOG_PACKET_BUFFERED0— (N/A: no applicable scenario)
Total6313 files

Based on benchmark results (test/benchmarks/qlog_overhead_bench.cpp, 442 lines, 16+ benchmarks):

MetricValue
Single event latency (PacketSent)~1.5 μs
Single event latency (RecoveryMetrics)~1.8 μs
Throughput (sustained)~690K events/sec
Null trace overhead< 1 ns (zero-cost when disabled)
Serialization only (PacketSent)~485 ns
Event whitelist filter~101 ns (fast-path rejection)
Multi-connection scalingLinear (no degradation up to 50 connections)
AsyncWriter queue stressTested with sustained high-volume writes
DimensionBenchmarksDescription
Single Event Latency3PacketSent, RecoveryMetrics, ConnectionStarted
Throughput1Sustained event logging rate
AsyncWriter Queue1Queue pressure under sustained writes
Sampling Rate1Performance impact of different sampling rates
Serialization2JSON-SEQ serialization overhead, whitelist filtering
Manager Lifecycle1Create/destroy trace lifecycle cost
Multi-connection1Concurrent writes from 50 connections
Null/Disabled1Zero-cost verification when qlog disabled

Unit Tests (10 files in test/unit_test/common/qlog/)

Section titled “Unit Tests (10 files in test/unit_test/common/qlog/)”
Test FileSizeKey Tests
qlog_e2e_output_test.cpp20.3 KB7 tests: complete lifecycle, field correctness, multi-connection isolation, event ordering, whitelist filtering, large volume, vantage point
qlog_event_test.cpp24.0 KBEvent data creation and serialization for all event types
qlog_serializer_test.cpp22.3 KBJSON-SEQ format compliance, timestamp precision, field completeness
qlog_async_writer_test.cpp15.5 KBAsync write queue, flush, backpressure
qlog_trace_test.cpp14.2 KBTrace lifecycle, whitelist/blacklist filtering
qlog_manager_test.cpp13.0 KBManager singleton, trace management, config propagation
qlog_integration_test.cpp12.1 KBCross-component integration scenarios
qlog_types_test.cpp9.8 KBType conversion (PacketType, FrameType, VantagePoint)
qlog_config_test.cpp8.4 KBConfiguration validation and defaults
qlog_sampling_test.cpp7.0 KBSampling rate behavior
ScriptSizeDescription
scripts/verify_qlog_format.py379 linesRFC 7464 format validation, field checks, timestamp monotonicity
scripts/verify_qlog_qvis.py—qvis.quictools.info compatibility validation
QlogManager (singleton)
├── QlogConfig (global: enabled, output_dir, sampling_rate, whitelist/blacklist)
├── AsyncWriter (async write thread)
└── traces_ map: connection_id -> QlogTrace
├── IQlogSerializer (JsonSeqSerializer)
├── ShouldLogEvent() whitelist/blacklist filtering
└── WriteEvent() -> AsyncWriter
└── output .sqlog files (JSON-SEQ format)
Macro call chain:
QLOG_PACKET_SENT(trace, data)
-> trace->LogPacketSent(time_us, data)
-> LogEvent(time_us, "quic:packet_sent", unique_ptr<PacketSentData>)
-> ShouldLogEvent() filtering
-> SerializeEvent() JSON serialization
-> AsyncWriter::WriteEvent() async write
RevisionChangeImpact
1Initial report12/19 events (63%)
2Major update: Corrected coverage from 63% to 94.7% (18/19)Added: connection_id_updated, server_listening, stream_state_updated, packet_dropped, key_updated, key_discarded, marked_for_retransmit, http3:frame_created, http3:frame_parsed. Total macros in src/: 57 calls in 13 files
3Data audit: reconciled the macro-usage summary against the per-event tables and sourceKEY_UPDATED 6→9, PACKET_DROPPED 5→7, KEY_DISCARDED 4→2 (file attribution fixed); total 57→63 per grep counts