summaryrefslogtreecommitdiffstats
path: root/third_party/rust/qlog/README.md
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/qlog/README.md
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/qlog/README.md')
-rw-r--r--third_party/rust/qlog/README.md316
1 files changed, 316 insertions, 0 deletions
diff --git a/third_party/rust/qlog/README.md b/third_party/rust/qlog/README.md
new file mode 100644
index 0000000000..44df39274e
--- /dev/null
+++ b/third_party/rust/qlog/README.md
@@ -0,0 +1,316 @@
+The qlog crate is an implementation of the qlog [main logging schema],
+[QUIC event definitions], and [HTTP/3 and QPACK event definitions].
+The crate provides a qlog data model that can be used for traces with
+events. It supports serialization and deserialization but defers logging IO
+choices to applications.
+
+The crate uses Serde for conversion between Rust and JSON.
+
+[main logging schema]: https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema
+[QUIC event definitions]:
+https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-quic-events.html
+[HTTP/3 and QPACK event definitions]:
+https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-h3-events.html
+
+Overview
+--------
+qlog is a hierarchical logging format, with a rough structure of:
+
+* Log
+ * Trace(s)
+ * Event(s)
+
+In practice, a single QUIC connection maps to a single Trace file with one
+or more Events. Applications can decide whether to combine Traces from
+different connections into the same Log.
+
+## Buffered Traces with standard JSON
+
+A [`Trace`] is a single JSON object. It contains metadata such as the
+[`VantagePoint`] of capture and the [`Configuration`], and protocol event
+data in the [`Event`] array.
+
+JSON Traces allow applications to appends events to them before eventually
+being serialized as a complete JSON object.
+
+### Creating a Trace
+
+```rust
+let mut trace = qlog::Trace::new(
+ qlog::VantagePoint {
+ name: Some("Example client".to_string()),
+ ty: qlog::VantagePointType::Client,
+ flow: None,
+ },
+ Some("Example qlog trace".to_string()),
+ Some("Example qlog trace description".to_string()),
+ Some(qlog::Configuration {
+ time_offset: Some(0.0),
+ original_uris: None,
+ }),
+ None,
+);
+```
+
+### Adding events to a Trace
+
+Qlog `Event` objects are added to `qlog::Trace.events`.
+
+The following example demonstrates how to log a qlog QUIC `packet_sent` event
+containing a single Crypto frame. It constructs the necessary elements of the
+[`Event`], then appends it to the trace with [`push_event()`].
+
+```rust
+let scid = [0x7e, 0x37, 0xe4, 0xdc, 0xc6, 0x68, 0x2d, 0xa8];
+let dcid = [0x36, 0xce, 0x10, 0x4e, 0xee, 0x50, 0x10, 0x1c];
+
+let pkt_hdr = qlog::events::quic::PacketHeader::new(
+ qlog::events::quic::PacketType::Initial,
+ 0, // packet_number
+ None, // flags
+ None, // token
+ None, // length
+ Some(0x00000001), // version
+ Some(&scid),
+ Some(&dcid),
+);
+
+let frames = vec![qlog::events::quic::QuicFrame::Crypto {
+ offset: 0,
+ length: 0,
+}];
+
+let raw = qlog::events::RawInfo {
+ length: Some(1251),
+ payload_length: Some(1224),
+ data: None,
+};
+
+let event_data =
+ qlog::events::EventData::PacketSent(qlog::events::quic::PacketSent {
+ header: pkt_hdr,
+ frames: Some(frames.into()),
+ is_coalesced: None,
+ retry_token: None,
+ stateless_reset_token: None,
+ supported_versions: None,
+ raw: Some(raw),
+ datagram_id: None,
+ });
+
+trace.push_event(qlog::events::Event::with_time(0.0, event_data));
+```
+
+### Serializing
+
+The qlog crate has only been tested with `serde_json`, however other serializer
+targets might work.
+
+For example, serializing the trace created above:
+
+```rust
+serde_json::to_string_pretty(&trace).unwrap();
+```
+
+would generate the following:
+
+```
+{
+ "vantage_point": {
+ "name": "Example client",
+ "type": "client"
+ },
+ "title": "Example qlog trace",
+ "description": "Example qlog trace description",
+ "configuration": {
+ "time_offset": 0.0
+ },
+ "events": [
+ {
+ "time": 0.0,
+ "name": "transport:packet_sent",
+ "data": {
+ "header": {
+ "packet_type": "initial",
+ "packet_number": 0,
+ "version": "1",
+ "scil": 8,
+ "dcil": 8,
+ "scid": "7e37e4dcc6682da8",
+ "dcid": "36ce104eee50101c"
+ },
+ "raw": {
+ "length": 1251,
+ "payload_length": 1224
+ },
+ "frames": [
+ {
+ "frame_type": "crypto",
+ "offset": 0,
+ "length": 0
+ }
+ ]
+ }
+ }
+ ]
+}
+```
+
+## Streaming Traces JSON Text Sequences (JSON-SEQ)
+
+To help support streaming serialization of qlogs,
+draft-ietf-quic-qlog-main-schema-01 introduced support for RFC 7464 JSON
+Text Sequences (JSON-SEQ). The qlog crate supports this format and provides
+utilities that aid streaming.
+
+A [`TraceSeq`] contains metadata such as the [`VantagePoint`] of capture and
+the [`Configuration`]. However, protocol event data is handled as separate
+lines containing a record separator character, a serialized [`Event`], and a
+newline.
+
+### Creating a TraceSeq
+
+``` rust
+let mut trace = qlog::TraceSeq::new(
+ qlog::VantagePoint {
+ name: Some("Example client".to_string()),
+ ty: qlog::VantagePointType::Client,
+ flow: None,
+ },
+ Some("Example qlog trace".to_string()),
+ Some("Example qlog trace description".to_string()),
+ Some(qlog::Configuration {
+ time_offset: Some(0.0),
+ original_uris: None,
+ }),
+ None,
+);
+```
+
+Create an object with the [`Write`] trait:
+```
+let mut file = std::fs::File::create("foo.sqlog").unwrap();
+```
+
+Create a [`QlogStreamer`] and start serialization to foo.sqlog
+using [`start_log()`]:
+
+```rust
+let mut streamer = qlog::QlogStreamer::new(
+ qlog::QLOG_VERSION.to_string(),
+ Some("Example qlog".to_string()),
+ Some("Example qlog description".to_string()),
+ None,
+ std::time::Instant::now(),
+ trace,
+ qlog::EventImportance::Base,
+ Box::new(file),
+);
+
+streamer.start_log().ok();
+```
+
+### Adding simple events
+
+Once logging has started you can stream events. Simple events can be written in
+one step using [`add_event()`]:
+
+```rust
+let event_data = qlog::events::EventData::MetricsUpdated(
+ qlog::events::quic::MetricsUpdated {
+ min_rtt: Some(1.0),
+ smoothed_rtt: Some(1.0),
+ latest_rtt: Some(1.0),
+ rtt_variance: Some(1.0),
+ pto_count: Some(1),
+ congestion_window: Some(1234),
+ bytes_in_flight: Some(5678),
+ ssthresh: None,
+ packets_in_flight: None,
+ pacing_rate: None,
+ },
+);
+
+let event = qlog::events::Event::with_time(0.0, event_data);
+streamer.add_event(event).ok();
+```
+
+### Adding events with frames
+Some events contain optional arrays of QUIC frames. If the event has
+`Some(Vec<QuicFrame>)`, even if it is empty, the streamer enters a frame
+serializing mode that must be finalized before other events can be logged.
+
+In this example, a `PacketSent` event is created with an empty frame array and
+frames are written out later:
+
+```rust
+let scid = [0x7e, 0x37, 0xe4, 0xdc, 0xc6, 0x68, 0x2d, 0xa8];
+let dcid = [0x36, 0xce, 0x10, 0x4e, 0xee, 0x50, 0x10, 0x1c];
+
+let pkt_hdr = qlog::events::quic::PacketHeader::with_type(
+ qlog::events::quic::PacketType::OneRtt,
+ 0,
+ Some(0x00000001),
+ Some(&scid),
+ Some(&dcid),
+);
+
+let event_data =
+ qlog::events::EventData::PacketSent(qlog::events::quic::PacketSent {
+ header: pkt_hdr,
+ frames: Some(vec![]),
+ is_coalesced: None,
+ retry_token: None,
+ stateless_reset_token: None,
+ supported_versions: None,
+ raw: None,
+ datagram_id: None,
+};
+
+let event = qlog::events::Event::with_time(0.0, event_data);
+
+streamer.add_event(event).ok();
+```
+
+In this example, the frames contained in the QUIC packet
+are PING and PADDING. Each frame is written using the
+[`add_frame()`] method. Frame writing is concluded with
+[`finish_frames()`].
+
+```rust
+let ping = qlog::events::quic::QuicFrame::Ping;
+let padding = qlog::events::quic::QuicFrame::Padding;
+
+streamer.add_frame(ping, false).ok();
+streamer.add_frame(padding, false).ok();
+
+streamer.finish_frames().ok();
+```
+
+Once all events have been written, the log
+can be finalized with [`finish_log()`]:
+
+```rust
+streamer.finish_log().ok();
+```
+
+### Serializing
+
+Serialization to JSON occurs as methods on the [`QlogStreamer`]
+are called. No additional steps are required.
+
+[`Trace`]: struct.Trace.html
+[`TraceSeq`]: struct.TraceSeq.html
+[`VantagePoint`]: struct.VantagePoint.html
+[`Configuration`]: struct.Configuration.html
+[`qlog::Trace.events`]: struct.Trace.html#structfield.events
+[`push_event()`]: struct.Trace.html#method.push_event
+[`packet_sent_min()`]: event/struct.Event.html#method.packet_sent_min
+[`QuicFrame::crypto()`]: enum.QuicFrame.html#variant.Crypto
+[`QlogStreamer`]: struct.QlogStreamer.html
+[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+[`start_log()`]: struct.QlogStreamer.html#method.start_log
+[`add_event()`]: struct.QlogStreamer.html#method.add_event
+[`add_frame()`]: struct.QlogStreamer.html#method.add_frame
+[`finish_frames()`]: struct.QlogStreamer.html#method.finish_frames
+[`finish_log()`]: struct.QlogStreamer.html#method.finish_log \ No newline at end of file