Skip to content

Feat/query name - #283

Merged
AlexAxthelm merged 8 commits into
mainfrom
feat/query_name
Sep 24, 2026
Merged

AlexAxthelm merged 8 commits into
mainfrom
feat/query_name

Conversation

@AlexAxthelm

@AlexAxthelm AlexAxthelm commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

Add functionality to wrap ORM queries in a query_name context to allow disambiguating queries with similar initial construction (starting with the same CTEs) when parsing telemetry/logs

[STIT-762]


Testing notes: I overrode the > 200ms logging threshold for this PR's API, to ensure that we get results in the logs, but on other environments (PROD, other DEVs) only the "slow" queries will show in logs like this:

image

What & why

STIT-762

Azure logs give us per-request duration, but the two list-handler queries both
open with WITH resource_universe AS … and are indistinguishable by SQL text
alone. This adds an optional query_name label to
stitch.api.observability.query (db_query) events so log analysis can
identify a query by a stable name instead of fragile SQL-string matching.

How

  • New query_name_var contextvar + named_query() context manager in
    observability/context.py, mirroring the existing db_stats_var /
    request_id_var pattern.
  • The query-timing listener (observability/query_timing.py) reads the var and
    adds query_name to the emitted event only when set — unlabeled queries
    omit the field entirely, so existing dashboards/consumers are unaffected.
  • Because the label rides a contextvar, every statement in the scope (including
    ORM secondary queries like selectinload/refresh and shared helpers such as
    coalesce_resources) inherits the name — so only the action-function
    boundaries are wrapped, not the shared helpers.
  • Labels the resource / source / merge-candidate action entrypoints. Where one
    operation runs several distinct statements, a third name level disambiguates
    them.

Naming

  • Ticket-required names are exact: resources.list_ids, resources.count,
    filter_options.<field> (e.g. filter_options.country).
  • Convention is <domain>.<operation> (lower_snake), with an optional third
    level (.load / .load_resources / .check_existing / .coalesce /
    .default_priority / .candidates / .apply / .persist) when a single
    operation runs multiple distinct queries.

Acceptance criteria

  • db_query events include query_name for list / filter-options / detail queries
  • The two list queries are distinguishable as resources.list_ids and resources.count
  • Filter-options queries labeled by field name (filter_options.country, etc.)
  • No behavior change; field is optional and omitted when unset

Testing

  • New unit tests in tests/observability/test_query_timing.py: label appears on
    the event, field omitted when unset, and the scope resets after exit.
  • Full API suite green (274 passed); ruff check + ruff format --check clean
    on all touched files.

Docs

  • deployments/PERFORMANCE.md query-event field table updated to document
    query_name.

AI assistance

Implemented with Claude Code: exploration, the contextvar/context-manager design,
call-site wrapping, tests, and docs. Verified manually by running the API test
suite and linters locally; behavior-change safety (field omitted when unset)
is covered by the new tests.

🤖 Generated with Claude Code

AlexAxthelm and others added 2 commits September 22, 2026 13:56
The two list-handler queries both open with `WITH resource_universe AS …`,
so they were indistinguishable in Azure logs by SQL text alone. Add an
optional `query_name` label to `stitch.api.observability.query` events so
analysis can identify a query by a stable name instead of SQL-string matching.

A `query_name_var` contextvar plus a `named_query()` context manager
(observability/context.py) let a call site label the queries it runs; the
timing listener reads the var and adds `query_name` to the event only when
set, so unlabeled queries omit the field and existing log consumers are
unaffected. Because the label rides a contextvar, every statement in the
scope — including ORM secondary queries and shared helpers — inherits the
name, so only the action-function boundaries are wrapped.

Label the resource/source/merge-candidate action entrypoints; the two list
queries are distinguishable as resources.list_ids and resources.count, and
filter options as filter_options.<field> (e.g. filter_options.country).

No behavior change. Docs (deployments/PERFORMANCE.md) and query-timing tests
updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Several action functions ran multiple distinct statements under one
query_name (e.g. merge_candidates.detail wrapped the candidate load, the
coalesce, and the default-priority read), so those statements were still
indistinguishable by name alone. Give each wrapped statement a third-level
suffix (.load / .load_resources / .check_existing / .coalesce /
.default_priority / .candidates / .apply / .persist) so every labeled query
is uniquely identifiable in logs.

No behavior change; single-use labels (resources.count, resources.detail,
filter_options.<field>, etc.) are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 22, 2026 12:39
@AlexAxthelm
AlexAxthelm marked this pull request as draft September 22, 2026 12:40
@AlexAxthelm AlexAxthelm self-assigned this Sep 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Acceptance-critical action labels lack integration tests, so incorrect names or scope placement could regress unnoticed.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds optional query_name context labels to SQL query telemetry and applies stable names across resource, source, and merge-candidate database actions.

Changes:

  • Added named_query context management and event emission support.
  • Labeled ORM query scopes with operation-specific names.
  • Added documentation and low-level context tests.
File Description
deployments/​PERFORMANCE.md Documents the optional query_name field.
deployments/​api/​tests/​observability/​test_query_timing.py Tests query-label context behavior.
deployments/​api/​src/​stitch/​api/​observability/​context.py Adds query-name context state and manager.
deployments/​api/​src/​stitch/​api/​observability/​query_timing.py Emits labels on query events.
deployments/​api/​src/​stitch/​api/​db/​og_field_source_actions.py Labels source operations.
deployments/​api/​src/​stitch/​api/​db/​og_field_resource_actions.py Labels resource and filter operations.
deployments/​api/​src/​stitch/​api/​db/​merge_candidate_actions.py Labels merge-candidate operations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread deployments/api/tests/observability/test_query_timing.py
@github-actions

Copy link
Copy Markdown

CD summary 604d909

Frontend: https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net

Deployments (4)
service url fqdn
api open pr-0283-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
entity-linkage open pr-0283-el.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net
stitch-llm open pr-0283-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0283 stitch-dev.postgres.database.azure.com 5432 pr_0283
Jobs (2)
job image postgres_db api_url auth_mode
db-migrations ghcr.io/rmi/stitch-api:pr-0283@sha256:473ebe63c085c4c61e91916c721f28efeaeb1d69ce4e2f15811364350f8e3831 pr_0283
seed ghcr.io/rmi/stitch-seed:pr-0283@sha256:298d2fb94ef511cebf43d234251bdc8d1b02f0eec25b5d619659a77e787355da https://pr-0283-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io/api/v1 stitch-client-bearer-token
Images (4)
build_time commit_time git_sha image image_digest
2026-09-22T12:40:16Z 2026-09-22T12:39:54Z bfb0653 ghcr.io/rmi/stitch-api:pr-0283 ghcr.io/rmi/stitch-api:pr-0283@sha256:473ebe63c085c4c61e91916c721f28efeaeb1d69ce4e2f15811364350f8e3831
2026-09-22T12:40:13Z 2026-09-22T12:39:54Z bfb0653 ghcr.io/rmi/stitch-entity-linkage:pr-0283 ghcr.io/rmi/stitch-entity-linkage:pr-0283@sha256:48c8a604afc3692d33306c5ac81e0d8af430e0c9dbe81c5045f6aac50639204a
2026-09-22T12:40:18Z 2026-09-22T12:39:54Z bfb0653 ghcr.io/rmi/stitch-seed:pr-0283 ghcr.io/rmi/stitch-seed:pr-0283@sha256:298d2fb94ef511cebf43d234251bdc8d1b02f0eec25b5d619659a77e787355da
2026-09-22T12:40:18Z 2026-09-22T12:39:54Z bfb0653 ghcr.io/rmi/stitch-stitch-llm:pr-0283 ghcr.io/rmi/stitch-stitch-llm:pr-0283@sha256:aaf3e207663ae0ce6cceb0f7d387175f44c34c88e7e90f1135b4f44cd011c9fa

Copilot review (PR #283): the query-timing unit tests exercised named_query
around raw statements but never the wrapped action functions, so a typo'd
label or misplaced scope could pass while the acceptance criteria regressed.

Add end-to-end tests that register query timing on the integration engine, hit
the list / filter-options / detail endpoints, and assert the exact emitted
labels — including secondary statements (resources.list_hydrate,
resources.resolve_root).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

CD summary aa60a44

Frontend: https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net

Deployments (4)
service url fqdn
api open pr-0283-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
entity-linkage open pr-0283-el.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net
stitch-llm open pr-0283-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0283 stitch-dev.postgres.database.azure.com 5432 pr_0283
Jobs (1)
job image postgres_db
db-migrations ghcr.io/rmi/stitch-api:pr-0283@sha256:9aa79c9b21bbba5be54a6445823798cfd40bf5cd1ff29b5a4ae4daeb29be0afc pr_0283
Images (4)
build_time commit_time git_sha image image_digest
2026-09-22T12:51:29Z 2026-09-22T12:51:14Z 162814c ghcr.io/rmi/stitch-api:pr-0283 ghcr.io/rmi/stitch-api:pr-0283@sha256:9aa79c9b21bbba5be54a6445823798cfd40bf5cd1ff29b5a4ae4daeb29be0afc
2026-09-22T12:51:31Z 2026-09-22T12:51:14Z 162814c ghcr.io/rmi/stitch-entity-linkage:pr-0283 ghcr.io/rmi/stitch-entity-linkage:pr-0283@sha256:22b66fa650c59d33fe0d4ba5a5870846a40dd815138affa277c45c84efa77a19
2026-09-22T12:51:32Z 2026-09-22T12:51:14Z 162814c ghcr.io/rmi/stitch-seed:pr-0283 ghcr.io/rmi/stitch-seed:pr-0283@sha256:a093d6c67e3f061443db61b6522ae66e7d14b54987ee7eb2752a358ad81dfcbb
2026-09-22T12:51:33Z 2026-09-22T12:51:14Z 162814c ghcr.io/rmi/stitch-stitch-llm:pr-0283 ghcr.io/rmi/stitch-stitch-llm:pr-0283@sha256:cf492e8b1479ca6b3e89989b351ab067e39001ee7eb23ea4fcf2e2150834dd11

@jdhoffa

jdhoffa commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Cool!!!

@github-actions

Copy link
Copy Markdown

CD summary 73bf7d2

Frontend: https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net

Deployments (4)
service url fqdn
api open pr-0283-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
entity-linkage open pr-0283-el.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net
stitch-llm open pr-0283-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0283 stitch-dev.postgres.database.azure.com 5432 pr_0283
Jobs (1)
job image postgres_db
db-migrations ghcr.io/rmi/stitch-api:pr-0283@sha256:dd772fda388af93a6894442b4f939009a1d4e289959154e535314274f7b8b782 pr_0283
Images (4)
build_time commit_time git_sha image image_digest
2026-09-24T09:28:07Z 2026-09-24T09:27:49Z 5d317ac ghcr.io/rmi/stitch-api:pr-0283 ghcr.io/rmi/stitch-api:pr-0283@sha256:dd772fda388af93a6894442b4f939009a1d4e289959154e535314274f7b8b782
2026-09-24T09:28:07Z 2026-09-24T09:27:49Z 5d317ac ghcr.io/rmi/stitch-entity-linkage:pr-0283 ghcr.io/rmi/stitch-entity-linkage:pr-0283@sha256:2c8c514545c4aa889c6ceb972dd28e561c5ba1f92d71f8463f051d2a530de75b
2026-09-24T09:28:08Z 2026-09-24T09:27:49Z 5d317ac ghcr.io/rmi/stitch-seed:pr-0283 ghcr.io/rmi/stitch-seed:pr-0283@sha256:7dc6e2f6f651f08d9ecf772d8c338a64b731bc8a1ac9805c36388483e9a8c636
2026-09-24T09:28:05Z 2026-09-24T09:27:49Z 5d317ac ghcr.io/rmi/stitch-stitch-llm:pr-0283 ghcr.io/rmi/stitch-stitch-llm:pr-0283@sha256:a455c78fbf571c7581f9be9cfd198749fabcc1d46d0289714395a80233f04931

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Filter-option labels contradict the stated contract, and the integration assertions can overlook unlabeled or unexpected events.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
Resolved since last review (1)

Comment thread deployments/api/src/stitch/api/db/og_field_resource_actions.py
Comment thread deployments/api/tests/observability/test_query_name_actions.py Outdated
Address PR #283 review: subset checks over a labels-only helper let an
unexpectedly-labeled or scope-leaked secondary query pass. Capture each
operation on its own and assert the exact label set it emits (missing or extra
labels now fail), pinning each action's full fan-out. Unlabeled statements
(connection/transaction/ORM-internal) stay excluded by design — the field is
optional.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

CD summary 16974af

Frontend: https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net

Deployments (4)
service url fqdn
api open pr-0283-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io
entity-linkage open pr-0283-el.purplegrass-c07d0a94.westus2.azurecontainerapps.io
frontend https://witty-mushroom-017a3dc1e-283.westus2.1.azurestaticapps.net
stitch-llm open pr-0283-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io
Database (1)
db_name postgres_host postgres_port postgres_db
pr_0283 stitch-dev.postgres.database.azure.com 5432 pr_0283
Jobs (1)
job image postgres_db
db-migrations ghcr.io/rmi/stitch-api:pr-0283@sha256:4733c9e210c218d399e6b872045fc9cde8c789e3414b9bc7d98b14025c68b23e pr_0283
Images (4)
build_time commit_time git_sha image image_digest
2026-09-24T09:49:36Z 2026-09-24T09:49:21Z 5295ac4 ghcr.io/rmi/stitch-api:pr-0283 ghcr.io/rmi/stitch-api:pr-0283@sha256:4733c9e210c218d399e6b872045fc9cde8c789e3414b9bc7d98b14025c68b23e
2026-09-24T09:49:40Z 2026-09-24T09:49:21Z 5295ac4 ghcr.io/rmi/stitch-entity-linkage:pr-0283 ghcr.io/rmi/stitch-entity-linkage:pr-0283@sha256:179eee3ed7403c1d50c7313747b149f3bb923e770188ca524d90581e500042f5
2026-09-24T09:49:36Z 2026-09-24T09:49:21Z 5295ac4 ghcr.io/rmi/stitch-seed:pr-0283 ghcr.io/rmi/stitch-seed:pr-0283@sha256:1bb9a6e8ff3321db4fdf5cccc79afa5a2e06fce8d84cbd7b5e12ba5add106302
2026-09-24T09:49:36Z 2026-09-24T09:49:21Z 5295ac4 ghcr.io/rmi/stitch-stitch-llm:pr-0283 ghcr.io/rmi/stitch-stitch-llm:pr-0283@sha256:560af6295640476391d9bb2f8b5ce1a45384d7e00c86d4d4781de80bc3eed095

@AlexAxthelm
AlexAxthelm merged commit 0eb529c into main Sep 24, 2026
32 checks passed
@AlexAxthelm
AlexAxthelm deleted the feat/query_name branch September 24, 2026 14:52

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants