Repository navigation
feat: add GraphQL operation, resolver, and error metrics - #434
AllysiadevOps wants to merge 6 commits into
Conversation
|
@AllysiadevOps Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
tsc --noEmit clean vitest 97 files, 1127 passing (up from 93 / 1068) dropped-tests none #325 GET /movers for market gainers and losers #327 GET /correlation for basket construction #485 net arbitrage spread against fees #494 declare the resources capability and expose pages over MCP Two fixes on merge. #325 shipped the route file and the OpenAPI entry but never registered it. The repo's own guard caught it: AssertionError: Documented but unregistered: ["GET /movers"] So the endpoint was documented, generated into clients, and did not exist. registerMoversRoutes already followed the house signature, so wiring it was an import and a call next to registerScreenerRoutes. That guard is worth its weight -- a documented route that 404s is worse than an undocumented one, because a client is generated against it. #327 added a console.error to src/routes/correlation.ts, which the logging hygiene test forbids. Now createLogger, the same change #388 and #318 needed in the previous batch. Three PRs in two batches have tripped that test, which suggests the rule is not discoverable enough from the outside -- worth a line in CONTRIBUTING rather than catching it per-PR. NOT merged, each failing on its own branch rather than from merge order: #460 Phoenix AMM adapter -- 5 failures alone, including its own networkVenueConfig and venues/registry tests #353 1 tsc error #354 1 tsc error #482 4 tsc errors #393 #431 #434 #472 conflict Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
Miracle656
left a comment
There was a problem hiding this comment.
Screened against current main: this has 9 type errors on its own branch, so it needs work beyond a rebase.
Run npx tsc --noEmit after rebasing and you will see them. A fair number of PRs here today failed the same way, and in most cases it was a helper that gained a parameter, or a symbol that lives on another branch and never arrived with this one.
Two guards worth knowing about before you re-request, because both caught PRs today:
console.*is forbidden in non-test source — usecreateLoggertests/openapi.test.tsfails if a route is documented but not registered insrc/app.ts, or registered but not documented
Get tsc and vitest both clean locally and I will review it properly.
Miracle656
left a comment
There was a problem hiding this comment.
Scanned clean. GraphQL has been the blind spot in our metrics — the HTTP middleware counts one POST to /graphql whether it resolved one field or fifty, so operation and resolver level instrumentation is the only way to see what is actually expensive. Worth having.
The branch is 79 commits behind main, and merging it as-is would revert shipped work.
Against current main the diff removes roughly 6,000 lines from src/ that are not yours — files that landed after you branched: src/reconciliation/dispersion.ts (312, #448), src/__tests__/venueReconciliation.test.ts (385), src/__tests__/observationAndSourceTime.test.ts (335, #240), and src/routes/facilitator.ts, whose x402 spend ceiling landed this morning.
Please rebase on current main and re-request. npx tsc --noEmit and npx vitest run both pass on main right now.
One thing to settle on the rebase, because it decides whether these metrics are safe: label cardinality. An operation label taken from the client-supplied operation name is unbounded — a caller who sends a unique name per request grows /metrics until it cannot be scraped, and that is a denial of service against our own monitoring rather than a reporting bug.
Bound it by construction: label by resolver/field name from the schema (a finite set we control), and treat the operation name as something to log, not to label. If you do want an operation label, it has to be an allow-list of known documents with everything else collapsing to other.
Also worth coordinating with #446, which adds mcp_tool_calls_total, mcp_tool_duration_seconds and mcp_errors_total. Different namespace from yours so they should not collide, but you are both extending src/metrics.ts and whichever rebases second will meet the other there.
|
@Miracle656 — this PR is ready for another review. I resolved the merge conflicts with the main branch (pushed 63f205f). |
Overview
This PR adds bounded-cardinality Prometheus metrics for the GraphQL surface so that GraphQL traffic can be distinguished from other HTTP traffic and attributed to specific operations, resolver fields, and error categories. Previously
src/middleware/httpMetrics.tscollapsed every GraphQL request into a singlePOST /graphqlroute, andsrc/api/graphql.tsemitted no GraphQL-specific metrics at all — makinggetPricetraffic invisible and any future GraphQL pricing impossible to measure.Related Issue
Changes
📊 GraphQL Metrics
[MODIFY]
src/api/graphql.tsquery,mutation,subscription).getPrice).[MODIFY]
src/middleware/httpMetrics.ts/metricsendpoint as the single scrape target.All new metrics are registered on the existing Prometheus registry and are therefore exposed on the existing
/metricsendpoint — no new endpoint was added.Verification Results
The new metrics are exercised through the existing test surface; no new test files were added in this PR.
Load test (prices)remains failing onmainand is unrelated to this change.getPrice/metricsendpointCloses #374