Traffic Processing with Plugins
Understanding Stacks and Plugins
In Qtap's configuration, traffic processing is organized using two key concepts:
- Stacks: Named collections of plugins that work together to process traffic 
- Plugins: Individual components that perform specific functions on captured traffic 
This structure allows you to create different processing configurations for different types of traffic.
New to plugins? Follow the Complete Guide for hands-on examples progressing through all 4 levels of plugin configuration (from basic to production-ready).
Which Plugin Should I Use?
Choose the right plugin based on your use case:
Production monitoring with storage
http_capture with S3
Flexible capture levels, rule-based filtering, stores payloads in S3
Development debugging
access_logs
Human-readable console output, Apache-style formatting
Error-only capture
http_capture with rules
Set level: none by default, capture full only when errors occur
High-volume traffic
http_capture with level: summary
Minimal overhead, no headers/bodies captured
Compliance/audit
http_capture with level: full
Complete request/response capture for audit trails
Quick visibility test
access_logs
Fastest way to see if Qtap is working
Structured logging
http_capture with format: json
Easy integration with log aggregators (Fluent Bit, etc.)
Usage tracking (Qplane)
report_usage
Automatically reports metrics to Qplane dashboard
Quick Decision Tree
Do you need to store HTTP payloads long-term?
├─ YES → Use http_capture with S3 object store
└─ NO  → Continue...
Are you debugging in development?
├─ YES → Use access_logs (human-readable console output)
└─ NO  → Continue...
Do you need selective capture (errors only, specific domains)?
├─ YES → Use http_capture with rulekit rules
└─ NO  → Continue...
Do you just want to see if Qtap works?
├─ YES → Use access_logs (simplest output)
└─ NO  → Use http_capture (most flexible)Plugin Comparison
Feature
http_capture
access_logs
report_usage
Capture levels
4 levels (none/summary/details/full)
2 modes (default/details)
N/A (metrics only)
Rule-based filtering
✅ Full rulekit support
❌ No
❌ No
Output formats
text, json
console only
N/A
S3 storage
✅ Yes
❌ No
❌ No
Best for
Production, flexibility
Development, quick tests
Qplane dashboards
Performance
Low overhead
Lower overhead
Minimal overhead
Stack Configuration
Stacks are defined in the stacks section of your qpoint.yaml file. Each stack has a unique name and contains one or more plugins:
stacks:
  default_stack:   # Stack name
    plugins:       # List of plugins in this stack
      - type: http_capture
        config:
          # Plugin-specific configurationYou can create multiple stacks for different purposes, each with its own set of plugins and configurations.
Available Plugins
Qtap includes several plugins that provide different processing capabilities. Rules use Rulekit - Qpoint's flexible expression-based rules engine for evaluating conditions against HTTP traffic.
HTTP Capture Plugin
The http_capture plugin provides comprehensive HTTP traffic capture with flexible logging levels and the ability to upload payloads to object storage.
Basic Configuration
- type: http_capture
  config:
    level: summary        # Default capture level (none|summary|details|full)
    format: text          # Output format (text|json)Level Options
- none: No capture (effectively disables the plugin)
- summary: Basic information (method, path, status code)
- details: Includes headers
- full: Complete information including request/response bodies
Example with Rules
- type: http_capture
  config:
    level: summary        # Default level for most traffic
    format: text          # Human-readable format
    rules:
      - name: "Full capture for httpbin.org"
        expr: http.req.host == "httpbin.org"
        level: full
      - name: "Headers logging for server errors"
        expr: http.res.status >= 500
        level: details
      - name: "Full capture for client errors"
        expr: http.res.status >= 400 && http.res.status < 500
        level: fullThis configuration:
- Uses summary level by default 
- Captures full details for all traffic to - httpbin.org
- Captures detailed information for server errors (5xx) 
- Captures full information for client errors (4xx) 
Container and Pod-based Filtering
You can also create rules based on container or Kubernetes pod attributes:
- type: http_capture
  config:
    level: summary
    format: text
    rules:
      - name: "Debug specific container"
        expr: src.container.name == "my-app-container"
        level: full
      
      - name: "Debug by container label"
        expr: src.container.labels.qpoint_debug_level == "debug"
        level: full
      
      - name: "Debug specific pod"
        expr: src.pod.name == "frontend-deployment-abc123"
        level: full
      
      - name: "Debug by pod label"
        expr: src.pod.labels.app == "frontend" && src.pod.labels.debug == "true"
        level: fullThe http_capture plugin uploads captured payloads to the configured object store when capture levels include body content. When using full level, both headers and bodies are captured and stored. When using details level, only headers are captured (no body storage).
Access Logs Plugin
The access_logs plugin provides formatted logging of HTTP traffic to stdout. It does not upload to the object store.
Basic Configuration
- type: access_logs
  config:
    mode: details        # Default logging level (summary|details|full)
    format: console      # Output format (console|json)Mode Options
- summary: Basic information (method, path, status code)
- details: Includes headers and timing information
- full: Complete information including request/response bodies
Example with Rules
- type: access_logs
  config:
    mode: summary        # Default mode for most traffic
    format: console      # Human-readable format
    rules:
      - name: "Detailed API Logging"
        expr: http.req.host == "api.example.com"
        mode: details
      - name: "Full Error Logging"
        expr: http.res.status >= 400
        mode: fullReport Usage Plugin
The report_usage plugin sends anonymized usage metrics to Pulse. This is mainly useful when using Qplane. It works alongside other plugins and doesn't affect traffic capture.
- type: report_usageThis plugin is optional and can be included in any stack.
Error Detection Plugin (Deprecated)
DEPRECATED: The detect_errors plugin is deprecated and will be removed in a future version.
Migration: Use http_capture plugin with rulekit rules instead - it provides more flexibility and better performance.
Why deprecated: The http_capture plugin's rule-based filtering supersedes this plugin's functionality with a more powerful and flexible approach.
The detect_errors plugin captures detailed information when responses meet specific error criteria and optionally uploads the specified headers and/or bodies to the object store.
Example of OLD (deprecated) approach:
- type: detect_errors
  config:
    rules:
      - name: "Server Errors"
        trigger_status_codes:
          - '5xx'              # Status code pattern
        report_as_issue: true  # Flag as issue
        record_req_headers: true
        record_req_body: true
        record_res_headers: true
        record_res_body: trueNEW approach using http_capture with rules:
- type: http_capture
  config:
    level: none          # Don't capture by default
    format: json
    rules:
      - name: "Capture server errors"
        expr: http.res.status >= 500 && http.res.status < 600
        level: full      # Capture headers + bodies for errorsMigration benefits:
- More flexible filtering (combine status codes with headers, paths, etc.) 
- Better performance (single plugin instead of multiple) 
- Access to full rulekit expression syntax 
- Consistent configuration across all capture scenarios 
Debug Plugin (Deprecated)
DEPRECATED: The debug plugin is deprecated and will be removed in a future version.
Migration: Use access_logs plugin for console output, or http_capture for more flexible capture.
Why deprecated: The access_logs plugin provides better formatting and more features, making this plugin redundant.
The debug plugin provides basic logging of HTTP traffic.
Example of OLD (deprecated) approach:
- type: debug
  config:
    mode: summary  # or "details" for more informationNEW approach using access_logs:
- type: access_logs
  config:
    mode: details       # summary, details, or full
    format: console     # Human-readable console outputMigration benefits:
- Better formatted output (Apache-style logs) 
- Support for both console and JSON formats 
- Rule-based selective logging 
- Consistent with other plugins 
Rule Expressions with Rulekit
Both the http_capture and access_logs plugins use Rulekit for rule evaluation. Rulekit is Qpoint's expression-based rules engine that evaluates conditions against key-value data from HTTP traffic.
Expression Syntax
Rule expressions follow a straightforward pattern:
<field> <operator> <value>Multiple conditions can be combined using logical operators:
<field1> <operator1> <value1> and <field2> <operator2> <value2>Available Fields for Rule Expressions
Request Fields
http.req.method
http.req.method == "POST"
HTTP method (GET, POST, etc.)
http.req.path
http.req.path contains "/api/"
Request path
http.req.host
http.req.host == "api.example.com"
Host header value
http.req.url
http.req.url contains "search"
Full URL
http.req.headers.<name>
http.req.headers.content-type == "application/json"
Request header by name
Response Fields
http.res.status
http.res.status >= 400
HTTP status code
http.res.headers.<name>
http.res.headers.content-type contains "json"
Response header by name
Source Context Fields
src.container.name
src.container.name == "my-app"
Container name
src.container.labels.<key>
src.container.labels.app == "frontend"
Container label value
src.pod.name
src.pod.name == "frontend-abc123"
Kubernetes pod name
src.pod.labels.<key>
src.pod.labels.version == "v2"
Pod label value
Operators for Rule Expressions
Rulekit supports various operators for building expressions:
Comparison Operators
==
eq
Equal to
http.req.method == "GET"
!=
ne
Not equal to
http.req.host != "internal.example.com"
>
gt
Greater than
http.res.status > 200
>=
ge
Greater than or equal to
http.res.status >= 400
<
lt
Less than
http.res.status < 300
<=
le
Less than or equal to
http.res.status <= 399
=~
matches
Matches regex pattern
http.req.path matches /^\/api\/v\d+\//
contains
Contains substring
http.req.url contains "search"
in
Is contained in array
http.req.method in ["GET", "HEAD"]
Logical Operators
and
&&
Logical AND
http.req.method == "POST" and http.res.status >= 400
or
||
Logical OR
http.req.path contains "/admin" or http.req.path contains "/auth"
not
!
Logical NOT
not http.req.host == "public.example.com"
Value Types
Rulekit expressions support various value types:
- Boolean: - true,- false
- Number: Integer or floating-point values (e.g., - 200,- 1.5)
- String: Text enclosed in double quotes (e.g., - "example.com")
- Regex Pattern: Patterns enclosed in slashes - /pattern/or vertical bars- |pattern|
- Array: Values in square brackets (e.g., - [200, 201, 204])
Using Rulekit Macros
You can define reusable expression macros in the rulekit section of your configuration:
rulekit:
  macros:
    - name: is_error
      expr: http.res.status >= 400 && http.res.status < 600
    - name: is_api_request
      expr: http.req.path matches /^\/api\//
    - name: is_production
      expr: src.pod.labels.env == "production" || src.container.labels.env == "production"
stacks:
  default_stack:
    plugins:
      - type: http_capture
        config:
          level: summary
          format: text
          rules:
            - name: "Capture production API errors"
              expr: is_production() && is_api_request() && is_error()
              level: full
            - name: "Debug all errors"
              expr: is_error()
              level: detailsKnown Limitation: The not operator does not currently work in rule expressions or macros. Use explicit negation with != and && operators instead.
For example, instead of:
- name: is_not_production
  expr: not (src.pod.labels.env == "production")Use:
- name: is_not_production
  expr: src.pod.labels.env != "production"Complete Configuration Example
Here's a comprehensive example that demonstrates various plugin features:
version: 2
# Define reusable macros
rulekit:
  macros:
    - name: is_4xx
      expr: http.res.status >= 400 && http.res.status < 500
    - name: is_5xx
      expr: http.res.status >= 500 && http.res.status < 600
    - name: is_debug_enabled
      expr: src.container.labels.debug == "true" || src.pod.labels.debug == "true"
services:
  event_stores:
    - id: console_stdout
      type: stdout
  object_stores:
    - id: minio
      type: s3
      endpoint: minio.internal:9000
      bucket: qpoint-objects
      region: us-east-1
      access_url: https://minio.internal:9000/{{BUCKET}}/{{DIGEST}}
      insecure: false
      access_key:
        type: env
        value: S3_ACCESS_KEY
      secret_key:
        type: env
        value: S3_SECRET_KEY
stacks:
  production_stack:
    plugins:
      - type: http_capture
        config:
          level: summary
          format: text
          rules:
            # Debug containers with debug label
            - name: "Debug mode capture"
              expr: is_debug_enabled()
              level: full
            
            # Capture errors from specific service
            - name: "Payment service errors"
              expr: http.req.host == "payment.api.com" && (is_4xx() || is_5xx())
              level: full
            # Monitor external API calls
            - name: "External API monitoring"
              expr: http.req.host matches /\.(googleapis\.com|amazonaws\.com)$/ && http.req.method == "POST"
              level: details
tap:
  direction: egress
  ignore_loopback: true
  audit_include_dns: true
  http:
    stack: production_stackAdditional Resources
- Rulekit Documentation: For detailed information about rule expressions, operators, and advanced features, visit the Rulekit GitHub repository 
- Rulekit Examples: The repository includes an interactive CLI demo tool for testing rule expressions 
Last updated