# Qtap Output Examples

This appendix provides real-world examples of qtap output for different plugins, formats, and log levels. All examples are captured from actual qtap runs.

***

## http\_capture Plugin

The `http_capture` plugin captures HTTP traffic with configurable detail levels and output formats.

### Configuration Parameters

* **level**: Controls capture detail (`none`, `summary`, `details`, `full`)
* **format**: Output format (`text`, `json`)

### Text Format

#### Summary Level

Shows basic transaction information without headers or bodies.

**Configuration:**

```yaml
plugins:
  - type: http_capture
    config:
      level: summary    # Basic info only
      format: text      # Human-readable format
```

**Example Output:**

```
HTTP Transaction
================
Metadata:
  Transaction Time: 2025-10-28T16:13:51Z
  Duration: 98ms
  Direction: egress-external
  Process ID: 1134827
  Process: /usr/bin/curl
  Bytes Sent: 41
  Bytes Received: 395
Request:
  Method: GET
  URL: https://httpbin.org/get
Response:
  Status: 200
  Content-Type: application/json
```

#### Details Level

Includes HTTP headers but no request/response bodies.

**Configuration:**

```yaml
plugins:
  - type: http_capture
    config:
      level: headers    # Includes headers
      format: text
```

**Example Output:**

```
HTTP Transaction
================
Metadata:
  Transaction Time: 2025-10-28T16:16:33Z
  Duration: 4241ms
  Direction: egress-external
  Process ID: 1136045
  Process: /usr/bin/curl
  Bytes Sent: 41
  Bytes Received: 395

Request:
  Method: GET
  URL: https://httpbin.org/get
  Protocol: http2
  User-Agent: curl/8.10.1
  Request Headers:
    :authority: httpbin.org
    :method: GET
    :path: /get
    :scheme: https
    Accept: */*
    User-Agent: curl/8.10.1

Response:
  Status: 200
  Content-Type: application/json
  Response Headers:
    :status: 200
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: *
    Content-Length: 255
    Content-Type: application/json
    Date: Tue, 28 Oct 2025 16:16:37 GMT
    Server: gunicorn/19.9.0
```

#### Full Level

Captures everything: headers and request/response bodies.

**Configuration:**

```yaml
plugins:
  - type: http_capture
    config:
      level: full       # Everything including bodies
      format: text
```

**Example Output:**

```
HTTP Transaction
================
Metadata:
  Transaction Time: 2025-10-28T15:56:48Z
  Duration: 1006ms
  Direction: egress-external
  Process ID: 1115662
  Process: /usr/bin/curl
  Bytes Sent: 41
  Bytes Received: 395
  Connection ID: d40dobo7p3qp5ufu7dtg
  Endpoint ID: httpbin.org

Request:
  Method: GET
  URL: https://httpbin.org/get
  Protocol: http2
  User-Agent: curl/8.10.1
  Request Headers:
    :authority: httpbin.org
    :method: GET
    :path: /get
    :scheme: https
    Accept: */*
    User-Agent: curl/8.10.1
  Request Body:
    (empty)

Response:
  Status: 200 OK
  Content-Type: application/json
  Response Headers:
    :status: 200
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: *
    Content-Length: 255
    Content-Type: application/json
    Date: Mon, 28 Oct 2025 15:56:49 GMT
    Server: gunicorn/19.9.0
  Response Body:
    {
      "args": {},
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin.org",
        "User-Agent": "curl/8.10.1",
        "X-Amzn-Trace-Id": "Root=1-6900e621-3b1f78f52ad26b0b437b65ac"
      },
      "origin": "73.71.138.108",
      "url": "https://httpbin.org/get"
    }
```

### JSON Format

#### Summary Level

Structured JSON output with basic information.

**Configuration:**

```yaml
plugins:
  - type: http_capture
    config:
      level: summary
      format: json      # Machine-readable format
```

**Example Output:**

```json
{
  "metadata": {
    "process_id": "1139807",
    "process_exe": "/usr/bin/curl",
    "bytes_sent": 41,
    "bytes_received": 395,
    "connection_id": "d40er1g7p3qq0j13j5rg",
    "endpoint_id": "httpbin.org"
  },
  "request": {
    "method": "GET",
    "url": "https://httpbin.org/get",
    "scheme": "https",
    "path": "/get",
    "authority": "httpbin.org",
    "protocol": "http2",
    "request_id": "d40er1o7p3qq0j13j5s0",
    "user_agent": "curl/8.10.1"
  },
  "response": {
    "status": 200,
    "content_type": "application/json"
  },
  "transaction_time": "2025-10-28T16:21:55.351700841Z",
  "duration_ms": 28122,
  "direction": "egress-external"
}
```

#### Details Level

Includes request and response headers.

**Configuration:**

```yaml
plugins:
  - type: http_capture
    config:
      level: headers    # Adds header fields
      format: json
```

**Example Output:**

```json
{
  "metadata": {
    "process_id": "1140745",
    "process_exe": "/usr/bin/curl",
    "bytes_sent": 41,
    "bytes_received": 395,
    "connection_id": "d40erq07p3qq81aqqj20",
    "endpoint_id": "httpbin.org"
  },
  "request": {
    "method": "GET",
    "url": "https://httpbin.org/get",
    "scheme": "https",
    "path": "/get",
    "authority": "httpbin.org",
    "protocol": "http2",
    "request_id": "d40erq07p3qq81aqqj2g",
    "user_agent": "curl/8.10.1",
    "headers": {
      ":authority": "httpbin.org",
      ":method": "GET",
      ":path": "/get",
      ":scheme": "https",
      "Accept": "*/*",
      "User-Agent": "curl/8.10.1"
    }
  },
  "response": {
    "status": 200,
    "content_type": "application/json",
    "headers": {
      ":status": "200",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Origin": "*",
      "Content-Length": "255",
      "Content-Type": "application/json",
      "Date": "Tue, 28 Oct 2025 16:23:26 GMT",
      "Server": "gunicorn/19.9.0"
    }
  },
  "transaction_time": "2025-10-28T16:23:26.351652939Z",
  "duration_ms": 21744,
  "direction": "egress-external"
}
```

#### Full Level

Complete capture including base64-encoded request/response bodies.

**Configuration:**

```yaml
plugins:
  - type: http_capture
    config:
      level: full       # Complete capture
      format: json
```

**Example Output:**

```json
{
  "metadata": {
    "process_id": "1143058",
    "process_exe": "/usr/bin/curl",
    "bytes_sent": 41,
    "bytes_received": 395,
    "connection_id": "d40eto87p3qr61us0r5g",
    "endpoint_id": "httpbin.org"
  },
  "request": {
    "method": "GET",
    "url": "https://httpbin.org/get",
    "scheme": "https",
    "path": "/get",
    "authority": "httpbin.org",
    "protocol": "http2",
    "request_id": "d40eto87p3qr61us0r70",
    "user_agent": "curl/8.10.1",
    "headers": {
      ":authority": "httpbin.org",
      ":method": "GET",
      ":path": "/get",
      ":scheme": "https",
      "Accept": "*/*",
      "User-Agent": "curl/8.10.1"
    }
  },
  "response": {
    "status": 200,
    "content_type": "application/json",
    "headers": {
      ":status": "200",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Origin": "*",
      "Content-Length": "255",
      "Content-Type": "application/json",
      "Date": "Tue, 28 Oct 2025 16:27:14 GMT",
      "Server": "gunicorn/19.9.0"
    },
    "body": "ewogICJhcmdzIjoge30sIAogICJoZWFkZXJzIjogewogICAgIkFjY2VwdCI6ICIqLyoiLCAKICAgICJIb3N0IjogImh0dHBiaW4ub3JnIiwgCiAgICAiVXNlci1BZ2VudCI6ICJjdXJsLzguMTAuMSIsIAogICAgIlgtQW16bi1UcmFjZS1JZCI6ICJSb290PTEtNjkwMGVlZTEtMmVkNjgyN2Y2NjVhOTY5NjZkMTUxNTVkIgogIH0sIAogICJvcmlnaW4iOiAiNzMuNzEuMTM4LjEwOCIsIAogICJ1cmwiOiAiaHR0cHM6Ly9odHRwYmluLm9yZy9nZXQiCn0K"
  },
  "transaction_time": "2025-10-28T16:27:14.951732976Z",
  "duration_ms": 1428,
  "direction": "egress-external"
}
```

**Note**: Response body is base64-encoded. Decoded value:

```json
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/8.10.1",
    "X-Amzn-Trace-Id": "Root=1-6900eee1-2ed6827f665a96966d15155d"
  },
  "origin": "73.71.138.108",
  "url": "https://httpbin.org/get"
}
```

***

## access\_logs Plugin

The `access_logs` plugin formats HTTP traffic as access log entries, similar to web server logs.

### Configuration Parameters

* **mode**: Controls capture detail (`summary`, `details`, `full`)
* **format**: Output format (`console`, `json`)

### Console Format

#### Summary Mode

Single-line access log format.

**Configuration:**

```yaml
plugins:
  - type: access_logs
    config:
      mode: summary     # Minimal access log format
      format: console   # Terminal-friendly output
```

**Example Output:**

```
■ /usr/bin/curl → GET https://httpbin.org/get 503 Service Unavailable
```

#### Details Mode

Includes metadata, request headers, and response headers.

**Configuration:**

```yaml
plugins:
  - type: access_logs
    config:
      mode: details     # Adds headers
      format: console
```

**Example Output:**

```
=========================================================================
■ /usr/bin/curl → GET https://httpbin.org/get 503 Service Unavailable
=========================================================================

------------------ META ------------------
PID: 1145353
Exe: /usr/bin/curl
Direction: egress-external
Bytes Sent: 41
Bytes Received: 232

------------------ REQUEST ------------------
GET httpbin.org http2
User-Agent: curl/8.10.1
Accept: */*
:authority: httpbin.org
:method: GET
:path: /get
:scheme: https

------------------ RESPONSE ------------------
503 Service Unavailable
Content-Type: text/html
Content-Length: 162
:status: 503
Server: awselb/2.0
Date: Tue, 28 Oct 2025 16:31:49 GMT
```

#### Full Mode

Includes everything: metadata, headers, and request/response bodies.

**Configuration:**

```yaml
plugins:
  - type: access_logs
    config:
      mode: full        # Complete access log entry
      format: console
```

**Example Output:**

```
=========================================================================
■ /usr/bin/curl → GET https://httpbin.org/get 503 Service Unavailable
=========================================================================

------------------ META ------------------
PID: 1145889
Exe: /usr/bin/curl
Direction: egress-external
Bytes Sent: 41
Bytes Received: 232

------------------ REQUEST ------------------
GET httpbin.org http2
User-Agent: curl/8.10.1
Accept: */*
:authority: httpbin.org
:method: GET
:path: /get
:scheme: https

------------------ REQUEST BODY ------------------
(empty)

------------------ RESPONSE ------------------
503 Service Unavailable
:status: 503
Server: awselb/2.0
Date: Tue, 28 Oct 2025 16:32:35 GMT
Content-Type: text/html
Content-Length: 162

------------------ RESPONSE BODY ------------------
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
</body>
</html>
```

### JSON Format

#### Summary Mode

Minimal structured JSON access log.

**Configuration:**

```yaml
plugins:
  - type: access_logs
    config:
      mode: summary
      format: json      # Machine-readable logs
```

**Example Output:**

```json
{"msg":"HTTP transaction","bin":"/usr/bin/curl","direction":"egress-external","method":"GET","url":"https://httpbin.org/get","status":200,"request_id":"d40f0mo7p3qrr3bnbhcg"}
```

#### Details Mode

Includes metadata and headers in JSON structure.

**Configuration:**

```yaml
plugins:
  - type: access_logs
    config:
      mode: details     # Adds headers to JSON
      format: json
```

**Example Output:**

```json
{"msg":"HTTP transaction","meta":{"bytes_received":"395","bytes_sent":"41","exe":"/usr/bin/curl","pid":1147175},"direction":"egress-external","request":{"headers":{":authority":"httpbin.org",":method":"GET",":path":"/get",":scheme":"https","Accept":"*/*","User-Agent":"curl/8.10.1"},"method":"GET","proto":"http2","request_id":"d40f13g7p3qk61jv5dg0","url":"https://httpbin.org/get"},"response":{"headers":{":status":"200","Access-Control-Allow-Credentials":"true","Access-Control-Allow-Origin":"*","Content-Length":"255","Content-Type":"application/json","Date":"Tue, 28 Oct 2025 16:35:04 GMT","Server":"gunicorn/19.9.0"},"status":200}}
```

#### Full Mode

Complete JSON access log with request/response bodies.

**Configuration:**

```yaml
plugins:
  - type: access_logs
    config:
      mode: full        # Complete JSON entry
      format: json
```

**Example Output:**

```json
{"msg":"HTTP transaction","meta":{"bytes_received":"395","bytes_sent":"41","exe":"/usr/bin/curl","pid":1148159},"direction":"egress-external","request":{"body":"","headers":{":authority":"httpbin.org",":method":"GET",":path":"/get",":scheme":"https","Accept":"*/*","User-Agent":"curl/8.10.1"},"method":"GET","proto":"http2","request_id":"d40f1qo7p3qkfi948ivg","url":"https://httpbin.org/get"},"response":{"body":"{\n  \"args\": {}, \n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Host\": \"httpbin.org\", \n    \"User-Agent\": \"curl/8.10.1\", \n    \"X-Amzn-Trace-Id\": \"Root=1-6900f0eb-0f9ef3c911f3581220130d55\"\n  }, \n  \"origin\": \"73.71.138.108\", \n  \"url\": \"https://httpbin.org/get\"\n}\n","headers":{":status":"200","Access-Control-Allow-Credentials":"true","Access-Control-Allow-Origin":"*","Content-Length":"255","Content-Type":"application/json","Date":"Tue, 28 Oct 2025 16:36:06 GMT","Server":"gunicorn/19.9.0"},"status":200}}
```

**Note**: Bodies are plain text in JSON string fields (not base64-encoded like http\_capture).

***

## Comparison: http\_capture vs access\_logs

| Feature                  | http\_capture                     | access\_logs                |
| ------------------------ | --------------------------------- | --------------------------- |
| **Purpose**              | Detailed HTTP transaction capture | Log-style access recording  |
| **Formats**              | text, json                        | console, json               |
| **Levels/Modes**         | summary, details, full            | summary, details, full      |
| **Body encoding (JSON)** | base64-encoded                    | Plain text in JSON strings  |
| **Use case**             | Deep inspection, debugging        | Monitoring, log aggregation |
| **Readability**          | More structured                   | More compact                |

### When to use http\_capture

* Need complete transaction details for debugging
* Require structured data for analysis
* Want base64-encoded bodies for binary safety

### When to use access\_logs

* Need familiar web server log format
* Want quick visibility into traffic patterns
* Prefer compact single-line summaries (summary mode)
* Integrating with log aggregation tools

***

## Configuration Examples

### Capture Only Errors (Full Detail)

Use http\_capture with rulekit to capture only failed requests:

```yaml
version: 2

services:
  event_stores:
    - type: stdout
  object_stores:
    - type: stdout

rulekit:
  macros:
    - name: is_error
      expr: http.res.status >= 400 && http.res.status < 600

stacks:
  error_capture:
    plugins:
      - type: http_capture
        config:
          level: none           # Don't capture by default
          format: json
          rules:
            - name: "Capture errors"
              expr: is_error()
              level: full       # But capture errors fully

tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: false
  http:
    stack: error_capture
```

### Dual Output: Summary Access Logs + Full Error Capture

Combine access\_logs for general visibility with http\_capture for detailed error capture:

```yaml
version: 2

services:
  event_stores:
    - type: stdout
  object_stores:
    - type: stdout

rulekit:
  macros:
    - name: is_error
      expr: http.res.status >= 400

stacks:
  dual_output:
    plugins:
      - type: access_logs        # First: Log everything as summary
        config:
          mode: summary
          format: console
      - type: http_capture       # Second: Capture errors fully
        config:
          level: none
          format: json
          rules:
            - name: "Error detail"
              expr: is_error()
              level: full

tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: false
  http:
    stack: dual_output
```

***

## Notes

* All examples captured from real qtap v0 runs
* Timestamps reflect UTC timezone
* Process IDs (PID) are unique to the execution environment
* Some examples show 503 errors due to httpbin.org service issues during testing
* Base64 decoding required for http\_capture JSON bodies
* access\_logs JSON bodies are plain text strings


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.qpoint.io/appendix/qtap-output-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
