# How to Enable and Utilize qlog for Debugging XQUIC Connections

> Debug XQUIC connections with qlog. Learn how to enable the built-in qlog subsystem and use the Python parser to visualize QUIC protocol events for effective troubleshooting.

- Repository: [Alibaba/xquic](https://github.com/alibaba/xquic)
- Tags: how-to-guide
- Published: 2026-02-24

---

**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](https://github.com/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`](https://github.com/alibaba/xquic/blob/main/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`](https://github.com/alibaba/xquic/blob/main/src/common/xqc_log.c) |
| [`xqc_log_event_callback.c`](https://github.com/alibaba/xquic/blob/main/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`](https://github.com/alibaba/xquic/blob/main/src/common/xqc_log_event_callback.c) |
| Engine configuration | Stores `cfg_qlog_importance`; default is `EVENT_IMPORTANCE_EXTRA`. | [`src/transport/xqc_engine.c`](https://github.com/alibaba/xquic/blob/main/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`](https://github.com/alibaba/xquic/blob/main/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:

```bash
./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`](https://github.com/alibaba/xquic/blob/main/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:

```bash
./tests/test_client \
    -a 127.0.0.1 \
    -p 4433 \
    --qlog_importance e

```

### Disabling qlog

To completely suppress qlog output, use the disable flag:

```bash
./tests/test_client --qlog_disable

```

This sets the global `log_disable` flag (defined in [`src/common/xqc_log.c`](https://github.com/alibaba/xquic/blob/main/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.

```c
#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`](https://github.com/alibaba/xquic/blob/main/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:

```bash
python3 scripts/qlog_parser.py ./clog > qlog.json

```

The parser ([`scripts/qlog_parser.py`](https://github.com/alibaba/xquic/blob/main/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`](https://github.com/alibaba/xquic/blob/main/qlog.json) in a compatible viewer:

- **Chrome**: Navigate to `chrome://net-internals/#qlog` and click "Load" to select the file.
- **Mozilla Firefox**: Use `about:debugging` and 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.c`](https://github.com/alibaba/xquic/blob/main/src/common/xqc_log.c) and requires only runtime activation.
- **Control verbosity**: Set `cfg_qlog_importance` to `s`, `c`, `b`, `e`, or `r` to filter events by importance level.
- **Command-line usage**: Use `--qlog_importance <level>` with `test_client` or `test_server`; disable with `--qlog_disable`.
- **API integration**: Configure `xqc_config_t` before `xqc_engine_create()` and register a custom `xqc_qlog_event_write` callback.
- **Post-processing**: Convert raw logs to JSON using [`scripts/qlog_parser.py`](https://github.com/alibaba/xquic/blob/main/scripts/qlog_parser.py) before 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`](https://github.com/alibaba/xquic/blob/main/tests/test_client.c) (around line 4625) and [`tests/test_server.c`](https://github.com/alibaba/xquic/blob/main/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`](https://github.com/alibaba/xquic/blob/main/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.