How to Enable and Utilize qlog for Debugging XQUIC Connections
XQUIC provides a built-in qlog subsystem that records QUIC protocol events in JSON format; enable it via runtime flags or API configuration, then convert logs using the provided Python parser for visualization.
The qlog framework in alibaba/xquic allows developers to capture detailed, timestamped traces of QUIC connections for offline analysis. Because the subsystem is compiled into the library by default, you only need to configure the importance level and output destination at runtime to start debugging XQUIC connections with qlog.
Understanding XQUIC's qlog Architecture
The qlog implementation centers on a central logger object that filters events by importance before dispatching them to user-defined callbacks.
Core Components
| Component | Role | Source File |
|---|---|---|
xqc_log_t |
Central logger holding the Source Connection ID (SCID), importance threshold, and callback pointers. | src/common/xqc_log.c |
xqc_qlog_implement() |
Formats events, applies importance filtering, and routes output to either the generic error log or the qlog-specific callback. | src/common/xqc_log.c |
xqc_log_event_callback.c |
Defines per-event callbacks (e.g., connection start, packet sent, stream state change) that invoke xqc_qlog_implement. |
src/common/xqc_log_event_callback.c |
| Engine configuration | Stores cfg_qlog_importance; default is EVENT_IMPORTANCE_EXTRA. |
src/transport/xqc_engine.c |
Event Importance Levels
XQUIC uses a character-based scheme to control verbosity. The filter is applied inside xqc_qlog_implement() (lines 38-46 of xqc_log.c), where events below the configured threshold are discarded.
| Character | Macro | Description |
|---|---|---|
s |
EVENT_IMPORTANCE_SELECTED |
Only user-selected events. |
c |
EVENT_IMPORTANCE_CORE |
Core protocol events (handshake, loss detection). |
b |
EVENT_IMPORTANCE_BASE |
Base lifecycle events (connection open/close). |
e |
EVENT_IMPORTANCE_EXTRA |
Extra diagnostics (buffer states, stream flow control). |
r |
EVENT_IMPOTANCE_REMOVED |
All possible events (no filtering). |
Enabling qlog via Command Line
The test binaries (test_client and test_server) provide command-line switches to control qlog output without modifying source code.
Server Configuration
Start the server with an importance level to capture connection traces:
./tests/test_server \
-a 0.0.0.0 \
-p 4433 \
--qlog_importance c
By default, the server writes to ./clog (configured in tests/test_server.c at line 4140). The file contains both human-readable logs and raw qlog lines.
Client Configuration
Similarly, enable qlog on the client to trace the outgoing connection:
./tests/test_client \
-a 127.0.0.1 \
-p 4433 \
--qlog_importance e
Disabling qlog
To completely suppress qlog output, use the disable flag:
./tests/test_client --qlog_disable
This sets the global log_disable flag (defined in src/common/xqc_log.c line 12) to XQC_TRUE, causing xqc_qlog_implement() to return early before any formatting occurs.
Enabling qlog Programmatically via API
For production integrations, configure qlog through the engine API before creating connections.
#include <xquic/xquic.h>
/* 1. Obtain default configuration */
xqc_config_t cfg;
xqc_engine_get_default_config(&cfg, XQC_ENGINE_CLIENT);
/* 2. Set importance level (core events only) */
cfg.cfg_qlog_importance = EVENT_IMPORTANCE_CORE;
cfg.cfg_log_event = 1; /* Enable event logging */
/* 3. Create engine with config */
xqc_engine_t *engine;
xqc_engine_create(&engine, XQC_ENGINE_CLIENT, &cfg, ...);
/* 4. Register a custom qlog writer callback */
static ssize_t my_qlog_writer(qlog_event_importance_t imp,
const void *buf, size_t count,
void *user_data)
{
int fd = *(int *)user_data;
return write(fd, buf, count);
}
/* Assign callback and user data (file descriptor) */
engine->log->log_callbacks->xqc_qlog_event_write = my_qlog_writer;
int qlog_fd = open("./my_qlog.txt", O_WRONLY|O_CREAT|O_APPEND, 0644);
engine->log->log_callbacks->user_data = &qlog_fd;
With this setup, every qlog event passing the importance filter is streamed to my_qlog.txt in real-time.
Converting and Visualizing qlog Output
Raw qlog data written by XQUIC is not immediately valid JSON; it must be converted using the provided parser.
Converting Raw Logs to JSON
Use the Python script located in the repository:
python3 scripts/qlog_parser.py ./clog > qlog.json
The parser (scripts/qlog_parser.py) reads the text-based log format and produces a standards-compliant qlog JSON object suitable for external tools.
Viewing qlog Files
Once converted, open qlog.json in a compatible viewer:
- Chrome: Navigate to
chrome://net-internals/#qlogand click "Load" to select the file. - Mozilla Firefox: Use
about:debuggingand load the qlog for analysis. - Third-party tools: Import into Wireshark with qlog plugins or other QUIC visualization utilities.
Summary
- qlog is built-in: The subsystem is always compiled in
src/common/xqc_log.cand requires only runtime activation. - Control verbosity: Set
cfg_qlog_importancetos,c,b,e, orrto filter events by importance level. - Command-line usage: Use
--qlog_importance <level>withtest_clientortest_server; disable with--qlog_disable. - API integration: Configure
xqc_config_tbeforexqc_engine_create()and register a customxqc_qlog_event_writecallback. - Post-processing: Convert raw logs to JSON using
scripts/qlog_parser.pybefore viewing in Chrome or Firefox developer tools.
Frequently Asked Questions
What is the default qlog importance level in XQUIC?
By default, XQUIC initializes cfg_qlog_importance to EVENT_IMPORTANCE_EXTRA (character e). This setting captures extra diagnostic information including packet buffer states and stream flow control updates, providing a balance between verbosity and performance.
Can I enable qlog without modifying source code?
Yes. The test binaries (test_client and test_server) support the --qlog_importance command-line flag to set the importance level at runtime. You can also disable qlog entirely using --qlog_disable. These options are parsed in tests/test_client.c (around line 4625) and tests/test_server.c (around line 2620).
How do I convert XQUIC qlog output to a viewable format?
XQUIC writes qlog data as plain text lines interleaved with other logs. To convert this to standards-compliant JSON, run the provided Python script: python3 scripts/qlog_parser.py ./clog > output.json. The resulting JSON file can be loaded into Chrome's chrome://net-internals/#qlog or Firefox's debugging tools for visualization.
Is there a performance penalty for enabling qlog?
Yes, but it is controllable. The xqc_qlog_implement() function in src/common/xqc_log.c filters events by importance before formatting, so events below the configured threshold return early with minimal overhead. However, high-importance levels like r (all events) or e (extra) will incur CPU and I/O costs from formatting and writing to disk. For production environments, use c (core) or s (selected) importance levels.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →