diff --git a/index.html b/index.html index ad67ad5c..d5f33fac 100644 --- a/index.html +++ b/index.html @@ -92,6 +92,24 @@
HTTP/3 qlog event definitions | +plain text | +same as main | +
Main logging schema for qlog | +plain text | +diff with main | +
QUIC event definitions for qlog | +plain text | +same as main | +
Internet-Draft | +HTTP/3 qlog event definitions | +June 2024 | +
Marx, et al. | +Expires 29 December 2024 | +[Page] | +
This document describes concrete qlog event definitions and their metadata for +HTTP/3-related events. These events can then be embedded in the higher +level schema defined in [QLOG-MAIN].¶
+Note to RFC editor: Please remove this section before publication.¶
+Feedback and discussion are welcome at +https://github.com/quicwg/qlog. Readers are +advised to refer to the "editor's draft" at that URL for an up-to-date version +of this document.¶
+Concrete examples of integrations of this schema in +various programming languages can be found at +https://github.com/quiclog/qlog/.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 29 December 2024.¶
++ Copyright (c) 2024 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+This document describes the values of the qlog name ("category" + "event") and +"data" fields and their semantics for the HTTP/3 protocol [HTTP/3] and some +of extensions (see [EXTENDED-CONNECT], [H3_PRIORITIZATION] +and [H3-DATAGRAM]).¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+The event and data structure definitions in ths document are expressed +in the Concise Data Definition Language [CDDL] and its +extensions described in [QLOG-MAIN].¶
+The following fields from [QLOG-MAIN] are imported and used: name, category, +type, data, group_id, protocol_type, importance, RawInfo, and time-related +fields.¶
+As is the case for [QLOG-MAIN], the qlog schema definitions in this document +are intentionally agnostic to serialization formats. The choice of format is an +implementation decision.¶
+This document describes how HTTP/3 can be expressed in qlog using the schema +defined in [QLOG-MAIN]. HTTP/3 events are defined with a category, a name (the +concatenation of "category" and "event"), an "importance", an optional +"trigger", and "data" fields.¶
+Some data fields use complex datastructures. These are represented as enums or +re-usable definitions, which are grouped together on the bottom of this document +for clarity.¶
+When any event from this document is included in a qlog trace, the +"protocol_type" qlog array field MUST contain an entry with the value "HTTP3":¶
+The events described in this document can be used with or without logging the +related QUIC events defined in [QLOG-QUIC]. If used with QUIC events, the QUIC +document takes precedence in terms of recommended filenames and trace separation +setups.¶
+If used without QUIC events, it is recommended that the implementation assign a +globally unique identifier to each HTTP/3 connection. This ID can then be used as +the value of the qlog "group_id" field, as well as the qlog filename or file +identifier, potentially suffixed by the vantagepoint type (For example, +abcd1234_server.qlog would contain the server-side trace of the connection with +GUID abcd1234).¶
+This document defines events in two categories, written as lowercase to follow +convention: h3 (Section 4).¶
+As described in Section 3.4.2 of [QLOG-MAIN], the qlog "name" field is the +concatenation of category and type.¶
+Table 1 summarizes the name value of each event type that is defined +in this specification.¶
+Name value | +Importance | +Definition | +
---|---|---|
h3:parameters_set | +Base | ++ Section 4.1 + | +
h3:parameters_restored | +Base | ++ Section 4.2 + | +
h3:stream_type_set | +Base | ++ Section 4.3 + | +
h3:priority_updated | +Base | ++ Section 4.4 + | +
h3:frame_created | +Core | ++ Section 4.5 + | +
h3:frame_parsed | +Core | ++ Section 4.6 + | +
h3:datagram_created | +Base | ++ Section 4.7 + | +
h3:datagram_parsed | +Base | ++ Section 4.8 + | +
h3:push_resolved | +Extra | ++ Section 4.9 + | +
HTTP/3 events extend the $ProtocolEventData
extension point defined in
+[QLOG-MAIN]. Additionally, they allow for direct extensibility by their use of
+per-event extension points via the $$
CDDL "group socket" syntax, as also
+described in [QLOG-MAIN].¶
HTTP events are logged when a certain condition happens at the application +layer, and there isn't always a one to one mapping between HTTP and QUIC events. +The exchange of data between the HTTP and QUIC layer is logged via the +"stream_data_moved" and "datagram_data_moved" events in [QLOG-QUIC].¶
+HTTP/3 frames are transmitted on QUIC streams, which allows them to span +multiple QUIC packets. Some implementations might send a single large frame, +rather than a sequence of smaller frames, in order to amortize frame header +overhead. HTTP/3 frame headers are represented by the frame_created +(Section 4.5) and frame_parsed (Section 4.6) events. Subsequent +frame payload data transfer is indicated by stream_data_moved events. +Furthermore, stream_data_moved events can appear before frame_parsed events +because implementations need to read data from a stream in order to parse the +frame header.¶
+The parameters_set
event contains HTTP/3 and QPACK-level settings, mostly
+those received from the HTTP/3 SETTINGS frame. It has Base importance level; see
+Section 9.2 of [QLOG-MAIN].¶
All these parameters are typically set once and never change. However, they
+might be set at different times during the connection, therefore a qlog can have
+multiple instances of parameters_set
with different fields set.¶
The "owner" field reflects how Settings are exchanged on a connection. Sent +settings have the value "local" and received settings have the value +"received".¶
+The parameters_set
event can contain any number of unspecified fields. This
+allows for representation of reserved settings (aka GREASE) or ad-hoc support
+for extension settings that do not have a related qlog schema definition.¶
When using QUIC 0-RTT, HTTP/3 clients are expected to remember and reuse the
+server's SETTINGs from the previous connection. The parameters_restored
event
+is used to indicate which HTTP/3 settings were restored and to which values when
+utilizing 0-RTT. It has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
The stream_type_set
event conveys when a HTTP/3 stream type becomes known; see
+Sections 6.1 and 6.2 of [HTTP/3]. It has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
Client bidirectional streams always have a stream_type value of "request". +Server bidirectional streams have no defined use, although extensions could +change that.¶
+Unidirectional streams in either direction begin with with a variable-length +integer type. Where the type is not known, the stream_type value of "unknown" +type can be used and the value captured in the stream_type_bytes field; a +numerical value without variable-length integer encoding.¶
+The generic $H3StreamType
is defined here as a CDDL "type socket" extension
+point. It can be extended to support additional HTTP/3 stream types.¶
Emitted when the priority of a request stream or push stream is initialized or +updated through mechanisms defined in [RFC9218]. For example, the priority +can be updated through signals received from client and/or server (e.g., in +HTTP/3 HEADERS or PRIORITY_UPDATE frames) or it can be changed or overridden due +to local policies. The event has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
+The frame_created
event is emitted when the HTTP/3 framing actually happens.
+It has Core importance level; see Section 9.2 of [QLOG-MAIN].¶
This event does not necessarily coincide with HTTP/3 data getting passed to the
+QUIC layer. For that, see the stream_data_moved
event in [QLOG-QUIC].¶
The frame_parsed
event is emitted when the HTTP/3 frame is parsed. It has Core
+importance level; see Section 9.2 of [QLOG-MAIN].¶
This event is not necessarily the same as when the HTTP/3 data is actually
+received on the QUIC layer. For that, see the stream_data_moved
event in
+[QLOG-QUIC].¶
The datagram_created
event is emitted when an HTTP/3 Datagram is created (see
+[RFC9297]). It has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
This event does not necessarily coincide with the HTTP/3 Datagram getting passed
+to the QUIC layer. For that, see the datagram_data_moved
event in
+[QLOG-QUIC].¶
The datagram_parsed
event is emitted when the HTTP/3 Datagram is parsed (see
+[RFC9297]). It has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
This event is not necessarily the same as when the HTTP/3 Datagram is actually
+received on the QUIC layer. For that, see the datagram_data_moved
event in
+[QLOG-QUIC].¶
The push_resolved
event is emitted when a pushed resource (Section 4.6 of [HTTP/3]) is successfully claimed (used) or, conversely, abandoned (rejected)
+by the application on top of HTTP/3 (e.g., the web browser). This event provides
+additional context that can is aid debugging issues related to server push. It
+has Extra importance level; see Section 9.2 of [QLOG-MAIN].¶
The following data field definitions can be used in HTTP/3 events.¶
+ +The generic $H3Frame
is defined here as a CDDL "type socket" extension point.
+It can be extended to support additional HTTP/3 frame types.¶
The HTTP/3 frame types defined in this document are as follows:¶
+The generic $H3Datagram
is defined here as a CDDL "type socket" extension
+point. It can be extended to support additional HTTP/3 datagram types. This
+document intentionally does not define any specific qlog schemas for specific
+HTTP/3 Datagram types.¶
This represents an uncompressed, plaintext HTTP Headers frame (e.g., no QPACK +compression is applied).¶
+For example:¶
+The settings field can contain zero or more entries. Each setting has a name +field, which corresponds to Setting Name as defined (or as would be defined if +registered) in the "HTTP/3 Settings" registry maintained at +https://www.iana.org/assignments/http3-parameters.¶
+An endpoint that receives unknown settings is not able to log a specific name.
+Instead, the name value of "unknown" can be used and the value captured in the
+name_bytes
field; a numerical value without variable-length integer encoding.¶
The PRIORITY_UPDATE frame is defined in [RFC9218].¶
+The frame_type_bytes field is the numerical value without variable-length +integer encoding.¶
+The H3ApplicationError extends the general $ApplicationError +definition in the qlog QUIC document, see [QLOG-QUIC].¶
++; ensure HTTP errors are properly validated in QUIC events as well +; e.g., QUIC's ConnectionClose Frame +$ApplicationError /= H3ApplicationError +¶ +
The security and privacy considerations discussed in [QLOG-MAIN] apply to this +document as well.¶
+There are no IANA considerations.¶
+Much of the initial work by Robin Marx was done at the Hasselt and KU Leuven +Universities.¶
+Thanks to Jana Iyengar, Brian Trammell, Dmitri Tikhonov, Stephen Petrides, Jari +Arkko, Marcus Ihlar, Victor Vasiliev, Mirja Kühlewind, Jeremy Lainé, Kazu +Yamamoto, Christian Huitema and Hugo Landau for their feedback and suggestions.¶
+This section is to be removed before publishing as an RFC.¶
+Renamed 'http' category to 'h3' (#300)¶
+H3HTTPField.value is now optional (#296)¶
+Added definitions for RFC9297 (HTTP/3 Datagram extension) (#310)¶
+Added definitions for RFC9218 (HTTP Extensible Prioritizations extension) (#312)¶
+Added definitions for RFC9220 (Extended Connect extension) (#325)¶
+Editorial and formatting changes (#298, #258, #299, #304, #327)¶
+Renamed HTTPStreamType data to request (#222)¶
+Added HTTPStreamType value unknown (#227)¶
+Added HTTPUnknownFrame (#224)¶
+Replaced old and new fields with stream_type in HTTPStreamTypeSet (#240)¶
+Changed HTTPFrame to a CDDL plug type (#257)¶
+Moved data definitions out of the appendix into separate sections¶
+Added overview Table of Contents¶
+No changes - new draft to prevent expiration¶
+Change the data definition language from TypeScript to CDDL (#143)¶
+Major changes:¶
+Moved data_moved from http to transport. Also made the "from" and "to" fields +flexible strings instead of an enum (#111,#65)¶
+Moved packet_type fields to PacketHeader. Moved packet_size field out of +PacketHeader to RawInfo:length (#40)¶
+Made events that need to log packet_type and packet_number use a header field +instead of logging these fields individually¶
+Added support for logging retry, stateless reset and initial tokens (#94,#86,#117)¶
+Moved separate general event categories into a single category "generic" (#47)¶
+Added "transport:connection_closed" event (#43,#85,#78,#49)¶
+Added version_information and alpn_information events (#85,#75,#28)¶
+Added parameters_restored events to help clarify 0-RTT behaviour (#88)¶
+Smaller changes:¶
+Merged loss_timer events into one loss_timer_updated event¶
+Field data types are now strongly defined (#10,#39,#36,#115)¶
+Renamed qpack instruction_received and instruction_sent to instruction_created +and instruction_parsed (#114)¶
+Updated qpack:dynamic_table_updated.update_type. It now has the value "inserted" +instead of "added" (#113)¶
+Updated qpack:dynamic_table_updated. It now has an "owner" field to +differentiate encoder vs decoder state (#112)¶
+Removed push_allowed from http:parameters_set (#110)¶
+Removed explicit trigger field indications from events, since this was moved to +be a generic property of the "data" field (#80)¶
+Updated transport:connection_id_updated to be more in line with other similar +events. Also dropped importance from Core to Base (#45)¶
+Added length property to PaddingFrame (#34)¶
+Added packet_number field to transport:frames_processed (#74)¶
+Added a way to generically log packet header flags (first 8 bits) to +PacketHeader¶
+Added additional guidance on which events to log in which situations (#53)¶
+Added "simulation:scenario" event to help indicate simulation details¶
+Added "packets_acked" event (#107)¶
+Added "datagram_ids" to the datagram_X and packet_X events to allow tracking of +coalesced QUIC packets (#91)¶
+Extended connection_state_updated with more fine-grained states (#49)¶
+Event and category names are now all lowercase¶
+Added many new events and their definitions¶
+"type" fields have been made more specific (especially important for PacketType +fields, which are now called packet_type instead of type)¶
+Events are given an importance indicator (issue #22)¶
+Event names are more consistent and use past tense (issue #21)¶
+Triggers have been redefined as properties of the "data" field and updated for most events (issue #23)¶
+Internet-Draft | +Main logging schema for qlog | +June 2024 | +
Marx, et al. | +Expires 29 December 2024 | +[Page] | +
This document defines qlog, an extensible high-level schema for a standardized +logging format. It allows easy sharing of data, benefitting common debug and +analysis methods and tooling. The high-level schema is independent of protocol; +separate documents extend qlog for protocol-specific data. The schema is also +independent of serialization format, allowing logs to be represented in many +ways such as JSON, CSV, or protobuf.¶
+Note to RFC editor: Please remove this section before publication.¶
+Feedback and discussion are welcome at +https://github.com/quicwg/qlog. Readers are +advised to refer to the "editor's draft" at that URL for an up-to-date version +of this document.¶
+Concrete examples of integrations of this schema in +various programming languages can be found at +https://github.com/quiclog/qlog/.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 29 December 2024.¶
++ Copyright (c) 2024 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+Endpoint logging is a useful strategy for capturing and understanding how +applications using network protocols are behaving, particularly where protocols +have an encrypted wire image that restricts observers' ability to see what is +happening.¶
+Many applications implement logging using a custom, non-standard logging format. +This has an effect on the tools and methods that are used to +analyze the logs, for example to perform root cause analysis of an +interoperability failure between distinct implementations. A lack of a common +format impedes the development of common tooling that can be used by all parties +that have access to logs.¶
+This document defines qlog, an extensible high-level schema and harness that +provides a shareable, aggregatable and structured logging format. This +high-level schema is independent of protocol, with logging entries for specific +protocols and use cases being defined in other documents (see for example +[QLOG-QUIC] for QUIC and [QLOG-H3] for HTTP/3-related event definitions).¶
+The goal of this high-level schema is to provide amenities and default +characteristics that each logging file should contain (or should be able to +contain), such that generic and reusable toolsets can be created that can deal +with logs from a variety of different protocols and use cases.¶
+As such, qlog provides versioning, metadata inclusion, log aggregation, event +grouping and log file size reduction techniques.¶
+The qlog schema can be serialized in many ways (e.g., JSON, CBOR, protobuf, +etc). This document describes only how to employ [JSON], its subset +[I-JSON], and its streamable derivative +[JSON-Text-Sequences].¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+To define events and data structures, all qlog documents use the Concise Data
+Definition Language [CDDL]. This document uses the basic syntax, the
+specific text
, uint
, float32
, float64
, bool
, and any
types, as well
+as the .default
, .size
, and .regexp
control operators, the ~
unwrapping
+operator, and the $
and $$
extension points syntax from [CDDL].¶
Additionally, this document defines the following custom types for +clarity:¶
+All timestamps and time-related values (e.g., offsets) in qlog are
+logged as float64
in the millisecond resolution.¶
Other qlog documents can define their own CDDL-compatible (struct) types +(e.g., separately for each Packet type that a protocol supports).¶
+The ordering of member fields in qlog CDDL type definitions is not significant. +The ordering of member fields in the serialization formats defined in this +document, JSON (Section 10.1) and JSON Text Sequences (Section 10.2), +is not significant and qlog tools MUST NOT assume so. Other qlog serialization +formats MAY define field order significance, if they do they MUST define +requirements for qlog tools supporting those formats.¶
+Note to RFC editor: Please remove the following text in this section before +publication.¶
+The main general CDDL syntax conventions in this document a reader +should be aware of for easy reading comprehension are:¶
+? obj
: this object is optional¶
TypeName1 / TypeName2
: a union of these two types (object can be either type 1 OR
+type 2)¶
obj: TypeName
: this object has this concrete type¶
obj: [* TypeName]
: this object is an array of this type with
+minimum size of 0 elements¶
obj: [+ TypeName]
: this object is an array of this type with
+minimum size of 1 element¶
TypeName = ...
: defines a new type¶
EnumName = "entry1" / "entry2" / entry3 / ...
: defines an enum¶
StructName = { ... }
: defines a new struct type¶
;
: single-line comment¶
* text => any
: special syntax to indicate 0 or more fields that
+have a string key that maps to any value. Used to indicate a generic
+JSON object.¶
All timestamps and time-related values (e.g., offsets) in qlog are
+logged as float64
in the millisecond resolution.¶
Other qlog documents can define their own CDDL-compatible (struct) types +(e.g., separately for each Packet type that a protocol supports).¶
+Serialization examples in this document use JSON ([JSON]) unless +otherwise indicated.¶
+The main tenets for the qlog schema design are:¶
+Streamable, event-based logging¶
+A flexible format that can reduce log producer overhead, at the cost of +increased complexity for consumers (e.g. tools)¶
+Extensible and pragmatic¶
+Aggregation and transformation friendly (e.g., the top-level element +for the non-streaming format is a container for individual traces, +group_ids can be used to tag events to a particular context)¶
+Metadata is stored together with event data¶
+A qlog using the QlogFile schema can contain several individual traces and logs +from multiple vantage points that are in some way related. The top-level element +in this schema defines only a small set of "header" fields and an array of +component traces, defined in Figure 2 as:¶
+The required "qlog_version" field MUST have the value "0.4".¶
+The optional "qlog_format" field indicates the serialization format. Its value +MUST either be one of the options defined in this document (i.e., +Section 10) or the field MUST be omitted entirely. When the field is +omitted the default value of "JSON" applies.¶
+The optional "title" and "description" fields provide additional free-text +information about the file.¶
+The optional "traces" field contains an array of qlog traces (Section 3.2), each +of which contain metadata and an array of qlog events (Section 6).¶
+In order to make it easier to parse and identify qlog files and their +serialization format, the "qlog_version" and "qlog_format" fields and their +values SHOULD be in the first 256 characters/bytes of the resulting log file.¶
+Where a qlog file is serialized to a JSON format, one of the downsides is that +it is inherently a non-streamable format. Put differently, it is not possible to +simply append new qlog events to a log file without "closing" this file at the +end by appending "]}]}". Without these closing tags, most JSON parsers will be +unable to parse the file entirely. The alternative QlogFileSeq +(Section 4) is better suited to streaming.¶
+JSON serialization example:¶
+It can be advantageous to group several related qlog traces together in a single +file. For example, it is possible to simultaneously perform logging on the +client, on the server, and on a single point on their common network path. For +analysis, it is useful to aggregate these three individual traces together into +a single file, so it can be uniquely stored, transferred, and annotated.¶
+The QlogFile "traces" field is an array that contains a list of individual qlog +traces. When capturing a qlog at a vantage point, it is expected that the traces +field contains a single entry. Files can be aggregated, for example as part of a +post-processing operation, by copying the traces in component to files into the +combined "traces" array of a new, aggregated qlog file.¶
+The exact conceptual definition of a Trace can be fluid. For example, a trace +could contain all events for a single connection, for a single endpoint, for a +single measurement interval, for a single protocol, etc. In the normal use case +however, a trace is a log of a single data flow collected at a single location +or vantage point. For example, for QUIC, a single trace only contains events for +a single logical QUIC connection for either the client or the server.¶
+A Trace contains some metadata in addition to qlog events, defined in +Figure 4 as:¶
+The optional "title" and "description" fields provide additional free-text +information about the trace.¶
+The optional "common_fields" field is described in Section 6.9.¶
+The optional "vantage_point" field is described in Section 5.¶
+The semantics and context of the trace can mainly be deduced from the entries in +the "common_fields" list and "vantage_point" field.¶
+JSON serialization example:¶
+A TraceError indicates that an attempt to find/convert a file for inclusion in +the aggregated qlog was made, but there was an error during the process. Rather +than silently dropping the erroneous file, it can be explicitly included in the +qlog file as an entry in the "traces" array, defined in Figure 6 as:¶
+JSON serialization example:¶
+Note that another way to combine events of different traces in a single qlog file +is through the use of the "group_id" field, discussed in Section 6.7.¶
+A qlog file using the QlogFileSeq schema can be serialized to a streamable JSON +format called JSON Text Sequences (JSON-SEQ) ([RFC7464]). The top-level +element in this schema defines only a small set of "header" fields and an array +of component traces, defined in Figure 2 as:¶
+The required "qlog_format" field MUST have the value "JSON-SEQ".¶
+The required "qlog_version" field MUST have the value "0.4".¶
+The optional "title" and "description" fields provide additional free-text +information about the file.¶
+The optional "trace" field contains a singular trace metadata. All qlog events +in the file are related to this trace.¶
+JSON-SEQ serialization example:¶
+For further information about serialization, see Section 10.2.¶
+ +A VantagePoint describes the vantage point from which a trace originates, +defined in Figure 11 as:¶
+JSON serialization examples:¶
+The flow field is only required if the type is "network" (for example, the trace +is generated from a packet capture). It is used to disambiguate events like +"packet sent" and "packet received". This is indicated explicitly because for +multiple reasons (e.g., privacy) data from which the flow direction can be +otherwise inferred (e.g., IP addresses) might not be present in the logs.¶
+Meaning of the different values for the flow field: + * "client" indicates that this vantage point follows client data flow semantics (a + "packet sent" event goes in the direction of the server). + * "server" indicates that this vantage point follow server data flow semantics (a + "packet sent" event goes in the direction of the client). + * "unknown" indicates that the flow's direction is unknown.¶
+Depending on the context, tools confronted with "unknown" values in the +vantage_point can either try to heuristically infer the semantics from +protocol-level domain knowledge (e.g., in QUIC, the client always sends the first +packet) or give the user the option to switch between client and server +perspectives manually.¶
+A qlog event is specified as a generic object with a number of member +fields and their associated data. Depending on the protocol and use case, the +exact member field names and their formats can differ across implementations. This +section lists the main, pre-defined and reserved field names with specific +semantics and expected corresponding value formats.¶
+An Event is defined in Figure 13 as:¶
+Each qlog event MUST contain the mandatory fields: "time" +(Section 6.1), "name" (Section 6.2), and "data" (Section 6.3).¶
+Each qlog event MAY contain the optional fields: "time_format" +(Section 6.1), "protocol_type" (Section 6.5), "trigger" +(Section 6.6), and "group_id" (Section 6.7).¶
+Multiple events can appear in a Trace or TraceSeq and they might contain fields +with identical values. It is possible to optimize out this duplication using +"common_fields" (Section 6.9).¶
+The specific values for each of these fields and their semantics are defined in +separate documents, depending on protocol or use case. For example: event +definitions for QUIC and HTTP/3 can be found in [QLOG-QUIC] and [QLOG-H3].¶
+Events are intended to be extended with custom fields, therefore they MAY +contain other fields not defined in this document. Custom fields may be known or +unknown to tools. Tools SHOULD allow for the presence of unknown event fields, +but their semantics depend on the context of the log usage.¶
+JSON serialization:¶
+An event's "time" field indicates the timestamp at which the event occurred. Its value is +typically the Unix timestamp since the 1970 epoch (number of milliseconds since +midnight UTC, January 1, 1970, ignoring leap seconds). However, qlog supports two +more succinct timestamps formats to allow reducing file size. The employed format +is indicated in the "time_format" field, which allows one of three values: +"absolute", "delta" or "relative".¶
+Absolute: Include the full absolute timestamp with each event. This approach +uses the largest amount of characters. This is also the default value of the +"time_format" field.¶
+Delta: Delta-encode each time value on the previously logged value. The first +event in a trace typically logs the full absolute timestamp. This approach uses +the least amount of characters.¶
+Relative: Specify a full "reference_time" timestamp (typically this is done +up-front in "common_fields", see Section 6.9) and include only +relatively-encoded values based on this reference_time with each event. The +"reference_time" value is typically the first absolute timestamp. This approach +uses a medium amount of characters.¶
+The first option is good for stateless loggers, the second and third for stateful +loggers. The third option is generally preferred, since it produces smaller files +while being easier to reason about. An example for each option can be seen in +Figure 16.¶
+One of these options is typically chosen for the entire trace (put differently: +each event has the same value for the "time_format" field). Each event MUST +include a timestamp in the "time" field.¶
+Events in each individual trace SHOULD be logged in strictly ascending timestamp +order (though not necessarily absolute value, for the "delta" format). Tools MAY +sort all events on the timestamp before processing them, though are not required +to (as this could impose a significant processing overhead). This can be a problem +especially for multi-threaded and/or streaming loggers, who could consider using a +separate post-processor to order qlog events in time if a tool do not provide this +feature.¶
+Timestamps do not have to use the UNIX epoch timestamp as their reference. For +example for privacy considerations, any initial reference timestamps (for example +"endpoint uptime in ms" or "time since connection start in ms") can be chosen. +Tools SHOULD NOT assume the ability to derive the absolute Unix timestamp from +qlog traces, nor allow on them to relatively order events across two or more +separate traces (in this case, clock drift should also be taken into account).¶
+Events differ mainly in the type of metadata associated with them. The "name" +field is an identifier that parsers can use to decide how to interpret the event +metadata contained in the "data" field (see Section 6.3).¶
+Event names indicate a category and type. The "name" field MUST contain a +non-empty character sequence representing a category, followed by a colon (':'), +followed by a non-empty character sequence representing a type.¶
+Category allows a higher-level grouping of events per specific event type. For +example for QUIC and HTTP/3, the different categories could be "quic", "h3", +"qpack", and "recovery". Within these categories, the event type provides +additional granularity. For example for QUIC and HTTP/3, within the "quic" +category, there would be "packet_sent" and "packet_received" events.¶
+JSON serialization example:¶
+An event's "data" field is a generic key-value map (e.g., JSON object). It +defines the per-event metadata that is to be logged. Its specific subfields and +their semantics are defined per specific event type. For example, data field +definitions for QUIC and HTTP/3 can be found in [QLOG-QUIC] and [QLOG-H3].¶
+In order to keep qlog fully extensible, two separate CDDL extension points +("sockets" or "plugs") are used to fully define data fields.¶
+Firstly, to allow existing data field definitions to be extended (for example by
+adding an additional field needed for a new protocol feature), a CDDL "group
+socket" is used. This takes the form of a subfield with a name of
+* $$CATEGORY-NAME-extension
. This field acts as a placeholder that can later be
+replaced with newly defined fields by assigning them to the socket with the
+//=
operator. Multiple extensions can be assigned to the same group socket. An
+example is shown in Figure 18.¶
Secondly, to allow documents to define fully new event data field definitions
+(as opposed to extend existing ones), a CDDL "type socket" is used. For this
+purpose, the type of the "data" field in the qlog Event type (see Figure 13)
+is the extensible $ProtocolEventData
type. This field acts as an open enum of
+possible types that are allowed for the data field. As such, any new event data
+field is defined as its own CDDL type and later merged with the existing
+$ProtocolEventData
enum using the /=
extension operator. Any generic
+key-value map type can be assigned to $ProtocolEventData
(the only common
+"data" subfield defined in this document is the optional trigger
field, see
+Section 6.6). An example of this setup is shown in
+Figure 19.¶
Documents defining new qlog events MUST properly extend $ProtocolEventData
+when defining data fields to enable automated validation of aggregated qlog
+schemas. Furthermore, they SHOULD properly add a * $$CATEGORY-NAME-extension
+extension field to newly defined event data to allow the new events to be
+properly extended by other documents.¶
A combined but purely illustrative example of the use of both extension points +for a conceptual QUIC "packet_sent" event is shown in Figure 20:¶
+A qlog event can be associated with a single "network path" (usually, but not +always, identified by a 4-tuple of IP addresses and ports). In many cases, the +path will be the same for all events in a given trace, and does not need to be +logged explicitly with each event. In this case, the "path" field can be omitted +(in which case the default value of "" is assumed) or reflected in +"common_fields" instead (see Section 6.9).¶
+However, in some situations, such as during QUIC's Connection Migration or when +using Multipath features, it is useful to be able to split events across +multiple (concurrent) paths.¶
+Definition:¶
+The "path" field is an identifier that is associated with a single network path. +This document intentionally does not define further how to choose this +identifier's value per-path or how to potentially log other parameters that can +be associated with such a path. This is left for other documents. Implementers +are free to encode path information directly into the PathID or to log +associated info in a separate event. For example, QUIC has the "path_assigned" +event to couple the PathID value to a specific path configuration, see +[QLOG-QUIC].¶
+An event's "protocol_type" array field indicates to which protocols (or protocol +"stacks") this event belongs. This allows a single qlog file to aggregate traces +of different protocols (e.g., a web server offering both TCP+HTTP/2 and +QUIC+HTTP/3 connections).¶
+For example, QUIC and HTTP/3 events have the "QUIC" and "HTTP3" protocol_type +entry values, see [QLOG-QUIC] and [QLOG-H3].¶
+Typically however, all events in a single trace are of the same few protocols, and +this array field is logged once in "common_fields", see Section 6.9.¶
+Sometimes, additional information is needed in the case where a single event can +be caused by a variety of other events. In the normal case, the context of the +surrounding log messages gives a hint as to which of these other events was the +cause. However, in highly-parallel and optimized implementations, corresponding +log messages might separated in time. Another option is to explicitly indicate +these "triggers" in a high-level way per-event to get more fine-grained +information without much additional overhead.¶
+In qlog, the optional "trigger" field contains a string value describing +the reason (if any) for this event instance occurring, see +Section 6.3. While this "trigger" field could be a property of the +qlog Event itself, it is instead a property of the "data" field instead. +This choice was made because many event types do not include a trigger +value, and having the field at the Event-level would cause overhead in +some serializations. Additional information on the trigger can be added +in the form of additional member fields of the "data" field value, yet +this is highly implementation-specific, as are the trigger field's +string values.¶
+One purely illustrative example of some potential triggers for QUIC's +"packet_dropped" event is shown in Figure 23:¶
+As discussed in Section 3.2, a single qlog file can contain several traces taken +from different vantage points. However, a single trace from one endpoint can also +contain events from a variety of sources. For example, a server implementation +might choose to log events for all incoming connections in a single large +(streamed) qlog file. As such, a method for splitting up events belonging +to separate logical entities is required.¶
+The simplest way to perform this splitting is by associating a "group id" +to each event that indicates to which conceptual "group" each event belongs. A +post-processing step can then extract events per group. However, this group +identifier can be highly protocol and context-specific. In the example above, +the QUIC "Original Destination Connection ID" could be used to uniquely identify a +connection. As such, they might add a "ODCID" field to each event. However, a +middlebox logging IP or TCP traffic might rather use four-tuples to identify +connections, and add a "four_tuple" field.¶
+As such, to provide consistency and ease of tooling in cross-protocol and +cross-context setups, qlog instead defines the common "group_id" field, which +contains a string value. Implementations are free to use their preferred string +serialization for this field, so long as it contains a unique value per logical +group. Some examples can be seen in Figure 25.¶
+JSON serialization example for events grouped by four tuples +and QUIC connection IDs:¶
+Note that in some contexts (for example a Multipath transport protocol) it might +make sense to add additional contextual per-event fields (for example "path_id"), +rather than use the group_id field for that purpose.¶
+Note also that, typically, a single trace only contains events belonging to a +single logical group (for example, an individual QUIC connection). As such, +instead of logging the "group_id" field with an identical value for each event +instance, this field is typically logged once in "common_fields", see +Section 6.9.¶
+The "system_info" field can be used to record system-specific details related to an +event. This is useful, for instance, where an application splits work across +CPUs, processes, or threads and events for a single trace occur on potentially +different combinations thereof. Each field is optional to support deployment +diversity.¶
++SystemInformation = { + ? processor_id: uint32 + ? process_id: uint32 + ? thread_id: uint32 +} +¶ +
As discussed in the previous sections, information for a typical qlog event varies +in three main fields: "time", "name" and associated data. Additionally, there are +also several more advanced fields that allow mixing events from different +protocols and contexts inside of the same trace (for example "protocol_type" and +"group_id"). In most "normal" use cases however, the values of these advanced +fields are consistent for each event instance (for example, a single trace +contains events for a single QUIC connection).¶
+To reduce file size and making logging easier, qlog uses the "common_fields" list +to indicate those fields and their values that are shared by all events in this +component trace. This prevents these fields from being logged for each individual +event. An example of this is shown in Figure 26.¶
+An event's "common_fields" field is a generic dictionary of key-value pairs, where the +key is always a string and the value can be of any type, but is typically also a +string or number. As such, unknown entries in this dictionary MUST be disregarded +by the user and tools (i.e., the presence of an unknown field is explicitly NOT an +error).¶
+The list of default qlog fields that are typically logged in common_fields (as +opposed to as individual fields per event instance) are shown in the listing +below:¶
+Tools MUST be able to deal with these fields being defined either on each event +individually or combined in common_fields. Note that if at least one event in a +trace has a different value for a given field, this field MUST NOT be added to +common_fields but instead defined on each event individually. Good example of such +fields are "time" and "data", who are divergent by nature.¶
+While qlog is a high-level logging format, it also allows the inclusion of most +raw wire image information, such as byte lengths and byte values. This is useful +when for example investigating or tuning packetization behavior or determining +encoding/framing overheads. However, these fields are not always necessary, can +take up considerable space, and can have a considerable privacy and security +impact (see Section 13). Where applicable, these fields are grouped in a +separate, optional, field named "raw" of type RawInfo. The exact definition of +entities, headers, trailers and payloads depend on the protocol used.¶
+The RawInfo:data field can be truncated for privacy or security purposes, see +Section 10.4. In this case, the length and payload_length fields should +still indicate the non-truncated lengths when used for debugging purposes.¶
+This document does not specify explicit header_length or trailer_length fields. +In protocols without trailers, header_length can be calculated by subtracting +the payload_length from the length. In protocols with trailers (e.g., QUIC's +AEAD tag), event definition documents SHOULD define how to support header_length +calculation.¶
+There are some event types and data classes that are common across protocols, +applications, and use cases. This section specifies such common definitions.¶
+In typical logging setups, users utilize a discrete number of well-defined logging +categories, levels or severities to log freeform (string) data. This generic +events category replicates this approach to allow implementations to fully replace +their existing text-based logging by qlog. This is done by providing events to log +generic strings for the typical well-known logging levels (error, warning, info, +debug, verbose).¶
+For the events defined below, the "category" is "generic" and their "type" is the +name of the heading in lowercase (e.g., the "name" of the error event is +"generic:error").¶
+Used to log details of an internal error that might not get reflected on the +wire. It has Core importance level; see Section 9.2.¶
+Used to log details of an internal warning that might not get reflected on the +wire. It has Base importance level; see Section 9.2.¶
+Used mainly for implementations that want to use qlog as their one and only +logging format but still want to support unstructured string messages. The event +has Extra importance level; see Section 9.2.¶
+Used mainly for implementations that want to use qlog as their one and only +logging format but still want to support unstructured string messages. The event +has Extra importance level; see Section 9.2.¶
+Used mainly for implementations that want to use qlog as their one and only +logging format but still want to support unstructured string messages. The event +has Extra importance level; see Section 9.2.¶
+When evaluating a protocol implementation, one typically sets up a series of +interoperability or benchmarking tests, in which the test situations can change +over time. For example, the network bandwidth or latency can vary during the test, +or the network can be fully disable for a short time. In these setups, it is +useful to know when exactly these conditions are triggered, to allow for proper +correlation with other events.¶
+For the events defined below, the "category" is "simulation" and their "type" is +the name of the heading in lowercase (e.g., the "name" of the scenario event is +"simulation:scenario").¶
+Used to specify which specific scenario is being tested at this particular
+instance. This supports, for example, aggregation of several simulations into
+one trace (e.g., split by group_id
). It has Extra importance level; see
+Section 9.2.¶
Used to indicate when specific emulation conditions are triggered at set times +(e.g., at 3 seconds in 2% packet loss is introduced, at 10s a NAT rebind is +triggered). It has Extra importance level; see Section 9.2.¶
+This document defines the main schema for the qlog format together with some +common events, which on their own do not provide much logging utility. It is +expected that logging is extended with specific, per-protocol event definitions +that specify the name (category + type) and data needed for each individual +event. Examples include the QUIC event definitions [QLOG-QUIC] and HTTP/3 +event definitions [QLOG-H3].¶
+This section defines some basic annotations and concepts that SHOULD be used by +event definition documents. Doing so ensures a measure of consistency that makes +it easier for qlog implementers to support a wide variety of protocols.¶
+There are several ways of defining qlog events. In practice, two main types of
+approach have been observed: a) those that map directly to concepts seen in the
+protocols (e.g., packet_sent
) and b) those that act as aggregating events that
+combine data from several possible protocol behaviors or code paths into one
+(e.g., parameters_set
). The latter are typically used as a means to reduce the
+amount of unique event definitions, as reflecting each possible protocol event
+as a separate qlog entity would cause an explosion of event types.¶
Additionally, logging duplicate data is typically prevented as much as possible.
+For example, packet header values that remain consistent across many packets are
+split into separate events (for example spin_bit_updated
or
+connection_id_updated
for QUIC).¶
Finally, when logging additional state change events, those state changes can
+often be directly inferred from data on the wire (for example flow control limit
+changes). As such, if the implementation is bug-free and spec-compliant, logging
+additional events is typically avoided. Exceptions have been made for common
+events that benefit from being easily identifiable or individually logged (for
+example packets_acked
).¶
Depending on how events are designed, it may be that several events allow the
+logging of similar or overlapping data. For example the separate QUIC
+connection_started
event overlaps with the more generic
+connection_state_updated
. In these cases, it is not always clear which event
+should be logged or used, and which event should take precedence if e.g., both are
+present and provide conflicting information.¶
To aid in this decision making, qlog defines three event importance levels, in +decreasing order of importance and expected usage:¶
+ +Events definitions SHOULD assign an importance level.¶
+Core-level events SHOULD be present in all qlog files for a +given protocol. These are typically tied to basic packet and frame parsing and +creation, as well as listing basic internal metrics. Tool implementers SHOULD +expect and add support for these events, though SHOULD NOT expect all Core events +to be present in each qlog trace.¶
+Base-level events add additional debugging options and MAY be present in qlog +files. Most of these can be implicitly inferred from data in Core events (if +those contain all their properties), but for many it is better to log the events +explicitly as well, making it clearer how the implementation behaves. These +events are for example tied to passing data around in buffers, to how internal +state machines change, and used to help show when decisions are actually made +based on received data. Tool implementers SHOULD at least add support for +showing the contents of these events, if they do not handle them explicitly.¶
+Extra-level events are considered mostly useful for low-level debugging of the +implementation, rather than the protocol. They allow more fine-grained tracking +of internal behavior. As such, they MAY be present in qlog files and tool +implementers MAY add support for these, but they are not required to.¶
+Note that in some cases, implementers might not want to log for example data
+content details in Core-level events due to performance or privacy considerations.
+In this case, they SHOULD use (a subset of) relevant Base-level events instead to
+ensure usability of the qlog output. As an example, implementations that do not
+log QUIC packet_received
events and thus also not which (if any) ACK frames the
+packet contains, SHOULD log packets_acked
events instead.¶
Finally, for event types whose data (partially) overlap with other event types' +definitions, where necessary the event definition document should include explicit +guidance on which to use in specific situations.¶
+Event definition documents are free to define new category and event types, +top-level fields (e.g., a per-event field indicating its privacy properties or +path_id in multipath protocols), as well as values for the "trigger" property +within the "data" field, or other member fields of the "data" field, as they see +fit.¶
+They however SHOULD NOT expect non-specialized tools to recognize or visualize +this custom data. However, tools SHOULD make an effort to visualize even unknown +data if possible in the specific tool's context. If they do not, they MUST ignore +these unknown fields.¶
+qlog schema definitions in this document are intentionally agnostic to +serialization formats. The choice of format is an implementation decision.¶
+Other documents related to qlog (for example event definitions for specific +protocols), SHOULD be similarly agnostic to the employed serialization format +and SHOULD clearly indicate this. If not, they MUST include an explanation on +which serialization formats are supported and on how to employ them correctly.¶
+Serialization formats make certain tradeoffs between usability, flexibility, +interoperability, and efficiency. Implementations should take these into +consideration when choosing a format. Some examples of possible formats are +JSON, CBOR, CSV, protocol buffers, flatbuffers, etc. which each have their own +characteristics. For instance, a textual format like JSON can be more flexible +than a binary format but more verbose, typically making it less efficient than a +binary format. A plaintext readable (yet relatively large) format like JSON is +potentially more usable for users operating on the logs directly, while a more +optimized yet restricted format can better suit the constraints of a large scale +operation. A custom or restricted format could be more efficient for analysis +with custom tooling but might not be interoperable with general-purpose qlog +tools.¶
+Considering these tradeoffs, JSON-based serialization formats provide features +that make them a good starting point for qlog flexibility and interoperability. +For these reasons, JSON is a recommended default and expanded considerations are +given to how to map qlog to JSON (Section 10.1, and its streaming counterpart +JSON Text Sequences (Section 10.2. Section 10.3 presents +interoperability considerations for both formats, and Section 10.5 presents +potential optimizations.¶
+Serialization formats require appropriate deserializers/parsers. The +"qlog_format" field (Section 3) is used to indicate the chosen +serialization format.¶
+As described in Section 3, JSON is the default qlog serialization. When +mapping qlog to normal JSON, QlogFile (Figure 2) is used and the +"qlog_format" field MUST have the value "JSON". The file extension/suffix SHOULD +be ".qlog". The Media Type, if any, SHOULD be "application/qlog+json" per +[RFC6839].¶
+In accordance with Section 8.1 of [RFC8259], JSON files are required to use +UTF-8 both for the file itself and the string values it contains. In addition, +all qlog field names MUST be lowercase when serialized to JSON.¶
+In order to serialize CDDL-based qlog event and data structure +definitions to JSON, the official CDDL-to-JSON mapping defined in +Appendix E of [CDDL] SHOULD be employed.¶
+One of the downsides of using normal JSON is that it is inherently a +non-streamable format. A qlog serializer could work around this by opening a +file, writing the required opening data, streaming qlog events by appending +them, and then finalizing the log by appending appropriate closing tags e.g., +"]}]}". However, failure to append closing tags, could lead to problems because +most JSON parsers will fail if a document is malformed. Some streaming JSON +parsers are able to handle missing closing tags, however they are not widely +deployed in popular environments (e.g., Web browsers)¶
+To overcome the issues related to JSON streaming, a qlog mapping to a streamable +JSON format called JSON Text Sequences (JSON-SEQ) ([RFC7464]) is provided.¶
+JSON Text Sequences are very similar to JSON, except that objects are +serialized as individual records, each prefixed by an ASCII Record Separator +(<RS>, 0x1E), and each ending with an ASCII Line Feed character (\n, 0x0A). Note +that each record can also contain any amount of newlines in its body, as long as +it ends with a newline character before the next <RS> character.¶
+In order to leverage the streaming capability, each qlog event is serialized and +interpreted as an individual JSON Text Sequence record, that is appended as a +new object to the back of an event stream or log file. Put differently, unlike +default JSON, it does not require a document to be wrapped as a full object with +"{ ... }" or "[... ]".¶
+This alternative record streaming approach cannot be accommodated by QlogFile +(Figure 2). Instead, QlogFileSeq is defined in Figure 8, +which notably includes only a single trace (TraceSeq) and omits an explicit +"events" array. An example is provided in Figure 9. The "group_id" field +can still be used on a per-event basis to include events from conceptually +different sources in a single JSON-SEQ qlog file.¶
+When mapping qlog to JSON-SEQ, the "qlog_format" field MUST have the value +"JSON-SEQ". The file extension/suffix SHOULD be ".sqlog" (for "streaming" qlog). +The Media Type, if any, SHOULD be "application/qlog+json-seq" per [RFC8091].¶
+While not specifically required by the JSON-SEQ specification, all qlog field +names MUST be lowercase when serialized to JSON-SEQ.¶
+In order to serialize all other CDDL-based qlog event and data structure +definitions to JSON-SEQ, the official CDDL-to-JSON mapping defined in +Appendix E of [CDDL] SHOULD be employed.¶
+Note that JSON Text Sequences are not supported in most default programming +environments (unlike normal JSON). However, several custom JSON-SEQ parsing +libraries exist in most programming languages that can be used and the format is +easy enough to parse with existing implementations (i.e., by splitting the file +into its component records and feeding them to a normal JSON parser individually, +as each record by itself is a valid JSON object).¶
+Some JSON implementations have issues with the full JSON format, especially those +integrated within a JavaScript environment (e.g., Web browsers, NodeJS). I-JSON +(Internet-JSON) is a subset of JSON for such environments; see +[I-JSON]. One of the key limitations of JavaScript, and thus I-JSON, +is that it cannot represent full 64-bit integers in standard operating mode +(i.e., without using BigInt extensions), instead being limited to the range +-(253)+1 to (253)-1.¶
+To accommodate such constraints in CDDL, Appendix E of [CDDL] recommends +defining new CDDL types for int64 and uint64 that limit their values to the +restricted 64-bit integer range. However, some of the protocols that qlog is +intended to support (e.g., QUIC, HTTP/3), can use the full range of uint64 +values.¶
+As such, to support situations where I-JSON is in use, seralizers MAY encode +uint64 values using JSON strings. qlog parsers, therefore, SHOULD support +parsing of uint64 values from JSON strings or JSON numbers unless there is out-of-band +information indicating that neither the serializer nor parser are constrained by +I-JSON.¶
+For some use cases (e.g., limiting file size, privacy), it can be
+necessary not to log a full raw blob (using the hexstring
type) but
+instead a truncated value. For example, one might only store the first 100 bytes of an
+HTTP response body to be able to discern which file it actually
+contained. In these cases, the original byte-size length cannot be
+obtained from the serialized value directly.¶
As such, all qlog schema definitions SHOULD include a separate,
+length-indicating field for all fields of type hexstring
they specify,
+see for example Section 7. This not only ensures the original length
+can always be retrieved, but also allows the omission of any raw value
+bytes of the field completely (e.g., out of privacy or security
+considerations).¶
To reduce overhead however and in the case the full raw value is logged, +the extra length-indicating field can be left out. As such, tools MUST +be able to deal with this situation and derive the length of the field +from the raw value if no separate length-indicating field is present. +The main possible permutations are shown by example in +Figure 37.¶
+Both the JSON and JSON-SEQ formatting options described above are serviceable in +general small to medium scale (debugging) setups. However, these approaches tend +to be relatively verbose, leading to larger file sizes. Additionally, generalized +JSON(-SEQ) (de)serialization performance is typically (slightly) lower than that +of more optimized and predictable formats. Both aspects present challenges to +large scale setups, though they may still be practical to deploy; see [ANRW-2020]. +JSON and JSON-SEQ compress very well using commonly-available algorithms such as +GZIP or Brotli.¶
+During the development of qlog, a multitude of alternative formatting +and optimization options were assessed and the results are summarized on the qlog +github +repository.¶
+Formal definition of additional qlog formats or encodings that use the +optimization techniques described here, or any other optimization technique is +left to future activity that can apply the following guidelines.¶
+In order to help tools correctly parse and process serialized qlog, it is +RECOMMENDED that new formats also define suitable file extensions and media +types. This provides a clear signal and avoids the need to provide out-of-band +information or to rely on heuristic fallbacks; see Section 12.¶
+Different implementations will have different ways of generating and storing +qlogs. However, there is still value in defining a few default ways in which to +steer this generation and access of the results.¶
+To provide users control over where and how qlog files are created, two +environment variables are defined. The first, QLOGFILE, indicates a full path to where an +individual qlog file should be stored. This path MUST include the full file +extension. The second, QLOGDIR, sets a general directory path in which qlog files +should be placed. This path MUST include the directory separator character at the +end.¶
+In general, QLOGDIR should be preferred over QLOGFILE if an endpoint is prone to +generate multiple qlog files. This can for example be the case for a QUIC server +implementation that logs each QUIC connection in a separate qlog file. An +alternative that uses QLOGFILE would be a QUIC server that logs all connections in +a single file and uses the "group_id" field (Section 6.7) to allow post-hoc +separation of events.¶
+Implementations SHOULD provide support for QLOGDIR and MAY provide support for +QLOGFILE.¶
+When using QLOGDIR, it is up to the implementation to choose an appropriate naming +scheme for the qlog files themselves. The chosen scheme will typically depend on +the context or protocols used. For example, for QUIC, it is recommended to use the +Original Destination Connection ID (ODCID), followed by the vantage point type of +the logging endpoint. Examples of all options for QUIC are shown in +Figure 38.¶
+Tools ingestion qlog MUST indicate which qlog version(s), qlog format(s), +compression methods and potentially other input file formats (for example .pcap) +they support. Tools SHOULD at least support .qlog files in the default JSON format +(Section 10.1). Additionally, they SHOULD indicate exactly which values for and +properties of the name (category and type) and data fields they look for to +execute their logic. Tools SHOULD perform a (high-level) check if an input qlog +file adheres to the expected qlog schema. If a tool determines a qlog file does +not contain enough supported information to correctly execute the tool's logic, it +SHOULD generate a clear error message to this effect.¶
+Tools MUST NOT produce breaking errors for any field names and/or values in the +qlog format that they do not recognize. Tools SHOULD indicate even unknown event +occurrences within their context (e.g., marking unknown events on a timeline for +manual interpretation by the user).¶
+Tool authors should be aware that, depending on the logging implementation, some +events will not always be present in all traces. For example, using a circular +logging buffer of a fixed size, it could be that the earliest events (e.g., +connection setup events) are later overwritten by "newer" events. Alternatively, +some events can be intentionally omitted out of privacy or file size +considerations. Tool authors are encouraged to make their tools robust enough to +still provide adequate output for incomplete logs.¶
+Protocols such as TLS [RFC8446] and QUIC [RFC9000] offer secure protection +for the wire image [RFC8546]. Logging can reveal aspects of the wire image +that would ordinarily be protected, creating tension between observability, +security and privacy, especially if data can be correlated across data sources.¶
+qlog permits logging of a broad and detialed range of data. Operators and +implementers are responsible for deciding what data is logged to address their +requirements and constraints. As per [RFC6973], operators must be aware that +data could be compromised, risking the privacy of all participants. Where +entities expect protocol features to ensure data privacy, logging might +unknowingly be subject to broader privacy risks, undermining their ability to +assess or respond effectively.¶
+qlog operators and implementers need to consider security and privacy risks when +handling qlog data, including logging, storage, usage, and more. The +considerations presented in this section may pose varying risks depending on the +the data itself or its handling.¶
+The following is a non-exhaustive list of example data types that could contain +sensitive information that might allow identification or correlation of +individual connections, endpoints, users or sessions across qlog or other data +sources (e.g., captures of encrypted packets):¶
+IP addresses and transport protocol port numbers.¶
+Session, Connection, or User identifiers e.g., QUIC Connection IDs Section 9.5 of [RFC9000]).¶
+System-level information e.g., CPU, process, or thread identifiers.¶
+Stored State e.g., QUIC address validation and retry tokens, TLS session +tickets, and HTTP cookies.¶
+TLS decryption keys, passwords, and HTTP-level API access or authorization tokens.¶
+High-resolution event timestamps or inter-event timings, event counts, packet +sizes, and frame sizes.¶
+Full or partial raw packet and frame payloads that are encrypted.¶
+Full or partial raw packet and frame payloads that are plaintext e.g., HTTP Field +values, HTTP response data, or TLS SNI field values.¶
+Operational considerations should focus on authorizing capture and access to logs. Logging of +Internet protocols using qlog can be equivalent to the ability to store or read plaintext +communications. Without a more detailed analysis, all of the security considerations of plaintext access apply.¶
+It is recommended that qlog capture is subject to access control and auditing. +These controls should support granular levels of information capture based on +role and permissions (e.g., capture of more-sensitive data requires higher +privileges).¶
+It is recommended that access to stored qlogs is subject to access control and +auditing.¶
+End users might not understand the implications of qlog to security or privacy, +and their environments might limit access control techniques. Implementations should +make enabling qlog conspicuous (e.g., requiring clear and explicit actions to +start a capture) and resistant to social engineering, automation, or drive-by +attacks; for example, isolation or sandboxing of capture from other activities +in the same process or component.¶
+It is recommended that data retention policies are defined for the storage of +qlog files.¶
+It is recommended that qlog files are encrypted in transit and at rest.¶
+Applying data minimization or anonymization techniques to qlog might help +address some security and privacy risks. However, removing or anonymizing data +without sufficient care might not enhance privacy or security and +could diminish the utility of qlog data.¶
+Operators and implementers should balance the value of logged data with the +potential risks of voluntary or involuntary disclosure to trusted or untrusted +entities. The data requirements and definition of entities depends greatly on +the intended use cases. For example, a research project might be tightly scoped, +time bound, and require participants to explicitly opt in to having their data +collected with the intention for this to be shared in a publication. Whereas a +server administrator might desire to collect telemetry, from users whom they have +no relationship with, for continuing operational needs.¶
+The most extreme form of minimization or anonymization is deleting a field, +equivalent to not logging it. qlog implementations should offer fine-grained +control for this on a per-use-case or per-connection basis.¶
+Data can undergo anonymization, pseudonymization, permutation, truncation, +re-encryption, or aggregation; see Appendix B of [DNS-PRIVACY] for +techniques, especially regarding IP addresses. However, operators should be +cautious because many anonymization methods have been shown to be insufficient to safeguard +user privacy or identity, particularly with large or easily correlated data sets.¶
+Operators should consider end user rights and preferences. Active user participation (as +indicated by [RFC6973]) on a per-qlog basis is challenging but aligning qlog +capture, storage, and removal with existing user preference and privacy controls +is crucial. Operators should consider agressive approaches to deletion or +aggregation.¶
+The most sensitive data in qlog is typically contained in RawInfo type fields +(see Section 7). Therefore, qlog users should exercise caution and limit the +inclusion of such fields for all but the most stringent use cases.¶
+There are no IANA considerations.¶
+Much of the initial work by Robin Marx was done at the Hasselt and KU Leuven +Universities.¶
+Thanks to Jana Iyengar, Brian Trammell, Dmitri Tikhonov, Stephen Petrides, Jari +Arkko, Marcus Ihlar, Victor Vasiliev, Mirja Kühlewind, Jeremy Lainé, Kazu +Yamamoto, Christian Huitema and Hugo Landau for their feedback and suggestions.¶
+This section is to be removed before publishing as an RFC.¶
+Updated qlog_version to 0.4 (due to breaking changes) (#314)¶
+Renamed 'transport' category to 'quic' (#302)¶
+Added 'system_info' field (#305)¶
+Removed 'summary' and 'configuration' fields (#308)¶
+Editorial and formatting changes (#298, #303, #304, #316, #320, #321, #322, #326, #328)¶
+Updated RawInfo definition and guidance (#243)¶
+Added security and privacy considerations discussion (#252)¶
+No changes - new draft to prevent expiration¶
+Change the data definition language from TypeScript to CDDL (#143)¶
+These changes were done in preparation of the adoption of the drafts by the QUIC +working group (#137)¶
+Moved RawInfo, Importance, Generic events and Simulation events to this document.¶
+Added basic event definition guidelines¶
+Made protocol_type an array instead of a string (#146)¶
+Decoupled qlog from the JSON format and described a mapping instead (#89)¶
+Data types are now specified in this document and proper definitions for +fields were added in this format¶
+64-bit numbers can now be either strings or numbers, with a preference for +numbers (#10)¶
+binary blobs are now logged as lowercase hex strings (#39, #36)¶
+added guidance to add length-specifiers for binary blobs (#102)¶
+Removed "time_units" from Configuration. All times are now in ms instead (#95)¶
+Removed the "event_fields" setup for a more straightforward JSON format +(#101,#89)¶
+Added a streaming option using the NDJSON format (#109,#2,#106)¶
+Described optional optimization options for implementers (#30)¶
+Added QLOGDIR and QLOGFILE environment variables, clarified the .well-known URL +usage (#26,#33,#51)¶
+Overall tightened up the text and added more examples¶
+Internet-Draft | +QUIC event definitions for qlog | +June 2024 | +
Marx, et al. | +Expires 29 December 2024 | +[Page] | +
This document describes concrete qlog event definitions and their metadata for +QUIC events. These events can then be embedded in the higher level schema defined +in [QLOG-MAIN].¶
+Note to RFC editor: Please remove this section before publication.¶
+Feedback and discussion are welcome at +https://github.com/quicwg/qlog. Readers are +advised to refer to the "editor's draft" at that URL for an up-to-date version +of this document.¶
+Concrete examples of integrations of this schema in +various programming languages can be found at +https://github.com/quiclog/qlog/.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 29 December 2024.¶
++ Copyright (c) 2024 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+This document describes the values of the qlog name ("category" + "event") and +"data" fields and their semantics for the QUIC protocol (see +[QUIC-TRANSPORT], [QUIC-RECOVERY], and +[QUIC-TLS]) and some of its extensions (see +[QUIC-DATAGRAM] and [GREASEBIT]).¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+The event and data structure definitions in ths document are expressed +in the Concise Data Definition Language [CDDL] and its +extensions described in [QLOG-MAIN].¶
+The following fields from [QLOG-MAIN] are imported and used: name, category, +type, data, group_id, protocol_type, importance, RawInfo, and time-related +fields.¶
+As is the case for [QLOG-MAIN], the qlog schema definitions in this document +are intentionally agnostic to serialization formats. The choice of format is an +implementation decision.¶
+This document describes how the QUIC protocol can be expressed in qlog using +the schema defined in [QLOG-MAIN]. QUIC protocol events are defined with a +category, a name (the concatenation of "category" and "event"), an "importance", +an optional "trigger", and "data" fields.¶
+Some data fields use complex datastructures. These are represented as enums or +re-usable definitions, which are grouped together on the bottom of this document +for clarity.¶
+When any event from this document is included in a qlog trace, the
+protocol_type
qlog array field MUST contain an entry with the value "QUIC":¶
When the qlog group_id
field is used, it is recommended to use QUIC's Original
+Destination Connection ID (ODCID, the CID chosen by the client when first
+contacting the server), as this is the only value that does not change over the
+course of the connection and can be used to link more advanced QUIC packets (e.g.,
+Retry, Version Negotiation) to a given connection. Similarly, the ODCID should be
+used as the qlog filename or file identifier, potentially suffixed by the
+vantagepoint type (For example, abcd1234_server.qlog would contain the server-side
+trace of the connection with ODCID abcd1234).¶
QUIC packets always include an AEAD authentication tag at the end. In general, +the length of the AEAD tag depends on the TLS cipher suite, although all cipher +suites used in QUIC v1 use a 16 byte tag. For the purposes of calculating the +lengths in fields of type RawInfo (as defined in [QLOG-MAIN]) related to QUIC +packets, the AEAD tag is regarded as a trailer.¶
+A single qlog event trace is typically associated with a single QUIC connection.
+However, for several types of events (for example, a Section 5.7
+event with trigger value of connection_unknown
), it can be impossible to tie
+them to a specific QUIC connection, especially on the server.¶
There are various ways to handle these events, each making certain tradeoffs +between file size overhead, flexibility, ease of use, or ease of +implementation. Some options include:¶
+Log them in a separate endpoint-wide trace (or use a special group_id
value)
+not associated with a single connection.¶
Log them in the most recently used trace.¶
+Use additional heuristics for connection identification (for example use the +four-tuple in addition to the Connection ID).¶
+Buffer events until they can be assigned to a connection (for example for +version negotiation and retry events).¶
+QUIC connections consist of different phases and interaction events. In order to +model this, QUIC event types are divided into general categories: connectivity +(Section 4), security (Section 6), quic Section 5, and recovery +Section 7.¶
+As described in Section 3.4.2 of [QLOG-MAIN], the qlog name
field is the
+concatenation of category and type.¶
Table 1 summarizes the name value of each event type that is defined in +this specification.¶
+Name value | +Importance | +Definition | +
---|---|---|
connectivity:server_listening | +Extra | ++ Section 4.1 + | +
connectivity:connection_started | +Base | ++ Section 4.2 + | +
connectivity:connection_closed | +Base | ++ Section 4.3 + | +
connectivity:connection_id_updated | +Base | ++ Section 4.4 + | +
connectivity:spin_bit_updated | +Base | ++ Section 4.5 + | +
connectivity:connection_state_updated | +Base | ++ Section 4.6 + | +
connectivity:path_assigned | +Base | ++ Section 4.7 + | +
connectivity:mtu_updated | +Extra | ++ Section 4.8 + | +
quic:version_information | +Core | ++ Section 5.1 + | +
quic:alpn_information | +Core | ++ Section 5.2 + | +
quic:parameters_set | +Core | ++ Section 5.3 + | +
quic:parameters_restored | +Base | ++ Section 5.4 + | +
quic:packet_sent | +Core | ++ Section 5.5 + | +
quic:packet_received | +Core | ++ Section 5.6 + | +
quic:packet_dropped | +Base | ++ Section 5.7 + | +
quic:packet_buffered | +Base | ++ Section 5.8 + | +
quic:packets_acked | +Extra | ++ Section 5.9 + | +
quic:udp_datagrams_sent | +Extra | ++ Section 5.10 + | +
quic:udp_datagrams_received | +Extra | ++ Section 5.11 + | +
quic:udp_datagram_dropped | +Extra | ++ Section 5.12 + | +
quic:stream_state_updated | +Base | ++ Section 5.13 + | +
quic:frames_processed | +Extra | ++ Section 5.14 + | +
quic:stream_data_moved | +Base | ++ Section 5.15 + | +
quic:datagram_data_moved | +Base | ++ Section 5.16 + | +
quic:migration_state_updated | +Extra | ++ Section 5.17 + | +
security:key_updated | +Base | ++ Section 6.1 + | +
security:key_discarded | +Base | ++ Section 6.2 + | +
recovery:parameters_set | +Base | ++ Section 7.1 + | +
recovery:metrics_updated | +Core | ++ Section 7.2 + | +
recovery:congestion_state_updated | +Base | ++ Section 7.3 + | +
recovery:loss_timer_updated | +Extra | ++ Section 7.4 + | +
recovery:packet_lost | +Core | ++ Section 7.5 + | +
recovery:marked_for_retransmit | +Extra | ++ Section 7.6 + | +
recovery:ecn_state_updated | +Extra | ++ Section 7.7 + | +
QUIC events extend the $ProtocolEventData
extension point defined in
+[QLOG-MAIN]. Additionally, they allow for direct extensibility by their use of
+per-event extension points via the $$
CDDL "group socket" syntax, as also
+described in [QLOG-MAIN].¶
Emitted when the server starts accepting connections. It has Extra importance +level; see Section 9.2 of [QLOG-MAIN].¶
+Some QUIC stacks do not handle sockets directly and are thus unable to log +IP and/or port information.¶
+The connection_started
event is used for both attempting (client-perspective)
+and accepting (server-perspective) new connections. Note that while there is
+overlap with the connection_state_updated
event, this event is separate event
+in order to capture additional data that can be useful to log. It has Base
+importance level; see Section 9.2 of [QLOG-MAIN].¶
Some QUIC stacks do not handle sockets directly and are thus unable to log +IP and/or port information.¶
+The connection_closed
event is used for logging when a connection was closed,
+typically when an error or timeout occurred. It has Base importance level; see
+Section 9.2 of [QLOG-MAIN].¶
Note that this event has overlap with the connection_state_updated
event, as
+well as the CONNECTION_CLOSE frame. However, in practice, when analyzing large
+deployments, it can be useful to have a single event representing a
+connection_closed
event, which also includes an additional reason field to
+provide more information. Furthermore, it is useful to log closures due to
+timeouts, which are difficult to reflect using the other options.¶
In QUIC there are two main connection-closing error categories: connection and +application errors. They have well-defined error codes and semantics. Next to +these however, there can be internal errors that occur that may or may not get +mapped to the official error codes in implementation-specific ways. As such, +multiple error codes can be set on the same event to reflect this.¶
+The connection_id_updated
event is emitted when either party updates their
+current Connection ID. As this typically happens only sparingly over the course
+of a connection, using this event is more efficient than logging the observed
+CID with each and every packet_sent
or packet_received
events. It has Base
+importance level; see Section 9.2 of [QLOG-MAIN].¶
The connection_id_updated
event is viewed from the perspective of the endpoint
+applying the new ID. As such, when the endpoint receives a new connection ID
+from the peer, the owner field will be "remote". When the endpoint updates its
+own connection ID, the owner field will be "local".¶
The spin_bit_updated
event conveys information about the QUIC latency spin
+bit; see Section 17.4 of [QUIC-TRANSPORT]. The event is emitted when the spin
+bit changes value, it SHOULD NOT be emitted if the spin bit is set without
+changing its value. It has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
The connection_state_updated
event is used to track progress through QUIC's
+complex handshake and connection close procedures. It has Base importance
+level; see Section 9.2 of [QLOG-MAIN].¶
It is intended to provide exhaustive options to log each state individually, but +also provides a more basic, simpler set for implementations less interested in +tracking each smaller state transition. As such, users should not expect to see +all these states reflected in all qlogs and implementers should focus on support +for the SimpleConnectionState set.¶
+These states correspond to the following transitions for both client and server:¶
+Client:¶
+send initial¶
+state = attempted¶
+get initial¶
+state = validated (not really "needed" at the client, but somewhat useful to indicate progress nonetheless)¶
+get first Handshake packet¶
+state = handshake_started¶
+get Handshake packet containing ServerFinished¶
+state = handshake_complete¶
+send ClientFinished¶
+state = early_write + (1RTT can now be sent)¶
+get HANDSHAKE_DONE¶
+state = handshake_confirmed¶
+Server:¶
+get initial¶
+state = attempted¶
+send initial (TODO don't think this needs a separate state, since some handshake will always be sent in the same flight as this?)¶
+send handshake EE, CERT, CV, ...¶
+state = handshake_started¶
+send ServerFinished¶
+state = early_write + (1RTT can now be sent)¶
+get first handshake packet / something using a server-issued CID of min length¶
+state = validated¶
+get handshake packet containing ClientFinished¶
+state = handshake_complete¶
+send HANDSHAKE_DONE¶
+state = handshake_confirmed¶
+connection_state_changed
with a new state of attempted
is the same
+conceptual event as the connection_started
event above from the client's
+perspective. Similarly, a state of
closing or
draining corresponds to the
+
connection_closed` event.¶
Importance: Base¶
+This event is used to associate a single PathID's value with other parameters +that describe a unique network path.¶
+As described in [QLOG-MAIN], each qlog event can be linked to a single network +path by means of the top-level "path" field, whose value is a PathID. However, +since it can be cumbersome to encode additional path metadata (such as IP +addresses or Connection IDs) directly into the PathID, this event allows such an +association to happen separately. As such, PathIDs can be short and unique, and +can even be updated to be associated with new metadata as the connection's state +evolves.¶
+Definition:¶
+Choosing the different path_id
values is left up to the implementation. Some
+options include using a uniquely incrementing integer, using the (first)
+Destination Connection ID associated with a path (or its sequence number), or
+using (a hash of) the two endpoint IP addresses.¶
It is important to note that the empty string ("") is a valid PathID and that it
+is the default assigned to events that do not explicitly set a "path" field. Put
+differently, the initial path of a QUIC connection on which the handshake occurs
+(see also Section 4.2) is implicitly associated with the
+PathID with value "". Associating metadata with this default path is possible by
+logging the ConnectivityPathAssigned event with a value of "" for the path_id
+field.¶
As paths and their metadata can evolve over time, multiple
+ConnectivityPathAssigned events can be emitted for each unique PathID. The
+latest event contains the most up-to-date information for that PathID. As such,
+the first time a PathID is seen in a ConnectivityPathAssigned event, it is an
+indication that the path is created. Subsequent occurrences indicate the path is
+updated, while a final occurrence with both path_local
and path_remote
+fields omitted implicitly indicates the path has been abandoned.¶
The mtu_updated
event indicates that the estimated Path MTU was updated. This
+happens as part of the Path MTU discovery process. It has Extra importance
+level; see Section 9.2 of [QLOG-MAIN].¶
The version_information
event supports QUIC version negotiation; see Section 6 of [QUIC-TRANSPORT]. It has Core importance level; see Section 9.2 of [QLOG-MAIN].¶
QUIC endpoints each have their own list of QUIC versions they support. The
+client uses the most likely version in their first initial. If the server does
+not support that version, it replies with a Version Negotiation packet, which
+contains its supported versions. From this, the client selects a version. The
+version_information
event aggregates all this information in a single event
+type. It also allows logging of supported versions at an endpoint without actual
+version negotiation needing to happen.¶
Intended use:¶
+When sending an initial, the client logs this event with client_versions
and
+chosen_version
set¶
Upon receiving a client initial with a supported version, the server logs this
+event with server_versions
and chosen_version
set¶
Upon receiving a client initial with an unsupported version, the server logs
+this event with server_versions
set and client_versions
to the
+single-element array containing the client's attempted version. The absence of
+chosen_version implies no overlap was found¶
Upon receiving a version negotiation packet from the server, the client logs
+this event with client_versions
set and server_versions
to the versions in
+the version negotiation packet and chosen_version to the version it will use
+for the next initial packet. If the client receives a set of server_versions
+with no viable overlap with its own supported versions, this event should be
+logged without the chosen_version
set¶
The alpn_information
event supports Application-Layer Protocol Negotiation
+(ALPN) over the QUIC transport; see [RFC7301] and Section 7.4 of [QUIC-TRANSPORT]. It has Core importance level; see Section 9.2 of [QLOG-MAIN].¶
QUIC endpoints are configured with a list of supported ALPN identifiers. Clients send the list in a TLS ClientHello, and servers match against their list. On success, a single ALPN identifier is chosen and sent back in a TLS ServerHello. If no match is found, the connection is closed.¶
+ALPN identifiers are byte sequences, that may be possible to present as UTF-8.
+The ALPNIdentifier
` type supports either format. Implementations SHOULD log at
+least one format, but MAY log both or none.¶
Intended use:¶
+When sending an initial, the client logs this event with client_alpns
set¶
When receiving an initial with a supported alpn, the server logs this event
+with server_alpns
set, client_alpns
equalling the client-provided list,
+and chosen_alpn to the value it will send back to the client.¶
When receiving an initial with an alpn, the client logs this event with
+chosen_alpn
to the received value.¶
Alternatively, a client can choose to not log the first event, but wait for
+the receipt of the server initial to log this event with both client_alpns
+and chosen_alpn
set.¶
The parameters_set
event groups settings from several different sources
+(transport parameters, TLS ciphers, etc.) into a single event. This is done to
+minimize the amount of events and to decouple conceptual setting impacts from
+their underlying mechanism for easier high-level reasoning. The event has Core
+importance level; see Section 9.2 of [QLOG-MAIN].¶
Most of these settings are typically set once and never change. However, they +are usually set at different times during the connection, so there will +regularly be several instances of this event with different fields set.¶
+Note that some settings have two variations (one set locally, one requested by the
+remote peer). This is reflected in the owner
field. As such, this field MUST be
+correct for all settings included a single event instance. If you need to log
+settings from two sides, you MUST emit two separate event instances.¶
In the case of connection resumption and 0-RTT, some of the server's parameters
+are stored up-front at the client and used for the initial connection startup.
+They are later updated with the server's reply. In these cases, utilize the
+separate parameters_restored
event to indicate the initial values, and this
+event to indicate the updated values, as normal.¶
When using QUIC 0-RTT, clients are expected to remember and restore the server's
+transport parameters from the previous connection. The parameters_restored
+event is used to indicate which parameters were restored and to which values
+when utilizing 0-RTT. It has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
Note that not all transport parameters should be restored (many are even +prohibited from being re-utilized). The ones listed here are the ones expected +to be useful for correct 0-RTT usage.¶
+The packet_sent
event indicates a QUIC-level packet was sent. It has Core
+importance level; see Section 9.2 of [QLOG-MAIN].¶
The encryption_level
and packet_number_space
are not logged explicitly:
+the header.packet_type
specifies this by inference (assuming correct
+implementation)¶
For more details on datagram_id
, see Section 5.10. It is only needed
+when keeping track of packet coalescing.¶
The packet_received
event indicates a QUIC-level packet was received. It has
+Core importance level; see Section 9.2 of [QLOG-MAIN].¶
The encryption_level
and packet_number_space
are not logged explicitly: the
+header.packet_type
specifies this by inference (assuming correct
+implementation)¶
For more details on datagram_id
, see Section 5.10. It is only needed
+when keeping track of packet coalescing.¶
The packet_dropped
event indicates a QUIC-level packet was dropped. It has
+Base importance level; see Section 9.2 of [QLOG-MAIN].¶
The trigger field indicates a general reason category for dropping the packet, +while the details field can contain additional implementation-specific +information.¶
+Some example situations for each of the trigger categories include:¶
+internal_error
: not initialized, out of memory¶
rejected
: limits reached, DDoS protection, unwilling to track more paths, duplicate packet¶
unsupported
: unknown or unsupported version. See also Section 2.2.¶
invalid
: packet parsing or validation error¶
duplicate
: duplicate packet¶
connection_unknown
: packet does not relate to a known connection or Connection ID¶
decryption_failure
: decryption failed¶
key_unavailable
: decryption key was unavailable¶
general
: situations not clearly covered in the other categories¶
For more details on datagram_id
, see Section 5.10.¶
The packet_buffered
event is emitted when a packet is buffered because it
+cannot be processed yet. Typically, this is because the packet cannot be parsed
+yet, and thus only the full packet contents can be logged when it was parsed in
+a packet_received
event. The event has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
For more details on datagram_id
, see Section 5.10. It is only needed
+when keeping track of packet coalescing.¶
The packets_acked
event is emitted when a (group of) sent packet(s) is
+acknowledged by the remote peer for the first time. It has Extra importance
+level; see Section 9.2 of [QLOG-MAIN].¶
This information could also be deduced from the contents of received ACK frames. +However, ACK frames require additional processing logic to determine when a +given packet is acknowledged for the first time, as QUIC uses ACK ranges which +can include repeated ACKs. Additionally, this event can be used by +implementations that do not log frame contents.¶
+If packet_number_space
is omitted, it assumes the default value of
+application_data
, as this is by far the most prevalent packet
+number space a typical QUIC connection will use.¶
When one or more UDP-level datagrams are passed to the socket. This is useful +for determining how QUIC packet buffers are drained to the OS. The event has +Extra importance level; see Section 9.2 of [QLOG-MAIN].¶
+Since QUIC implementations rarely control UDP logic directly, the raw data +excludes UDP-level headers in all fields.¶
+The datagram_id
is a qlog-specific concept to allow tracking of QUIC packet
+coalescing inside UDP datagrams. Since QUIC generates many UDP datagrams, unique
+identifiers are required to be able to track them individually in qlog traces.
+However, neither UDP nor QUIC exchanges datagram identifiers on the wire.
+Selecting identifier values is thus left to qlog implementations, which should
+consider how to generate unique values within the scope of their created traces.¶
When one or more UDP-level datagrams are received from the socket. This is +useful for determining how datagrams are passed to the user space stack from the +OS. The event has Extra importance level; see Section 9.2 of [QLOG-MAIN].¶
+For more details on datagram_ids
, see Section 5.10.¶
When a UDP-level datagram is dropped. This is typically done if it does not
+contain a valid QUIC packet. If it does, but the QUIC packet is dropped for
+other reasons, the packet_dropped
event (Section 5.7) should be
+used instead. The event has Extra importance level; see Section 9.2 of [QLOG-MAIN].¶
The stream_state_updated
event is emitted whenever the internal state of a
+QUIC stream is updated; see Section 3 of [QUIC-TRANSPORT]. Most of this can be
+inferred from several types of frames going over the wire, but it's much easier
+to have explicit signals for these state changes. The event has Base importance
+level; see Section 9.2 of [QLOG-MAIN].¶
QUIC implementations SHOULD mainly log the simplified (HTTP/2-alike) +BaseStreamStates instead of the more fine-grained GranularStreamStates. These +latter ones are mainly for more in-depth debugging. Tools SHOULD be able to deal +with both types equally.¶
+The frame_processed
event is intended to prevent a large proliferation of
+specific purpose events (e.g., packets_acknowledged
, flow_control_updated
,
+stream_data_received
). It has Extra importance level; see Section 9.2 of [QLOG-MAIN].¶
Implementations have the opportunity to (selectively) log this type of
+signal without having to log packet-level details (e.g., in packet_received
).
+Since for almost all cases, the effects of applying a frame to the internal state
+of an implementation can be inferred from that frame's contents, these events
+are aggregated into this single frames_processed
event.¶
The frame_processed
event can be used to signal internal state change not
+resulting directly from the actual "parsing" of a frame (e.g., the frame could
+have been parsed, data put into a buffer, then later processed, then logged with
+this event).¶
The packet_received
event can convey all constituent frames. It is not
+expected that the frames_processed
event will also be used for a redundant
+purpose. Rather, implementations can use this event to avoid having to log full
+packets or to convey extra information about when frames are processed (for
+example, if frame processing is deferred for any reason).¶
Note that for some events, this approach will lose some information (e.g., for which
+encryption level are packets being acknowledged?). If this information is
+important, the packet_received
event can be used instead.¶
In some implementations, it can be difficult to log frames directly, even when
+using packet_sent
and packet_received
events. For these cases, the
+frames_processed
event also contains the packet_numbers
field, which can be
+used to more explicitly link this event to the packet_sent
/received events
.
+The field is an array, which supports using a single frames_processed
event
+for multiple frames received over multiple packets. To map between frames and
+packets, the position and order of entries in the frames
and packet_numbers
+is used. If the optional packet_numbers
field is used, each frame MUST have a
+corresponding packet number at the same index.¶
For example, an instance of the frames_processed
event that represents four
+STREAM frames received over two packets would have the fields serialized as:¶
+"frames":[ + {"frame_type":"stream","stream_id":0,"offset":0,"length":500}, + {"frame_type":"stream","stream_id":0,"offset":500,"length":200}, + {"frame_type":"stream","stream_id":1,"offset":0,"length":300}, + {"frame_type":"stream","stream_id":1,"offset":300,"length":50} + ], +"packet_numbers":[ + 1, + 1, + 2, + 2 +] +¶ +
The stream_data_moved
event is used to indicate when QUIC stream data moves
+between the different layers. This helps make clear the flow of data, how long
+data remains in various buffers, and the overheads introduced by individual
+layers. The event has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
For example, it can be useful to understand when when data moves from an +application protocol (e.g., HTTP) to QUIC stream buffers and vice versa. +Similarly, when data moves from the application protocol layer into a +user-facing application such as a web browser.¶
+The stream_data_moved
event can provide insight into whether received data on
+a QUIC stream is moved to the application protocol immediately (for example per
+received packet) or in larger batches (for example, all QUIC packets are
+processed first and afterwards the application layer reads from the streams with
+newly available data). This can help identify bottlenecks, flow control issues,
+or scheduling problems.¶
This event is only for data in QUIC streams. For data in QUIC Datagram Frames,
+see the datagram_data_moved
event defined in Section 5.16.¶
The datagram_data_moved
event is used to indicate when QUIC Datagram Frame
+data (see [RFC9221]) moves between the different layers. This helps make
+clear the flow of data, how long data remains in various buffers, and the
+overheads introduced by individual layers. The event has Base importance level;
+see Section 9.2 of [QLOG-MAIN].¶
For example, passing from the application protocol (e.g., WebTransport) to QUIC +Datagram Frame buffers and vice versa. Similarly, when data moves from the +application protocol layer into a user-facing application such as a web browser.¶
+The datagram_data_moved
event can provide insight into whether received data
+in a QUIC Datagram Frame is moved to the application protocol immediately (for
+example per received packet) or in larger batches (for example, all QUIC packets
+are processed first and afterwards the application layer reads all Datagrams at
+once). This can help identify bottlenecks, flow control issues, or scheduling
+problems.¶
This event is only for data in QUIC Datagram Frames. For data in QUIC streams,
+see the stream_data_moved
event defined in Section 5.15.¶
Importance: Extra¶
+Use to provide additional information when attempting (client-side) connection +migration. While most details of the QUIC connection migration process can be +inferred by observing the PATH_CHALLENGE and PATH_RESPONSE frames, in +combination with the ConnectivityPathAssigned event, it can be useful to +explicitly log the progression of the migration and potentially made decisions +in a single location/event.¶
+Generally speaking, connection migration goes through two phases: a probing +phase (which is not always needed/present), and a migration phase (which can be +abandoned upon error).¶
+Implementations that log per-path information in a QUICMigrationStateUpdated, +SHOULD also emit QUICPathAssigned events, to serve as a ground-truth source of +information.¶
+Definition:¶
+The key_updated
event has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
Note that the key_phase is the full value of the key phase (as indicated by +@M and @N in Figure 9 of [QUIC-TLS]). The key phase bit used on +the packet header is the least significant bit of the key phase.¶
+The key_discarded
event has Base importance level; see Section 9.2 of [QLOG-MAIN].¶
Most of the events in this category are kept generic to support different +recovery approaches and various congestion control algorithms. Tool creators +SHOULD make an effort to support and visualize even unknown data in these events +(e.g., plot unknown congestion states by name on a timeline visualization).¶
+The parameters_set
event groups initial parameters from both loss detection
+and congestion control into a single event. It has Base importance level; see
+Section 9.2 of [QLOG-MAIN].¶
All these settings are typically set once and never change. Implementation that
+do, for some reason, change these parameters during execution, MAY emit the
+parameters_set
event more than once.¶
Additionally, this event can contain any number of unspecified fields to support +different recovery approaches.¶
+The metrics_updated
event is emitted when one or more of the observable
+recovery metrics changes value. It has Core importance level; see Section 9.2 of [QLOG-MAIN].¶
This event SHOULD group all possible metric updates that happen at or around the
+same time in a single event (e.g., if min_rtt
and smoothed_rtt
change at the
+same time, they should be bundled in a single metrics_updated
entry, rather
+than split out into two). Consequently, a metrics_updated
event is only
+guaranteed to contain at least one of the listed metrics.¶
In order to make logging easier, implementations MAY log values even if they are the
+same as previously reported values (e.g., two subsequent RecoveryMetricsUpdated entries can
+both report the exact same value for min_rtt
). However, applications SHOULD try to
+log only actual updates to values.¶
Additionally, the metrics_updated
event can contain any number of unspecified fields to support
+different recovery approaches.¶
The congestion_state_updated
event indicates when the congestion controller
+enters a significant new state and changes its behaviour. It has Base importance
+level; see Section 9.2 of [QLOG-MAIN].¶
The values of the event's fields are intentionally unspecified here in order to +support different Congestion Control algorithms, as these typically have +different states and even different implementations of these states across +stacks. For example, for the algorithm defined in the Recovery draft ("enhanced" +New Reno), the following states are used: Slow Start, Congestion Avoidance, +Application Limited and Recovery. Similarly, states can be triggered by a +variety of events, including detection of Persistent Congestion or receipt of +ECN markings.¶
+The trigger
field SHOULD be logged if there are multiple ways in which a state
+change can occur but MAY be omitted if a given state can only be due to a single
+event occurring (for example Slow Start is often exited only when ssthresh is
+exceeded).¶
The loss_timer_updated
event is emitted when a recovery loss timer changes
+state. It has Extra importance level; see Section 9.2 of [QLOG-MAIN].¶
The three main event types are:¶
+set: the timer is set with a delta timeout for when it will trigger next¶
+expired: when the timer effectively expires after the delta timeout¶
+cancelled: when a timer is cancelled (e.g., all outstanding packets are +acknowledged, start idle period)¶
+In order to indicate an active timer's timeout update, a new set
event is used.¶
The packet_lost
event is emitted when a packet is deemed lost by loss
+detection. It has Core importance level; see Section 9.2 of [QLOG-MAIN].¶
It is RECOMMENDED to populate the optional trigger
field in order to help
+disambiguate among the various possible causes of a loss declaration.¶
The marked_for_retransmit
event indicates which data was marked for
+retransmission upon detection of packet loss (see packet_lost
). It has Extra
+importance level; see Section 9.2 of [QLOG-MAIN].¶
Similar to the reasoning for the frames_processed
event,
+in order to keep the amount of different events low, this signal is grouped into
+in a single event based on existing QUIC frame definitions for all types of
+retransmittable data.¶
Implementations retransmitting full packets or frames directly can just log the
+constituent frames of the lost packet here (or do away with this event and use the
+contents of the packet_lost
event instead). Conversely, implementations that have
+more complex logic (e.g., marking ranges in a stream's data buffer as in-flight),
+or that do not track sent frames in full (e.g., only stream offset + length), can
+translate their internal behaviour into the appropriate frame instance here even
+if that frame was never or will never be put on the wire.¶
Much of this data can be inferred if implementations log packet_sent
events
+(e.g., looking at overlapping stream data offsets and length, one can determine
+when data was retransmitted).¶
The ecn_state_updated
event indicates a progression in the ECN state machine
+as described in section A.4 of [QUIC-TRANSPORT]. It has Extra importance
+level; see Section 9.2 of [QLOG-MAIN].¶
PathEndpointInfo indicates a single half/direction of a path. A full path is +comprised of two halves. Firstly: the server sends to the remote client IP ++ port using a specific destination Connection ID. Secondly: the client sends to +the remote server IP + port using a different destination Connection ID.¶
+As such, structures logging path information SHOULD include two different +PathEndpointInfo instances, one for each half of the path.¶
+The token carried in an Initial packet can either be a retry token from a Retry
+packet, or one originally provided by the server in a NEW_TOKEN frame used when
+resuming a connection (e.g., for address validation purposes). Retry and
+resumption tokens typically contain encoded metadata to check the token's
+validity when it is used, but this metadata and its format is implementation
+specific. For that, Token
includes a general-purpose details
field.¶
The stateless reset token is carried in stateless reset packets, in transport +parameters and in NEW_CONNECTION_ID frames.¶
+The generic $QuicFrame
is defined here as a CDDL "type socket" extension
+point. It can be extended to support additional QUIC frame types.¶
The QUIC frame types defined in this document are as follows:¶
+In QUIC, PADDING frames are simply identified as a single byte of value 0. As +such, each padding byte could be theoretically interpreted and logged as an +individual PaddingFrame.¶
+However, as this leads to heavy logging overhead, implementations SHOULD instead +emit just a single PaddingFrame and set the payload_length property to the amount +of PADDING bytes/frames included in the packet.¶
+Note that the packet ranges in AckFrame.acked_ranges do not necessarily have to be +ordered (e.g., [[5,9],[1,4]] is a valid value).¶
+Note that the two numbers in the packet range can be the same (e.g., [120,120] means +that packet with number 120 was ACKed). However, in that case, implementers SHOULD +log [120] instead and tools MUST be able to deal with both notations.¶
+An endpoint that receives unknown error codes can record it in the error_code +field using the numerical value without variable-length integer encoding.¶
+When the connection is closed due a connection-level error, the
+trigger_frame_type
field can be used to log the frame that triggered the
+error. For known frame types, the appropriate string value is used. For unknown
+frame types, the numerical value without variable-length integer encoding is
+used.¶
The CONNECTION_CLOSE reason phrase is a byte sequences. It is likely that this
+sequence is presentable as UTF-8, in which case it can be logged in the reason
+field. The reason_bytes
field supports logging the raw bytes, which can be useful
+when the value is not UTF-8 or when an endpoint does not want to decode it.
+Implementations SHOULD log at least one format, but MAY log both or none.¶
The frame_type_bytes field is the numerical value without variable-length +integer encoding.¶
+The QUIC DATAGRAM frame is defined in Section 4 of [RFC9221].¶
+The generic $TransportError
is defined here as a CDDL "type socket" extension
+point. It can be extended to support additional Transport errors.¶
By definition, an application error is defined by the application-level +protocol running on top of QUIC (e.g., HTTP/3).¶
+As such, it cannot be defined here directly. It is instead defined as an empty +CDDL "type socket" extension point.¶
+Application-level qlog definitions that wish to define new ApplicationError +strings MUST do so by extending the $ApplicationError socket as such:¶
++$ApplicationError /= "new_error_name" / + "another_new_error_name" +¶ +
These errors are defined in the TLS document as "A TLS alert is turned into a QUIC +connection error by converting the one-byte alert description into a QUIC error +code. The alert description is added to 0x100 to produce a QUIC error code from +the range reserved for CRYPTO_ERROR."¶
+This approach maps badly to a pre-defined enum. As such, the crypto_error +string is defined as having a dynamic component here, which should include the +hex-encoded and zero-padded value of the TLS alert description.¶
+The security and privacy considerations discussed in [QLOG-MAIN] apply to this +document as well.¶
+There are no IANA considerations.¶
+Much of the initial work by Robin Marx was done at the Hasselt and KU Leuven +Universities.¶
+Thanks to Jana Iyengar, Brian Trammell, Dmitri Tikhonov, Stephen Petrides, Jari +Arkko, Marcus Ihlar, Victor Vasiliev, Mirja Kühlewind, Jeremy Lainé, Kazu +Yamamoto, Christian Huitema and Hugo Landau for their feedback and suggestions.¶
+This section is to be removed before publishing as an RFC.¶
+Added PathAssigned and MigrationStateUpdated events (#336)¶
+Added extension points to parameters_set and parameters_restored (#400)¶
+Removed error_code_value from connection_closed (#386, #392)¶
+Renamed generation to key_phase for key_updated and key_discarded (#390)¶
+Removed retry_token from packet_sent and packet_received (#389)¶
+Updated ALPN handling (#385)¶
+Added key_unavailable trigger to packet_dropped (#381)¶
+Updated several uint32 to uint64¶
+ProtocolEventBody is now called ProtocolEventData (#352)¶
+Editorial changes (#402, #404, #394, #393)¶
+Updated guidance on logging events across connections (#279)¶
+Renamed 'transport' category to 'quic' (#302)¶
+Added support for multiple packet numbers in 'quic:frames_processed' (#307)¶
+Added definitions for RFC9287 (QUIC GREASE Bit extension) (#311)¶
+Added definitions for RFC9221 (QUIC Datagram Frame extension) (#310)¶
+(Temporarily) removed definitions for connection migration events (#317)¶
+Editorial and formatting changes (#298, #299, #304, #306, #327)¶
+Ensured consistent use of RawInfo to indicate raw wire bytes (#243)¶
+Renamed UnknownFrame:raw_frame_type to :frame_type_value (#54)¶
+Renamed ConnectionCloseFrame:raw_error_code to :error_code_value (#54)¶
+Changed triggers for packet_dropped (#278)¶
+Added entries to TransportError enum (#285)¶
+Changed minimum_congestion_window to uint64 (#288)¶
+Renamed key_retired to key_discarded (#185)¶
+Added fields and events for DPLPMTUD (#135)¶
+Made packet_number optional in PacketHeader (#244)¶
+Removed connection_retried event placeholder (#255)¶
+Changed QuicFrame to a CDDL plug type (#257)¶
+Moved data definitions out of the appendix into separate sections¶
+Added overview Table of Contents¶
+Added Stateless Reset Token type (#122)¶
+Change the data definition language from TypeScript to CDDL (#143)¶
+These changes were done in preparation of the adoption of the drafts by the QUIC +working group (#137)¶
+Split QUIC and HTTP/3 events into two separate documents¶
+Moved RawInfo, Importance, Generic events and Simulation events to the main +schema document.¶
+Changed to/from value options of the data_moved
event¶
Major changes:¶
+Moved data_moved from http to transport. Also made the "from" and "to" fields +flexible strings instead of an enum (#111,#65)¶
+Moved packet_type fields to PacketHeader. Moved packet_size field out of +PacketHeader to RawInfo:length (#40)¶
+Made events that need to log packet_type and packet_number use a header field +instead of logging these fields individually¶
+Added support for logging retry, stateless reset and initial tokens (#94,#86,#117)¶
+Moved separate general event categories into a single category "generic" (#47)¶
+Added "transport:connection_closed" event (#43,#85,#78,#49)¶
+Added version_information and alpn_information events (#85,#75,#28)¶
+Added parameters_restored events to help clarify 0-RTT behaviour (#88)¶
+Smaller changes:¶
+Merged loss_timer events into one loss_timer_updated event¶
+Field data types are now strongly defined (#10,#39,#36,#115)¶
+Renamed qpack instruction_received and instruction_sent to instruction_created +and instruction_parsed (#114)¶
+Updated qpack:dynamic_table_updated.update_type. It now has the value "inserted" +instead of "added" (#113)¶
+Updated qpack:dynamic_table_updated. It now has an "owner" field to +differentiate encoder vs decoder state (#112)¶
+Removed push_allowed from http:parameters_set (#110)¶
+Removed explicit trigger field indications from events, since this was moved to +be a generic property of the "data" field (#80)¶
+Updated transport:connection_id_updated to be more in line with other similar +events. Also dropped importance from Core to Base (#45)¶
+Added length property to PaddingFrame (#34)¶
+Added packet_number field to transport:frames_processed (#74)¶
+Added a way to generically log packet header flags (first 8 bits) to +PacketHeader¶
+Added additional guidance on which events to log in which situations (#53)¶
+Added "simulation:scenario" event to help indicate simulation details¶
+Added "packets_acked" event (#107)¶
+Added "datagram_ids" to the datagram_X and packet_X events to allow tracking of +coalesced QUIC packets (#91)¶
+Extended connection_state_updated with more fine-grained states (#49)¶
+Event and category names are now all lowercase¶
+Added many new events and their definitions¶
+"type" fields have been made more specific (especially important for PacketType +fields, which are now called packet_type instead of type)¶
+Events are given an importance indicator (issue #22)¶
+Event names are more consistent and use past tense (issue #21)¶
+Triggers have been redefined as properties of the "data" field and updated for most events (issue #23)¶
+HTTP/3 qlog event definitions | +plain text | +same as main | +
Main logging schema for qlog | +plain text | +same as main | +
QUIC event definitions for qlog | +plain text | +same as main | +