feat(traces): OTel database query span support + SQLCommenter correlation#159
Merged
Conversation
…tion Foundation for database query observability, built entirely off the `db.*` OpenTelemetry semantic-convention spans that instrumented apps already emit — no connection or configuration required. Benefits every DB-instrumented service (Postgres/MySQL/ClickHouse/Redis/…), not just one engine. - Generic database span adapter (packages/ui/.../cloud-platforms/database.ts): detects `db.system.name` (with legacy `db.system` fallback) on any DB-client span and renders a query summary block in the span detail — system, namespace, table, operation, rows returned, batch size, server, error outcome. Reuses the existing span-annotation adapter registry (same pattern as cloudflare.ts), so no component changes are needed. - SQLCommenter traceparent parser (@maple/domain/sqlcommenter): extracts the W3C `traceparent` from a SQLCommenter comment in query text. Pure, dependency- free string parsing (safe in web/cli/scraper bundles). This is the seam that lets server-side query logs nest under the client span that issued them. - Semconv completeness: add `db.system.name`/`db.system` to the trace-view projection allowlist so DB spans detect promptly without waiting for the lazy per-span detail fetch. - Docs: docs/database-query-observability.md. First increment of the database query observability work; a cross-service Queries surface and the ClickHouse system.query_log poller (resource allocation + server-side timing) follow on this branch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
|
Your LLM provider API key was rejected. Rotate the key in your provider dashboard, then update the matching GitHub Actions secret. Update repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
The generic database adapter now detects db.system.name/db.system, so the existing 'non-platform span' case (which used db.system: postgresql) correctly matches. Point that null-case at a truly non-platform span and add coverage for the database adapter: humanized labels, legacy db.system fallback, error.type outcome, and the empty-projected-map regression guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 & why
Foundation for database query observability, built entirely off the
db.*OpenTelemetry semantic-convention spans that instrumented apps already emit — no connection, no configuration. It benefits every DB-instrumented service (Postgres / MySQL / ClickHouse / Redis / …), not just one engine.This came out of a customer request for native ClickHouse query timing + resource allocation. The ask splits cleanly by what telemetry can supply it:
system.query_loghas it → a follow-up poller (see below).So this PR is the broadly-useful OTel-SQL foundation; ClickHouse-specific work layers on top.
Changes
packages/ui/src/lib/cloud-platforms/database.ts. Detectsdb.system.name(with legacydb.systemfallback) on any DB-client span and renders a query summary block in the span detail panel: system,db.namespace, table, operation, rows returned, batch size,server.address:port, anderror.typeas the outcome. Humanizes ~30 knowndb.system.namevalues and tints the icon per engine. Reuses the existing span-annotation adapter registry (same pattern ascloudflare.ts) — registered inindex.ts, no component changes.traceparentparser —@maple/domain/sqlcommenter. Extracts the W3Ctraceparentfrom a SQLCommenter comment embedded in query text (/*traceparent='00-<trace>-<span>-01'*/). Pure, dependency-free string parsing (safe in web/cli/scraper bundles). This is the seam that lets server-side query logs nest under the client span that issued them.db.system.name/db.systemto the trace-view projection allowlist (TREE_SPAN_ATTR_KEYS) so DB spans detect promptly without waiting for the lazy per-span detail fetch.docs/database-query-observability.md.Testing
packages/domain/src/sqlcommenter.test.ts— 6 cases (trailing comment, sampled/unsampled flag, alongside other sqlcommenter keys, URL-encoded/whitespace/uppercase tolerance, absent, malformed/all-zero ids). ✅ passing.bun typecheckclean for@maple/domain,@maple/ui,@maple/query-engine.Reviewer notes
cloud-platformsregistry even though a database isn't a "cloud platform"; the normalizedCloudPlatformInfoshape is generic enough to describe a DB call, and it keeps the span-detail render path unchanged. A serverless span and a DB-client span are disjoint in practice.serviceDbTopQueriesSQLalready supports dropping the service filter, so it's mostly a new web route); (2) the ClickHousesystem.query_logpoller (Model B: poll → OTLP into Maple via theapps/scraperpattern, nesting via the SQLCommenter parser above) for resource allocation.🤖 Generated with Claude Code