Repository navigation
ref(cli): Template telemetry endpoints with the API catalog's paths - #2229
sentry-junior[bot] wants to merge 2 commits into
Conversation
`normalizeEndpoint` only templated paths with a leading slash, so paths
relative to `/api/0/` reached telemetry with raw org and project slugs.
This also normalizes full URLs, drops query strings, and templates short
IDs, monitor slugs, and numeric IDs. The same normalization now applies
to the `api_error` context, the `api_error.endpoint` span attribute of
`sentry api`, and the description and URL attributes (`url`, `url.full`,
`http.url`, `url.path`) of `http.client` spans.
On 0.48.0+, no `api_error.endpoint` value (~6K spans in 14d) and no
`http.client` span description (~1.3M of ~1.4M in 14d carry an org path)
was templated. Some `cli_error.api_endpoint` values still carried raw
slugs, through relative paths or short IDs.
**Before**
```
cli_error.api_endpoint: organizations/my-org/artifactbundle/assemble/
cli_error.api_endpoint: /organizations/{org}/shortids/MY-PROJECT-1A/
api_error.endpoint: projects/my-org/my-project/issues/?query=is:unresolved
span.description: GET https://sentry.io/api/0/organizations/my-org/issues/
```
**After**
```
cli_error.api_endpoint: organizations/{org}/artifactbundle/assemble/
cli_error.api_endpoint: /organizations/{org}/shortids/{id}/
api_error.endpoint: projects/{org}/{project}/issues/
span.description: GET https://sentry.io/api/0/organizations/{org}/issues/
```
<!-- junior-request-attribution:start -->
via @betegon.
<!-- junior-request-attribution:end -->
<!-- junior-session-footer:start -->
<!-- junior-conversation-id:agent%3Af73d86afcba15ac6080900f12725b985 -->
--
[View
Session](https://junior-prod.sentry.dev/conversations/agent%3Af73d86afcba15ac6080900f12725b985)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3Af73d86afcba15ac6080900f12725b985/?project=4510944073809921)
<!-- junior-session-footer:end -->
---------
Co-Authored-By: bete <28983162+betegon@users.noreply.github.com>
Replace normalizeEndpoint's regex list with the OpenAPI path templates
from @sentry/api, which generate-api-schema now writes to
src/generated/api-path-templates.json so the CLI never loads the full
catalog. The most specific template that matches the most of a path wins,
and segments past it that the templates don't spell out become {id}, so a
path outside the catalog leaks nothing.
Placeholders now use the OpenAPI names, such as
{organization_id_or_slug} and {project_id_or_slug}, which changes
existing cli_error.api_endpoint values.
Co-Authored-By: bete <28983162+betegon@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
| [/\/customers\/[^/]+/, "/customers/{org}"], | ||
| ]; | ||
| /** The API version prefix every OpenAPI path template starts with. */ | ||
| const API_PREFIX = "/api/0"; |
There was a problem hiding this comment.
Should this also come from the @sentry/api package? We can make it happen
There was a problem hiding this comment.
Yes, I think it should. @sentry/api doesn't export the API prefix today, in 0.428.0 on this branch or 1.59.0 on main. Toolkit defines "/api/0" privately in three places: toolkit-core/src/api-client/core.ts, cli/src/commands/api.ts, and now error-reporting.ts. An export from @sentry/api, for example next to buildSentryApiUrl, would let all three share it.
There was a problem hiding this comment.
Well then, make it happen. Ideally this would come all the way from the source in getsentry/sentry so we don't drift.
There was a problem hiding this comment.
I looked at what it would take to source this from the spec:
- getsentry/sentry: the OpenAPI spec's
serversentry is justhttps://{region}.sentry.io./api/0is spelled out at the start of every path in the spec, so the prefix isn't a separate field there today. - getsentry/sentry-api-schema (publishes
@sentry/api): the prefix is private there too. It's aconst API_PREFIXinlib/api-client/core.ts, plus hard-coded/api/0/inapi-path.tsandapi-path-scope.ts.
To avoid drift, sentry-api-schema could derive the prefix from the spec's paths at build time and export it. toolkit's three copies would then import it. Moving /api/0 into servers in getsentry/sentry would also work, but it changes the spec for every client.
This is a change in other repos, so I'm checking the scope with @betegon before I start. I'll leave this thread open until then.
**Depends on:** `@sentry/api` 2.0.0, which is published ([getsentry/sentry-api-schema#148](getsentry/sentry-api-schema#148)). This is the last step of the chain sentry-api-schema#148 → [sentry-docs#20787](getsentry/sentry-docs#20787) → [sentry#131065](getsentry/sentry#131065) → this PR. Sentry's OpenAPI spec is moving `/api/0` out of every path and into its server URL. `@sentry/api` 2.0 reads the base path from that URL, exports it as `API_BASE_PATH`, and makes operation paths relative. This PR drops toolkit's private `/api/0` copies and uses the export instead, so the version number lives only in the spec. Before: ```ts const API_PREFIX = "/api/0"; // cli/src/commands/api.ts this.apiPrefix = `${protocol}://${host}/api/0`; // mcp-core api-client path: operation.path, // "/api/0/organizations/" in 1.x ``` After: ```ts import { API_BASE_PATH } from "@sentry/api/client"; this.apiPrefix = `${protocol}://${host}${API_BASE_PATH}`; path: `${API_BASE_PATH}${operation.path}`, // still "/api/0/organizations/" ``` - **CLI endpoint index:** it keeps full request paths, so `sentry schema` and `sentry api` still show and accept `/api/0/...`. - **Requests:** CLI raw requests now pass relative URLs to `prepareRequest`. - **Unchanged on purpose:** user-facing help text and examples still say `/api/0`. - **Breaking:** only the `@sentry/api` 1.x → 2.0.0 bump. CLI and MCP behavior doesn't change, so no toolkit major is needed. **#2229 (stacked on #1807):** on 2.0 it needs two changes: - replace its local `API_PREFIX = "/api/0"` in `error-reporting.ts` with `API_BASE_PATH`; - build `api-path-templates.json` from `` `${API_BASE_PATH}${op.path}` ``, because `op.path` is now relative. **Checks:** - `pnpm run tsc` and `pnpm run lint` pass. - mcp-core vitest: 2301 passed. - The CLI api, schema, sentry-client, error-reporting, issue-links and script tests: 82 files, 1685 passed. - `pnpm install --frozen-lockfile` passes with the `minimumReleaseAgeExclude` entry moved from 1.83.0 to 2.0.0. <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A640c5343d03e547097aa9b8a711daaf5 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A640c5343d03e547097aa9b8a711daaf5) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A640c5343d03e547097aa9b8a711daaf5/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
Stacked on #1807. It also carries #2213's commit, which is already on
mainbut not on #1807's branch; it drops out of the diff once #1807 picks upmain.This follows up @BYK's suggestion on #2213:
normalizeEndpointnow templates paths with the@sentry/apiOpenAPI path templates andmatchApiPathTemplate, instead of a regex list.generate-api-schema.tswrites the 173 unique paths (~14 KB) tosrc/generated/api-path-templates.json, next toidempotent-operations.json, so the CLI never loads the full catalog. The template that matches the most of the path wins. Any segment past that match that no template spells out becomes{id}, so a path outside the catalog doesn't leak. This coverscli_error.api_endpoint,api_error.endpoint, and thehttp.clientspan description and URL attributes. The install-prefix and/api/0handling from #2213 are unchanged.Placeholder names change. Existing
cli_error.api_endpointvalues change too:{org}becomes{organization_id_or_slug},{project}becomes{project_id_or_slug}, and{id}becomes the catalog's name where there is one, such as{issue_id}or{event_id}. Nothing in this repo keys on the old form excepterror-reporting.test.ts, which this PR updates. In Sentry, none of thesentry/clifingerprint rules, issue alerts, or metric alerts referencecli_error.api_endpoint, and neither does any widget on the 12 CLI dashboards.Endpoints missing from the public catalog, such as
/auth/,/envelope/, andevents-stats, now report{id}in place of their name. Full URLs outside/api/0/, such as OAuth or GitHub, are left as they are.Before
After
via @betegon.
--
View Session [Sentry]