feat(cache-proxy): emit standalone OTLP traces#790
Merged
Conversation
Add OpenTelemetry tracing to the cache-proxy so its S3 fetches show up in Tempo. Spans are emitted as standalone root traces under service.name=duckgres-cache-proxy: - cache.get (cacheable GET) with cache.origin_fetch / cache.peer_fetch children - cache.connect (CONNECT tunnels) - cache.forward (non-cached methods) DuckDB httpfs sends no traceparent, so these are deliberately NOT stitched into the duckgres query trace — true single-trace stitching would need either per-request header injection through the C++ httpfs path (session-global only, not per-query) or an out-of-band worker->proxy side-channel keyed by source IP. Instead spans carry the cross-reference anchors for manual correlation: client.address (worker pod IP), the S3 object (server.address + url.path + range), timestamp, and cache.source (hit/peer/miss). Tracing init is replicated locally rather than imported from internal/cliboot, which transitively pulls in the DuckDB CGO runtime (via posthog/duckgres/server) that this standalone binary must not link. Same env vars as the main binary (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / DUCKGRES_TRACE_ENDPOINT / _PATH); no-op when unset. The cache proxy is not deployed in tests/e2e-mw-dev (DUCKGRES_CACHE_ENABLED is off there), so behavior is gated by cmd/cache-proxy/tracing_test.go rather than an e2e harness assertion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds OpenTelemetry tracing to the
cache-proxyso its S3 fetches are visible in Tempo.When a trace endpoint is configured, the proxy exports spans under
service.name=duckgres-cache-proxy:cache.get(cacheable GET) withcache.origin_fetch/cache.peer_fetchchildrencache.connect(CONNECT tunnels)cache.forward(non-cached methods)Why these are standalone traces (not stitched into the query trace)
DuckDB
httpfs(C++) builds the S3 requests and sends notraceparent, so the proxy has nothing to extract. True single-trace stitching would require one of:traceparentheader injection through the httpfs path — only achievable at session granularity (via the secret), not per-query, so all queries in a session would collapse into one trace; orNeither is in scope here. Instead each span carries the cross-reference anchors for manual correlation against a query trace:
client.address— worker pod IP (→ org/session via Kubernetes)server.address+url.path+duckgres.s3.rangeduckgres.cache.source(hit/peer/miss),duckgres.cache.hit,duckgres.bytes,http.response.status_codeorg_idis intentionally absent — the proxy has no per-request tenant identity.Notes
cmd/cache-proxy/tracing.go) rather than imported frominternal/cliboot, which transitively pulls in the DuckDB CGO runtime (viaposthog/duckgres/server) that this standalone binary must not link. Same env vars as the main binary (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT/DUCKGRES_TRACE_ENDPOINT/OTEL_EXPORTER_OTLP_TRACES_PATH); no-op when unset.Testing
cmd/cache-proxy/tracing_test.go— in-memory span recorder asserts miss→hit, child-span nesting undercache.get, andcache.forwardstatus.tests/e2e-mw-dev(DUCKGRES_CACHE_ENABLEDis off there), so this behavior is gated by the unit test rather than an e2e harness assertion — documented in the README.🤖 Generated with Claude Code