> For the complete documentation index, see [llms.txt](https://docs.qpoint.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.qpoint.io/guides/qtap-guides/getting-started/qtap-starter-configuration-stdout-only.md).

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