Draft: draft-ietf-quic-qlog-main-schema

Commentary: Additionally also specified Media Types and file extensions for the various formats  to , and . 
 Hello all , I 've tried to resolve all the excellent comments as well as possible . If you have time , please try to review the new changes , and then I will mint a new  tomorrow ! 
 The field is part of the QlogFile and QlogFileNDJSON , so it 's a bit circular to decide how to parse the object . When processing large files , it can be a pain to decide , One technique would be to look at the first line of a file to determine the qlog format before attempting to parse it . But that seems like a hack . It also does n't help if a large qlog is written into a file as a single line . Knowing the format up front , such as by unique file extensions , would mean that tools or applications can make more assumptions about how to deal with the file . For instance , I could simply use to safely slice up NDJSON files today , without requireing deep knowledge of qlog formats . 
 This seems like a general issue wider than just qlog , and one that IIUC has traditionally been solved by a combination of looking at extensions AND the first few bytes / line of the file in question ( e.g. , image format headers ) . While we could indicate a specific extension for the different qlog serialization types in the spec , tools probably would still want to just support as a valid file in any format . In qvis for example , we do to guess its format , so we support both options for a before actual parsing . As such , I feel it 's one of those cases that we could / should spec , but that it would n't have full impact IRL for reusable tooling . An additional aspect is using mime - types when transferring over e.g. , HTTP , see , where I do also think we should define the media types in the draft . So , I 'd propose to indeed recommend ( SHOULD , not MUST ) .qlog for normal JSON and .sqlog ( for " streaming " qlog ) for json - seq . What do you think ? 
 We picked . This issue can be closed now . 
 The document includes considerations about streaming serialization and specifies a way to do this using NDJSON ( new - line delimited JSON ) . There 's two things that the Working Group should consider : 1 ) Does streaming serialization need to be defined as part of the qlog main schema ? 2 ) If the answer to 1 is yes , what format should be used . During IETF 111 , it was noted that is an IETF - defined format that achieves similar streaming properties as NDJSON . There might be a preference for using RFC 7464 pending the outcome of . 
 As discussed previously , I have now experimented with the " JSON text sequences " format described in While it is a bit annoying to have to add the RecordSeparator ( RS , % x1E , U+001E ) character before each event , in practice it was easy enough to integrate the new format with tools like and use it with existing tools like jq , grep , sed and awk . As such , we propose to indeed replace the NDJSON format in draft-00 with the RFC 7464 format . This has several advantages , among which : an existing RFC to refer to instead of having to define the format in qlog itself ( since NDJSON is not an official standard anywhere ) an existing mime - type ( see also ) " pretty printed " JSON ( records / events can span multiple lines ) , while NDJSON does not support \n characters in an event I will create a PR to make this change in the text . Below are some example files and practical guidelines for those who wish to start experimenting with this themselves . cc contains 2 files in both NDJSON , line - based json - seq and pretty - printed json - seq formats . These were generated by taking quic - go  outputs from and then adding the RecordSeparator character to them using the following sed monstrosity : I then also changed the " qlog - format " field on the first line to " JSON - SEQ " ( instead of " NDJSON " ) . That should be enough to get the files to load in qvis ( " qlog - version " is currently still " draft-02 " , we 'll probably want to change that for the upcoming ietf - draft-01 ) . Of course , implementations that output the new format should just output the \x1E character directly instead of post - processing the files like this ... how to do that depends on the programming language of course . I then also tested the json - seq files with some common tooling , especially . has built - in support for text - sequences by passing in the option . With the option on , should also still be able to process normal  and  , so it should be safe to " leave it on " , no matter which qlog format you 're processing . For example : Feel free to test this out yourselves and let me know if you find problems with the new format ! 
 I 've been using NDJSON and I like the simplicity , but the inability to have newlines in the JSON output was a point of contention for me . The ability to add some newlines to make events more readable would be nice . The addition of the character is gross but solves the problem while using an existing IETF standard . 
 My two cents would go to using NDJSON rather than JSON Text Sequences ( RFC 7464 ) , because the former is more widespread , easy to use with existing line - oriented tools , and because I do not think we need the properties being provided by RFC 7464 ( e.g. , process dataset in the middle , as discussed in [ Section 1 of RFC 7464 ] { } ) . I would not mind too strongly about switching to JSON Text Sequences , as it is possible to convert from that to NDJSON , but my preference goes to using something more widespread - that was the reason we chose JSON instead of some binary format , after all . 
 As an individual : I prefer to base the streaming output on an IETF standard . Building something for general purpose tools is useful and valuable today but I would like to set up qlog to be something that integrates well into IETF paradigms in the long term . The transformation to newline - only delimitation is trivial . If its useful , I think we can mention that without referring to NDJSON explicitly . 
 Thanks all for the additional input . We decided to try the JSON Text Sequences for now and see how it goes ( does n't mean we ca n't later switch to something else if Text Sequences turn out horrible somehow ) . The new approach is detailed in the new  of the main schema here : Feel free to implement the new format and let us know results , remarks , feedback , etc . Thanks ! 
 We have n't heard major pushback against this since the introduction , so I 'm going to close this issue for now . 
 What is the of the qlog files ? 
 This is currently not yet defined ... At first instinct , I 'd say , but I 'm not sure how we 'd indicate the difference between normal JSON and newline - delimited  ( if we even decide to keep that ) . Maybe and then something like down the line ? Not sure how easy / difficult that would be to deal with for qlog tooling / how media - type parsers typically deal with this type of thing . 
 Thank you for the response . For context , the reason I asked is because h2o has a well - known URI for serving traces , see At the moment , we use a custom ndjson format , but if we are to use qlog , there has to be a media - type . 
 Fixed as far as I can tell , closing . 
 Design changes LGTM . There are some broader editorial improvements that could be made but they can be done later on ( when we 're not up agaisnt the publish cutoff date ) .
Mailing list commentary: Hello folks , Today and I have submitted a tiny I - D called draft - kazuho - httpbis - selftrace . The draft specifies a well - known URI to be used for providing a trace of a particular HTTP/3 connection ( e.g. , qlog ) on that same HTTP/3 connection . One of the biggest hurdles in analyzing HTTP/3 performance issues is obtaining traces that show the symptoms . That is because clients being affected by issues have to coordinate with the server operators to collect the traces . This PR solves the problem by defining a well - known URI for serving a trace to the client on the HTTP connection that the client is using . When a user sees an issue , they can collect the traces themselves and provide it to the server operator . We have already implemented the feature in h2o , and doing so was easy , assuming that the underlying QUIC stack already defines callbacks for collecting trace events , see lib / handler / self_trace.c of . We also have a public endpoint ; to try it out , first open ( which starts streaming a video ) , then open . While the video is being served , you would see the trace flowing through the well - known URI . At the moment , we are using a custom JSON format for the trace , but when gzip compression is applied on - the - fly , the overhead of sending a trace alongside ordinary HTTP responses is less than 10 % . Therefore , we tend to believe that this approach would work well in practice . Please let us know what you think - your feedback is very welcome .
Paragraph (version A):
This document describes how to employ JSON and NDJSON as textual
serializations for qlog in concrete-formats.  Other documents will
describe how to utilize other concrete serialization options, though
tips and requirements for these are also listed in this document
(concrete-formats).
Paragraph (version B):
This document describes how to employ JSON (RFC8259) and JSON Text
Sequences (RFC7464) as textual serializations for qlog in concrete-
formats.  Other documents will describe how to utilize other concrete
serialization options, though tips and requirements for these are
also listed in this document (concrete-formats).
Paragraph (version A):
A qlog file should be able to contain several indivdual traces and
logs from multiple vantage points that are in some way related.  To
that end, the top-level element in the qlog schema defines only a
small set of "header" fields and an array of component traces.  For
this document, the required "qlog_version" field MUST have a value of
"qlog-03-WIP".
Paragraph (version A):
there have been several previously broadly deployed qlog versions
based on older drafts of this document (see draft-marx-qlog-main-
schema).  The old values for the "qlog_version" field were "draft-
00", "draft-01" and "draft-02".  When qlog was moved to the QUIC
working group, we decided to increment the existing counter,
rather than reverting back to -00.  As such, any numbering
indicating in the "qlog_version" field is explicitly not tied to a
particular version of the draft documents.
Paragraph (version B):
A qlog file should be able to contain several indivdual traces and
logs from multiple vantage points that are in some way related.  To
that end, the top-level element in the qlog schema defines only a
small set of "header" fields and an array of component traces.  For
this document, the required "qlog_version" field MUST have a value of
"0.3".
Paragraph (version B):
there have been several previously broadly deployed qlog versions
based on older drafts of this document (see draft-marx-qlog-main-
schema).  The old values for the "qlog_version" field were "draft-
00", "draft-01" and "draft-02".  When qlog was moved to the QUIC
working group, we decided to switch to a new versioning scheme
which is independent of individual draft document numbers.
However, we do start from 0.3, as conceptually 0.0, 0.1 and 0.2
can map to draft-00, draft-01 and draft-02.
Paragraph (version A):
This being said, the authors prefer JSON as the basis for storing
qlog, as it retains full flexibility and maximum interoperability.
Storage overhead can be managed well in practice by employing
compression.  For this reason, this document details both how to
practically transform qlog schema definitions to JSON and to the
streamable NDJSON.  We discuss concrete options to bring down JSON
size and processing overheads in optimizations.
Paragraph (version B):
This being said, the authors prefer JSON as the basis for storing
qlog, as it retains full flexibility and maximum interoperability.
Storage overhead can be managed well in practice by employing
compression.  For this reason, this document details both how to
practically transform qlog schema definitions to JSON and to the
streamable JSON Text Sequences.  We discuss concrete options to bring
down JSON size and processing overheads in optimizations.
Paragraph (version B):
When using normal JSON serialization, the file extension/suffix
SHOULD be ".qlog" and the Media Type (if any) SHOULD be "application/
qlog+json" RFC6839.
Paragraph (version A):
One of the downsides of using pure JSON 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.  As most platforms
do not provide a standard streaming JSON parser (which would be able
to deal with this problem), this document also provides a qlog
mapping to a streamable JSON format called Newline-Delimited JSON
(NDJSON) [7].
Paragraph (version A):
When mapping qlog to NDJSON, the "qlog_format" field MUST have the
value "NDJSON".
Paragraph (version A):
NDJSON is very similar to JSON, except that it interprets each line
in a file as a fully separate JSON object.  Put differently, unlike
default JSON, it does not require a file to be wrapped as a full
object with "{ ... }" or "[ ... ]".  Using this setup, qlog events
can simply be appended as individually serialized lines at the back
of a streamed logging file.
Paragraph (version A):
For this to work, some qlog definitions have to be adjusted however.
Mainly, events are no longer part of the "events" array in the Trace
object, but are instead logged separately from the qlog "file header"
(QlogFile class in top-level).  Additionally, qlog's NDJSON mapping
does not allow logging multiple individual traces in a single qlog
file.  As such, the QlogFile:traces field is replaced by the singular
"trace" field, which simply contains the Trace data directly.  An
example can be seen in ndjson-example.  Note that the "group_id"
field can still be used on a per-event basis to include events from
conceptually different sources in a single NDJSON qlog file.
Paragraph (version A):
Note as well from ndjson-example that the file's header
(QlogFileNDJSON) also needs to be fully serialized on a single line
to be NDJSON compatible.
Paragraph (version A):
Finally, while not specifically required by the NDJSON specification,
all qlog field names in a NDJSON serialization MUST be lowercase.
Paragraph (version A):
Note that NDJSON is not supported in most default programming
environments (unlike normal JSON).  However, several custom NDJSON
parsing libraries exist [8] that can be used and the format is easy
enough to parse with existing implementations (i.e., by splitting the
file into its component lines and feeding them to a normal JSON
parser individually, as each line by itself is a valid JSON object).
Paragraph (version A):
Both the JSON and NDJSON 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 (ND)JSON
(de)serialization performance is typically (slightly) lower than that
of more optimized and predictable formats.  Both aspects make these
formats more challenging (though still practical [9]) to use in large
scale setups.
Paragraph (version A):
During the development of qlog, we compared a multitude of
alternative formatting and optimization options.  The results of this
study are summarized on the qlog github repository [10].  The rest of
this section discusses some of these approaches implementations could
choose and the expected gains and tradeoffs inherent therein.  Tools
SHOULD support mainly the compression options listed in compression,
as they provide the largest wins for the least cost overall.
Paragraph (version B):
One of the downsides of using pure JSON 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.  As most platforms
do not provide a standard streaming JSON parser (which would be able
to deal with this problem), this document also provides a qlog
mapping to a streamable JSON format called JSON Text Sequences (JSON-
SEQ) (RFC7464).
Paragraph (version B):
When mapping qlog to JSON-SEQ, the "qlog_format" field MUST have the
value "JSON-SEQ".
Paragraph (version B):
When using JSON-SEQ serialization, the file extension/suffix SHOULD
be ".sqlog" (for "streaming" qlog) and the Media Type (if any) SHOULD
be "application/qlog+json-seq" RFC8091.
Paragraph (version B):
JSON Text Sequences are very similar to JSON, except that JSON
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.
Paragraph (version B):
Each qlog event is serialized and interpreted as an individual JSON
Text Sequence record, and can simply be appended as a new object at
the back of an event stream or log file.  Put differently, unlike
default JSON, it does not require a file to be wrapped as a full
object with "{ ... }" or "[... ]".
Paragraph (version B):
For this to work, some qlog definitions have to be adjusted however.
Mainly, events are no longer part of the "events" array in the Trace
object, but are instead logged separately from the qlog "header", as
indicated by the TraceSeq object in json-seq-example.  Additionally,
qlog's JSON-SEQ mapping does not allow logging multiple individual
traces in a single qlog file.  As such, the QlogFile:traces field is
replaced by the singular QlogFileSeq:trace field.  An example can be
seen in json-seq-example.  Note that 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.
Paragraph (version B):
Note: while not specifically required by the JSON-SEQ specification,
all qlog field names in a JSON-SEQ serialization MUST be lowercase.
Paragraph (version B):
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).
Paragraph (version B):
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 make these
formats more challenging (though still practical [7]) to use in large
scale setups.
Paragraph (version B):
During the development of qlog, we compared a multitude of
alternative formatting and optimization options.  The results of this
study are summarized on the qlog github repository [8].  The rest of
this section discusses some of these approaches implementations could
choose and the expected gains and tradeoffs inherent therein.  Tools
SHOULD support mainly the compression options listed in compression,
as they provide the largest wins for the least cost overall.
Paragraph (version A):
the extension ".qlog.A.B").  This allows tooling to start at the back
of the extension to "undo" applied optimizations to finally arrive at
the expected qlog representation.
Paragraph (version A):
The first general category of optimizations is to alter the
representation of data within an (ND)JSON qlog file to reduce file
size.
Paragraph (version A):
The first option is to employ a scheme similar to the CSV (comma
separated value rfc4180) format, which utilizes the concept of column
"headers" to prevent repeating field names for each datapoint
instance.  Concretely for JSON qlog, several field names are repeated
with each event (i.e., time, name, data).  These names could be
extracted into a separate list, after which qlog events could be
serialized as an array of values, as opposed to a full object.  This
approach was a key part of the original qlog format (prior to draft
02) using the "event_fields" field.  However, tests showed that this
optimization only provided a mean file size reduction of 5% (100MB to
95MB) while significantly increasing the implementation complexity,
and this approach was abandoned in favor of the default JSON setup.
Implementations using this format should not employ a separate file
extension (as it still uses JSON), but rather employ a new value of
"JSON.namedheaders" (or "NDJSON.namedheaders") for the "qlog_format"
field (see top-level).
Paragraph (version B):
the extension ".(s)qlog.A.B").  This allows tooling to start at the
back of the extension to "undo" applied optimizations to finally
arrive at the expected qlog representation.
Paragraph (version B):
The first general category of optimizations is to alter the
representation of data within an JSON(-SEQ) qlog file to reduce file
size.
Paragraph (version B):
The first option is to employ a scheme similar to the CSV (comma
separated value RFC4180) format, which utilizes the concept of column
"headers" to prevent repeating field names for each datapoint
instance.  Concretely for JSON qlog, several field names are repeated
with each event (i.e., time, name, data).  These names could be
extracted into a separate list, after which qlog events could be
serialized as an array of values, as opposed to a full object.  This
approach was a key part of the original qlog format (prior to draft-
02) using the "event_fields" field.  However, tests showed that this
optimization only provided a mean file size reduction of 5% (100MB to
95MB) while significantly increasing the implementation complexity,
and this approach was abandoned in favor of the default JSON setup.
Implementations using this format should not employ a separate file
extension (as it still uses JSON), but rather employ a new value of
"JSON.namedheaders" (or "JSON-SEQ.namedheaders") for the
"qlog_format" field (see top-level).
Paragraph (version A):
The second option is to replace field values and/or names with
indices into a (dynamic) lookup table.  This is a common compression
technique and can provide significant file size reductions (up to 50%
in our tests, 100MB to 50MB).  However, this approach is even more
difficult to implement efficiently and requires either including the
(dynamic) table in the resulting file (an approach taken by for
example Chromium's NetLog format [11]) or defining a (static) table
up-front and sharing this between implementations.  Implementations
using this approach should not employ a separate file extension (as
it still uses JSON), but rather employ a new value of
"JSON.dictionary" (or "NDJSON.dictionary") for the "qlog_format"
field (see top-level).
Paragraph (version B):
The second option is to replace field values and/or names with
indices into a (dynamic) lookup table.  This is a common compression
technique and can provide significant file size reductions (up to 50%
in our tests, 100MB to 50MB).  However, this approach is even more
difficult to implement efficiently and requires either including the
(dynamic) table in the resulting file (an approach taken by for
example Chromium's NetLog format [9]) or defining a (static) table
up-front and sharing this between implementations.  Implementations
using this approach should not employ a separate file extension (as
it still uses JSON), but rather employ a new value of
"JSON.dictionary" (or "JSON-SEQ.dictionary") for the "qlog_format"
field (see top-level).
Paragraph (version A):
The second general category of optimizations is to utilize a
(generic) compression scheme for textual data.  As qlog in the
(ND)JSON format typically contains a large amount of repetition, off-
the-shelf (text) compression techniques typically succeed very well
in bringing down file sizes (regularly with up to two orders of
magnitude in our tests, even for "fast" compression levels).  As
such, utilizing compression is recommended before attempting other
optimization options, even though this might (somewhat) increase
processing costs due to the additional compression step.
Paragraph (version B):
The second general category of optimizations is to utilize a
(generic) compression scheme for textual data.  As qlog in the JSON(-
SEQ) format typically contains a large amount of repetition, off-the-
shelf (text) compression techniques typically succeed very well in
bringing down file sizes (regularly with up to two orders of
magnitude in our tests, even for "fast" compression levels).  As
such, utilizing compression is recommended before attempting other
optimization options, even though this might (somewhat) increase
processing costs due to the additional compression step.
Paragraph (version A):
The first option is to use GZIP compression (RFC1952).  This generic
compression scheme provides multiple compression levels (providing a
trade-off between compression speed and size reduction).  Utilized at
level 6 (a medium setting thought to be applicable for streaming
compression of a qlog stream in commodity devices), gzip compresses
qlog JSON files to 7% of their initial size on average (100MB to
7MB).  For this option, the file extension .qlog.gz SHOULD BE used.
The "qlog_format" field should still reflect the original JSON
formatting of the qlog data (e.g., "JSON" or "NDJSON").
Paragraph (version B):
The first option is to use GZIP compression (RFC1952).  This generic
compression scheme provides multiple compression levels (providing a
trade-off between compression speed and size reduction).  Utilized at
level 6 (a medium setting thought to be applicable for streaming
compression of a qlog stream in commodity devices), gzip compresses
qlog JSON files to 7% of their initial size on average (100MB to
7MB).  For this option, the file extension .(s)qlog.gz SHOULD BE
used.  The "qlog_format" field should still reflect the original JSON
formatting of the qlog data (e.g., "JSON" or "JSON-SEQ").
Paragraph (version A):
The second option is to use Brotli compression (RFC7932).  While
similar to gzip, this more recent compression scheme provides a
better efficiency.  It also allows multiple compression levels.
Utilized at level 4 (a medium setting thought to be applicable for
streaming compression of a qlog stream in commodity devices), brotli
compresses qlog JSON files to 7% of their initial size on average
(100MB to 7MB).  For this option, the file extension .qlog.br SHOULD
BE used.  The "qlog_format" field should still reflect the original
JSON formatting of the qlog data (e.g., "JSON" or "NDJSON").
Paragraph (version B):
The second option is to use Brotli compression (RFC7932).  While
similar to gzip, this more recent compression scheme provides a
better efficiency.  It also allows multiple compression levels.
Utilized at level 4 (a medium setting thought to be applicable for
streaming compression of a qlog stream in commodity devices), brotli
compresses qlog JSON files to 7% of their initial size on average
(100MB to 7MB).  For this option, the file extension .(s)qlog.br
SHOULD BE used.  The "qlog_format" field should still reflect the
original JSON formatting of the qlog data (e.g., "JSON" or "JSON-
SEQ").
Paragraph (version A):
The first option is to use the CBOR (Concise Binary Object
Representation rfc7049) format.  For our purposes, CBOR can be viewed
as a straighforward binary variant of JSON.  As such, existing JSON
qlog files can be trivially converted to and from CBOR (though
slightly more work is needed for NDJSON qlogs).  While CBOR thus does
retain the full qlog flexibility, it only provides a 25% file size
reduction (100MB to 75MB) compared to textual (ND)JSON.  As CBOR
support in programming environments is not as widespread as that of
textual JSON and the format lacks human readability, CBOR was not
chosen as the default qlog format.  For this option, the file
extension .qlog.cbor SHOULD BE used.  The "qlog_format" field should
still reflect the original JSON formatting of the qlog data (e.g.,
"JSON" or "NDJSON").
Paragraph (version B):
The first option is to use the CBOR (Concise Binary Object
Representation RFC7049) format.  For our purposes, CBOR can be viewed
as a straighforward binary variant of JSON.  As such, existing JSON
qlog files can be trivially converted to and from CBOR (though
slightly more work is needed for JSON-SEQ qlogs to convert them to
CBOR-SEQ, see RFC8742).  While CBOR thus does retain the full qlog
flexibility, it only provides a 25% file size reduction (100MB to
75MB) compared to textual JSON(-SEQ).  As CBOR support in programming
environments is not as widespread as that of textual JSON and the
format lacks human readability, CBOR was not chosen as the default
qlog format.  For this option, the file extension .(s)qlog.cbor
SHOULD BE used.  The "qlog_format" field should still reflect the
original JSON formatting of the qlog data (e.g., "JSON" or "JSON-
SEQ").  The media type should indicate both whether JSON or JSON Text
Sequences are used, as well as whether CBOR or CBOR Sequences are
used (see the table below).
Paragraph (version A):
this option, the file extension .qlog.protobuf SHOULD BE used.  The
"qlog_format" field should reflect the different internal format, for
example: "qlog_format": "protobuf".
Paragraph (version B):
this option, the file extension .(s)qlog.protobuf SHOULD BE used.
The "qlog_format" field should reflect the different internal format,
for example: "qlog_format": "protobuf".
Paragraph (version A):
Still, qlog implementers are free to define other qlog formats
depending on their needs and context of use.  These formats should be
described in their own documents, the discussion in this document
mainly acting as inspiration and high-level guidance.  Implementers
are encouraged to add concrete qlog formats and definitions to the
designated public repository [13].
Paragraph (version B):
Still, qlog implementers are free to define other qlog formats
depending on their needs and context of use.  These formats should be
described in their own documents, the discussion in this document
mainly acting as inspiration and high-level guidance.  Implementers
are encouraged to add concrete qlog formats and definitions to the
designated public repository [11].
Paragraph (version A):
As discussed in the previous sections, a qlog file can be serialized
in a multitude of formats, each of which can conceivably be
transformed into or from one another without loss of information.
For example, a number of NDJSON streamed qlogs could be combined into
a JSON formatted qlog for later processing.  Similarly, a captured
binary qlog could be transformed to JSON for easier interpretation
and sharing.
Paragraph (version B):
As discussed in the previous sections, a qlog file can be serialized
in a multitude of formats, each of which can conceivably be
transformed into or from one another without loss of information.
For example, a number of JSON-SEQ streamed qlogs could be combined
into a JSON formatted qlog for later processing.  Similarly, a
captured binary qlog could be transformed to JSON for easier
interpretation and sharing.
Paragraph (version A):
As such, when defining a new qlog serialization format or wanting to
utilize qlog-compatible tools with existing codebases lacking qlog
support, it is recommended to define and provide a concrete mapping
from one format to default JSON-serialized qlog.  Several of such
mappings exist.  Firstly, [pcap2qlog]((https://github.com/quiclog/
pcap2qlog) transforms QUIC and HTTP/3 packet capture files to qlog.
Secondly, netlog2qlog [14] converts chromium's internal dictionary-
encoded JSON format to qlog.  Finally, quictrace2qlog [15] converts
the older quictrace format to JSON qlog.  Tools can then easily
integrate with these converters (either by incorporating them
directly or for example using them as a (web-based) API) so users can
provide different file types with ease.  For example, the qvis [16]
toolsuite supports a multitude of formats and qlog serializations.
Paragraph (version B):
As such, when defining a new qlog serialization format or wanting to
utilize qlog-compatible tools with existing codebases lacking qlog
support, it is recommended to define and provide a concrete mapping
from one format to default JSON-serialized qlog.  Several of such
mappings exist.  Firstly, [pcap2qlog]((https://github.com/quiclog/
pcap2qlog) transforms QUIC and HTTP/3 packet capture files to qlog.
Secondly, netlog2qlog [12] converts chromium's internal dictionary-
encoded JSON format to qlog.  Finally, quictrace2qlog [13] converts
the older quictrace format to JSON qlog.  Tools can then easily
integrate with these converters (either by incorporating them
directly or for example using them as a (web-based) API) so users can
provide different file types with ease.  For example, the qvis [14]
toolsuite supports a multitude of formats and qlog serializations.