Repository navigation
fix(edge-otel): bounded DB span names, parameterised db.query.text, http.route + error.type - #682
Conversation
… add server.address DB CLIENT spans were named after the full statement with filter values interpolated, so the api service emitted 511 distinct span names in a week (full-text search terms, memory keys, user ids). Spans are now named by db.query.summary (SELECT memories / CALL memory_write), db.query.text uses $n placeholders, and server.address names the hosted Supabase host. Root SERVER spans gain http.route (router-matched and single-route functions) and every error()/clientError() call records a bounded error.type. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…he operation rename
The PR's own CI smoke trace showed two things the unit tests could not:
UPDATE ... .select('id,scope,key') rendered the returned columns as the SET
list, and Dash0 names root-span operations by http.route once it is present
(POST /mcp), not by faas.name. Fix the first; document the second and the
check rules that must move to faas_name before deploy.
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
✅ No issues foundThe delta since 1540895 is docs plus one comment, and it closes the last open thread: catch-block guidance now names errorTypeOf. A full deep re-pass found nothing above the bar; three low-confidence notes are listed as advisory. 3 advisory findings below the confidence bar — see Less certain below. Checked: 28 of 29 changed files read · 5 possible issues → 0 confirmed → 0 posted Less certain (3) — advisory, below the confidence bar
Review details
Found Quality — produced 5 → posted inline 0 · cleared 0 · carried forward 0 · deferred 0 · below-bar 3 Run full · 9 lines in delta · tier deep · depth checkout
Nothing to report — measurability (17 paths classified), integrations (not activated), severity, 0 files skipped.
|
…interpolates filter values Addresses the pr-reviewer advisory on #682: the token-lookup guards stay, but their reason is now the rejection arm's error message, not the span name. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…clean room
Evals preflight failed on three heads of this PR with "CONTAMINATED -
plugins-loaded: cc-plugin-agents-md, cc-plugin-plugin-authoring" on a
runner that has no ~/.claude. evals.yml installs @anthropic-ai/claude-code
unpinned; 2.1.287 ships built-in plugins, some on by default (2.1.280, the
latest at the last green preflight, ships none), and the harness's
`enabledPlugins: {}` override sets nothing, so they load.
Set `"<name>@Builtin": false` for each built-in instead. The
environment check is unchanged: any plugin that still loads fails preflight.
Reproduced locally with claude 2.1.287: the old override reports the same
two plugins, and the new one reports clean with the harness's SessionStart
hook still firing.
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
postgrest-js resolves a failed fetch (status 0) with the request URL, filter values included, in result.error.message, and the DB span copied it into error.message on every traced query. Record 'fetch failed' for status 0 and redact URLs from every other recorded message; correct the docs and comments that blamed only the rejection arm. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Error messages are URL-redacted, not value-free: Postgres's own wording can still echo a value. Say exactly that, and list redactUrls in key-files. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…isely Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
… error objects by code Two pr-reviewer findings on #682: handler and root spans still recorded a failed request's raw message (URL and search terms included), and a rethrown PostgREST error object (no name) produced error.type 'undefined'. Span.error and clientError now redact URLs and tolerate a non-string message; catch blocks pass errorTypeOf(e), which falls back to the object's code. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Why
Edge DB spans were named after the full statement with filter values interpolated, so
apiemitted 511 distinct span names in one week. 287 of them carried full-text search terms (built from agents' tool-failure text, which the CLI keeps out of its own telemetry), 133 carried memory keys, and 4 carried user ids. This was recommendation #1 indocs/telemetry-quality-review.md.What changed
db.query.summary(SELECT memories,CALL memory_write).db.query.textis parameterised ($n, LIMIT included) and renders a mutation's.select()asRETURNING.error.messageon every span has request URLs redacted, so a failed request no longer copies its URL and the filter values in it into telemetry. A postgrest-js fetch failure (status: 0) on a DB span recordsfetch failed.server.address(the hosted Supabase host; omitted for BYOD) anddb.response.status_code. Root SERVER spans gethttp.route. Every recorded error gets a boundederror.type(an Error's name, a PostgREST code, or_OTHER), and an unexplained 5xx falls back to the status code.enabledPluginscouldn't switch off (packages/evals, one commit, can be cherry-picked out).How to verify
cd packages/mcp-core && npx vitest runandnode scripts/ci/deno-check-functions.mjs. Telemetry was verified on this PR's CI integration-smoke traces in Dash0: 57 span names per run, stable across runs, and no quoted literal in any statement.Notes for reviewers
With
http.routeset, Dash0 names api operations by route (POST /mcp) instead of by function. Move the twodash0_operation_name="mcp"check rules tofaas_name="mcp"before merging, or the absence rule will fire about 2h after deploy (seedocs/otel.md).llms.txtand the user docs are unchanged because this is internal telemetry.