5-Minute Quickstart

Get Qtap running in 5 minutes with console output - perfect for a fast preview of Qtap's capabilities.

Who This Is For

Use this guide if you want to:

  • Preview Qtap's traffic capture quickly without complex setup

  • See immediate console output (no storage configuration needed)

  • Understand basic Qtap concepts before diving deeper

  • Test if Qtap works on your system

This is NOT for:

Time to complete: 5 minutes

What you'll get: Real-time visibility into HTTP/HTTPS traffic with console output


This is a simple configuration to get started with Qtap without any external dependencies. Everything outputs to your console for immediate visibility.

Quick Start Configuration

Save this as qtap-starter.yaml:

version: 2

# Storage Configuration - Everything to console
services:
  # Event metadata goes to stdout
  event_stores:
    - type: stdout
  
  # Object data (headers) goes to stdout
  object_stores:
    - type: stdout

# Processing Stack - Simple HTTP capture
stacks:
  starter_stack:
    plugins:
      # HTTP Capture plugin - outputs to console
      - type: http_capture
        config:
          level: details  # Capture headers (use 'full' for bodies too)
          format: text    # Human-readable format (use 'json' for structured)

# Traffic Capture Settings
tap:
  direction: egress  # Capture outgoing traffic
  ignore_loopback: true  # Skip localhost traffic
  audit_include_dns: false  # Skip DNS queries for cleaner output
  http:
    stack: starter_stack

Running the Starter Config

Quick Test

# Install/Update QTap
curl -s https://get.qpoint.io/install | sudo sh

# Run with the config (runs in foreground by default)
sudo qtap --config=qtap-starter.yaml

Testing Your Configuration

Once QTap is running, test it with some HTTP requests on the same host:

# In another terminal, make test requests:

# Test 1: Simple GET request
curl https://httpbin.org/get

# Test 2: POST with headers
curl -X POST https://httpbin.org/post \
  -H "X-Test-Header: test-value" \
  -d "test=data"

You should see output in your QTap terminal showing the captured traffic.

Configuration Variations

Variation 1: Capture Everything (Including Bodies)

version: 2

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

stacks:
  debug_stack:
    plugins:
      - type: http_capture
        config:
          level: full     # Capture everything including bodies
          format: json    # Structured output for parsing

tap:
  direction: all          # Capture both ingress and egress
  ignore_loopback: false  # Include localhost traffic
  audit_include_dns: true # Include DNS queries
  http:
    stack: debug_stack

Variation 2: With Filtering Rules

version: 2

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

stacks:
  filtered_stack:
    plugins:
      - type: http_capture
        config:
          level: summary  # Default: just basic info
          format: text
          rules:
            # Capture headers for specific domains
            - name: "API calls"
              expr: http.req.host contains "api"
              level: details
            
            # Capture everything for errors
            - name: "Error debugging"
              expr: http.res.status >= 400
              level: full
            
            # Skip health checks entirely
            - name: "Ignore health"
              expr: http.req.path in ["/health", "/ping"]
              level: none

tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: false
  http:
    stack: filtered_stack

Variation 3: Using access_logs Plugin

version: 2

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

stacks:
  logging_stack:
    plugins:
      # Access logs plugin - old
      - type: access_logs
        config:
          mode: details      # Options: summary, details, full
          format: console    # Human-readable format
 
tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: false
  http:
    stack: logging_stack

Understanding the Output

With http_capture plugin (text format):

[HTTP] GET https://httpbin.org/get
Headers:
  User-Agent: curl/7.81.0
  Accept: */*
Status: 200 OK
Duration: 145ms

With http_capture plugin (json format):

{
  "timestamp": "2024-10-15T10:23:45Z",
  "http": {
    "method": "GET",
    "host": "httpbin.org",
    "path": "/get",
    "status": 200,
    "headers": {
      "user-agent": "curl/7.81.0"
    }
  },
  "direction": "egress"
}

With access_logs plugin:

2024-10-15T10:23:45Z [EGRESS] GET httpbin.org/get 200 145ms

Troubleshooting

Quick Checklist: Not Working?

Use this checklist to diagnose common issues:

No Output Appearing

Symptom: Qtap is running but no traffic is captured

Solutions:

  1. Check for errors in debug mode:

    sudo qtap --config=qtap-starter.yaml --log-level=debug

    Look for messages like "attached to process" or "http capture"

  2. Verify traffic is being generated:

    # Make sure this runs AFTER qtap is started
    curl -v https://httpbin.org/get
  3. Check process attribution:

    # See if qtap detected the curl process
    ps aux | grep curl
  4. Verify eBPF hooks:

    # Check if eBPF programs are loaded
    sudo bpftool prog list | grep qtap

Common causes:

  • Qtap started AFTER traffic was generated (restart qtap, then generate traffic)

  • Process doesn't use standard TLS libraries (OpenSSL, BoringSSL, GnuTLS)

  • Traffic is going through a proxy that qtap isn't monitoring

Too Much Output

Symptom: Overwhelming amount of captured traffic

Solution: Add filters to ignore noisy processes:

tap:
  filters:
    groups:
      - kubernetes  # Ignore k8s system traffic
      - qpoint     # Ignore QTap itself
    custom:
      - exe: /usr/bin/prometheus
        strategy: exact
      - exe: /opt/datadog-agent
        strategy: prefix

Common noisy processes:

  • Monitoring agents (Prometheus, Datadog, New Relic)

  • Log shippers (Fluent Bit, Logstash)

  • Kubernetes system components

  • Container runtime health checks

Wrong Traffic Direction

Symptom: Expected traffic not appearing

Solution: Choose the correct direction:

  • egress: Outgoing traffic from your system (e.g., curl making requests)

  • ingress: Incoming traffic to your services (e.g., web server receiving requests)

  • all: Both directions

Examples:

  • Testing with curl → use egress

  • Monitoring NGINX web server → use ingress

  • Capturing both client and server traffic → use all

Protocol Shows as "other" Instead of "http"

Symptom: Traffic captured but not parsed as HTTP

Possible causes:

  1. HTTP/3 (QUIC): Not yet supported - shows as "other"

  2. Non-standard TLS library: Qtap supports OpenSSL, BoringSSL, GnuTLS

  3. Binary protocol: Not HTTP traffic (database protocols, gRPC, etc.)

How to verify:

# Check qtap debug logs for TLS detection
sudo qtap --config=qtap-starter.yaml --log-level=debug 2>&1 | grep -i "tls"

Still Having Issues?

What's Next?

Now that you've confirmed Qtap is capturing traffic, choose your next step based on your goals:

For Production Deployment

Follow the progressive tutorial with real-world examples:

For Specific Use Cases

For Configuration Details

Quick Improvements to This Setup

  1. Add error-only capture - Reduce volume by only capturing errors:

    # Add to your config
    rulekit:
      macros:
        - name: is_error
          expr: http.res.status >= 400
    
    stacks:
      starter_stack:
        plugins:
          - type: http_capture
            config:
              level: none  # Don't capture by default
              format: text
              rules:
                - name: "Capture errors only"
                  expr: is_error()
                  level: full
  2. Add process filtering - Ignore noisy processes:

    # Add to tap section
    tap:
      filters:
        custom:
          - exe: /usr/bin/prometheus
            strategy: exact
  3. Switch to JSON - For easier parsing and integration:

    # Change format in http_capture plugin
    format: json  # instead of text

Minimal Test Config

The absolute minimum config to see if QTap works:

version: 2
services:
  event_stores:
    - type: stdout
  object_stores:
    - type: stdout
stacks:
  test:
    plugins:
      - type: access_logs
        config:
          mode: details
          format: console
tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: false
  http:
    stack: test

Save as test.yaml and run:

sudo qtap --config=test.yaml

Then in another terminal on same host:

curl https://example.com

You should immediately see the captured request in your QTap terminal.

Last updated