You already have an observability stack — Grafana + Loki, Datadog, Elastic, or similar — and S3-compatible object storage. This guide shows how Qtap slots into what you already run, without provisioning new infrastructure. Qtap speaks OTLP for events and S3 for payloads. If your stack can receive either, you're set.
Qtap produces two independent data streams. Events flow through your existing OTel pipeline. Objects go directly to your S3 storage. The access_url in each artifact_record event links the two together — click it to fetch the full HTTP transaction from S3.
Two Data Paths
Events
Objects
What
Lightweight metadata — method, URL, status, duration, process
HTTP transaction objects — 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)
S3 API
Destination
Any OTLP-compatible backend via OTel Collector
Any S3-compatible object storage
Volume
Every observed request
Every captured request (content varies by capture level)
The link between them: When Qtap stores an object in S3, it emits an artifact_record event containing a url field built from your access_url template. The {{DIGEST}} placeholder is replaced with the SHA1 hash of the stored object, creating a direct link from your log UI to the full HTTP transaction.
Configuring Qtap
One complete qtap.yaml that connects to your existing OTel Collector and S3 storage:
Replace these values with yours:
Placeholder
What to set
endpoint (event_stores)
Your OTel Collector address (e.g., otel-collector:4317)
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:
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.
All capture levels generate artifact_record events and store objects in S3. The difference is content: summary objects contain only metadata (method, URL, status), while headers and full objects include the complete request/response headers and bodies.
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.
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" events
List S3 objects — Verify objects appear in your bucket after generating traffic
Test object linking — Find an artifact_record event and open the URL to confirm the full HTTP transaction is accessible