Integrating Qtap with Your Observability Stack
You already have an observability stack — Grafana + Loki, Datadog, Elastic, or similar. This guide shows how Qtap slots into what you already run, without provisioning new infrastructure. Qtap speaks OTLP for both events and artifacts. You can also use S3 for artifact storage if you prefer. If your stack can receive OTLP, you're set.
How Qtap Fits In
┌──────────────────────────────────────────────────────────────────┐
│ YOUR INFRASTRUCTURE │
│ │
│ ┌───────┐ │
│ │ Qtap │──── Events (OTLP) ──────► OTel Collector │
│ │ Agent │ │ │
│ │ │ ▼ │
│ │ │ Your Log Backend │
│ │ │ (Loki, Datadog, Elastic, …) │
│ │ │ │
│ │ │── Objects ──► OTel (same collector) │
│ │ │ OR ► S3 Storage (MinIO, AWS S3, GCS, …) │
│ └───────┘ │
└──────────────────────────────────────────────────────────────────┘Qtap produces two data streams: events and objects. Both can flow through your OTel pipeline, or you can send objects to S3 storage separately. When using S3, the access_url in each artifact_record event links back to the stored object.
Two Data Streams
What
Lightweight metadata — method, URL, status, duration, process
HTTP transaction content — metadata at summary level; headers and bodies at full level
Sensitivity
Low — safe to send to any backend
Varies — summary objects contain only metadata; full objects may contain API keys, tokens, PII
Protocol
OTLP (gRPC or HTTP)
OTLP (gRPC or HTTP) or S3 API
Destination
Any OTLP-compatible backend via OTel Collector
Same OTel Collector or any S3-compatible storage
Volume
Every observed request
Every captured request (content varies by capture level)
Choose your object storage approach:
OTel objects — Simplest. Events and artifacts flow through the same collector. No S3 credentials needed. Best for ClickStack, self-contained setups, or when you don't need separate object storage.
S3 objects — Events go to OTel, artifacts go to S3. Each
artifact_recordevent contains a clickableurllinking to the stored object. Best when you need durable, queryable object storage or have existing S3 infrastructure.
Configuring Qtap
Option 1: Everything through OTel (simplest)
Both events and artifacts go to the same OTel endpoint. No S3 credentials, no bucket setup.
Option 2: OTel events + S3 objects
One complete qtap.yaml that connects to your existing OTel Collector and S3 storage:
Replace these values with yours:
endpoint (event_stores)
Your OTel Collector address (e.g., otel-collector:4317)
endpoint (object_stores)
Your S3 storage address (e.g., s3.amazonaws.com)
bucket
Your S3 bucket name
region
Your S3 region
access_url
URL template that your dashboard users can reach (see Connecting to Your S3 Storage)
S3_ACCESS_KEY / S3_SECRET_KEY
Environment variable names holding your S3 credentials
Connecting to Your OTel Collector
If you already have an OTel Collector running, point Qtap's event_stores endpoint at it — no other changes needed. Qtap sends OTLP logs on the standard gRPC port (4317).
If your collector doesn't yet forward to a log backend, add the relevant exporter. For example, to forward to Loki:
This works with any OTLP-compatible backend — replace the exporter with whatever your stack uses (Datadog, Elastic, Honeycomb, etc.). See Backend-Specific Configurations for detailed examples.
Connecting to Your S3 Storage
Qtap's S3 object store works with any S3-compatible storage. Set the endpoint to match your provider:
Provider
Endpoint Example
access_url Example
MinIO
minio.internal:9000
https://minio.internal/{{BUCKET}}/{{DIGEST}}
AWS S3
s3.amazonaws.com
https://s3.amazonaws.com/{{BUCKET}}/{{DIGEST}}
Google Cloud Storage
storage.googleapis.com
https://storage.cloud.google.com/{{BUCKET}}/{{DIGEST}}
Garage
garage.internal:3900
http://garage.internal:3902/{{BUCKET}}/{{DIGEST}}
The access_url Template
The access_url determines the clickable link embedded in every artifact_record event. It supports three template variables:
{{DIGEST}}— SHA1 hash of the stored object (always required){{BUCKET}}— The bucket name from your config{{ENDPOINT}}— The S3 endpoint from your config
The URL must be reachable by whoever is reading your logs. For internal dashboards, use an internal hostname. For shared access, consider:
Presigned URLs — Generate time-limited signed URLs for private buckets
Public bucket — Allow anonymous reads (development only)
Reverse proxy — Place nginx or similar in front of your S3 for access control
What You'll See
Qtap stores an HTTP transaction object in S3 and emits an artifact_record event for every captured request. At summary level, the object contains only metadata. At headers or full level, it includes the complete request/response headers and bodies.
The artifact_record Event
Search your log backend for event_type="artifact_record" to find stored objects:
The Stored Object
Click the url to fetch the full HTTP transaction from your S3 storage:
This works in any log UI — search for artifact_record events, click the URL, and you have the full request and response.
Common Configurations
These snippets show just the services: block — the rest of the config (rulekit, stacks, tap) stays the same as the full example above.
ClickStack (all OTel)
See Self-Hosted ClickStack Observability for the full walkthrough.
Loki + MinIO
Datadog + AWS S3
Elastic + Google Cloud Storage
Verification Checklist
Check OTel Collector — Look for received log entries in your collector's output
Query your log backend — Search for
service_name="qtap"eventsList S3 objects — Verify objects appear in your bucket after generating traffic
Test object linking — Find an
artifact_recordevent and open the URL to confirm the full HTTP transaction is accessible
Next Steps
Self-Hosted ClickStack Observability — Simplest self-hosted setup (everything through OTel)
Self-Hosted Grafana Observability Stack — Build the full Grafana stack from scratch
Storage Configuration — OTel and S3 object storage options, credential management
Traffic Processing with Plugins — Rulekit rules, capture levels, conditional logic
Qpoint Data Schema Reference — Full event schema documentation
Last updated