# 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:**

* Production deployments (use [Complete Guide](/guides/qtap-guides/getting-started/getting-started-complete-guide.md) instead)
* Long-term traffic storage (add [S3 configuration](/guides/qtap-guides/getting-started/getting-started-complete-guide.md#level-4-add-s3-storage-for-production) later)
* Multi-environment management (consider [Qplane](/guides/qplane-guides/poc-kick-off-guide.md))

**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`:

```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: headers  # 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

```bash
# 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:

```bash
# 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)

```yaml
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

```yaml
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: headers
            
            # 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

```yaml
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):

```json
{
  "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:

* [ ] **Qtap is running**: `sudo systemctl status qtap` or `docker ps | grep qtap`
* [ ] **Correct config file**: Verify YAML syntax with `yamllint qtap-starter.yaml`
* [ ] **Sufficient permissions**: Running as root/sudo with necessary capabilities
* [ ] **eBPF support**: Kernel 5.10+ with `uname -r`, eBPF enabled
* [ ] **Traffic being generated**: Make HTTP requests with `curl https://example.com`
* [ ] **Correct direction**: Use `egress` for outbound (curl), `ingress` for inbound (web server)
* [ ] **Not filtered**: Check if process is in `filters` section
* [ ] **Logs show activity**: Check qtap logs for errors with `--log-level=debug`

#### No Output Appearing

**Symptom:** Qtap is running but no traffic is captured

**Solutions:**

1. **Check for errors in debug mode:**

   ```bash
   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:**

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

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

   ```bash
   # 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:

```yaml
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:**

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

#### Still Having Issues?

* **Check system requirements:** [System Requirements](/getting-started/qtap/system-requirements.md)
* **Run preflight check:** `curl -sSL https://github.com/qpoint-io/preflight/releases/latest/download/preflight.sh | sudo bash`
* **See detailed troubleshooting:** [Troubleshooting Guide](/troubleshooting.md)
* **Review healthy capture patterns:** [What a Healthy Capture Looks Like](/appendix/healthy-capture-patterns.md)

### 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:

* [Complete Guide: Hello World to Production](/guides/qtap-guides/getting-started/getting-started-complete-guide.md) - 50-minute tutorial covering rules, filtering, S3 storage, and production deployment

#### **For Specific Use Cases**

* **Web servers (NGINX, Caddy, etc.):** [NGINX Traffic Capture](/guides/qtap-guides/web-server-integration/capturing-nginx-traffic.md)
* **Ingress traffic:** [Ingress Traffic Capture](/guides/qtap-guides/getting-started/ingress-traffic-capture-with-python.md)
* **Production debugging:** [Production Debugging with HTTPS Visibility](/guides/qtap-guides/debugging/production-debugging-with-https-visibility.md)

#### **For Configuration Details**

* **Add S3 storage:** [Storage Configuration](/getting-started/qtap/configuration/storage-configuration.md#s3-compatible-object-storage)
* **Add filtering rules:** [Traffic Capture Settings](/getting-started/qtap/configuration/traffic-capture-settings.md#filters)
* **Understand plugins:** [Traffic Processing with Plugins](/getting-started/qtap/configuration/traffic-processing-with-plugins.md)
* **See more examples:** [Configuration Examples](/getting-started/qtap/configuration/configuration-examples.md)

#### **Quick Improvements to This Setup**

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

   ```yaml
   # 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:

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

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

### Minimal Test Config

The absolute minimum config to see if QTap works:

```yaml
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:

```bash
sudo qtap --config=test.yaml
```

Then in another terminal on same host:

```bash
curl https://example.com
```

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


---

# 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/guides/qtap-guides/getting-started/qtap-starter-configuration-stdout-only.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.
