Skip to content

fix: use endpoint templates in metrics labels#115

Merged
rsbh merged 6 commits into
mainfrom
fix/metrics-route-templates
Jun 3, 2026
Merged

fix: use endpoint templates in metrics labels#115
rsbh merged 6 commits into
mainfrom
fix/metrics-route-templates

Conversation

@rsbh
Copy link
Copy Markdown
Member

@rsbh rsbh commented Jun 3, 2026

Summary

  • Replace raw request paths with endpoint templates in Prometheus metric labels to prevent high-cardinality explosion
  • API routes (/api/*) keep exact path since they're fixed endpoints
  • Map-based approach for easy extension
Path Label
/docs/guides/installation /docs/:slug
/apis/petstore/listPets /apis/:slug
/api/page /api/page
/api/search /api/search
/assets/chunk-abc.js /assets/:file
/_content/docs/intro.mdx /_content/:path
/llms.txt /llms.txt

Test plan

  • 163 tests pass

🤖 Generated with Claude Code

Prevents high-cardinality metric labels in Prometheus by mapping
request paths to endpoint templates (e.g., /docs/:slug, /apis/:slug).
API routes keep their exact path (/api/page, /api/search).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chronicle Ready Ready Preview, Comment Jun 3, 2026 6:39am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 022da52c-19d4-42e4-8af0-5ba0bf2352b1

📥 Commits

Reviewing files that changed from the base of the PR and between 4366645 and 55b8949.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • packages/chronicle/src/server/plugins/telemetry.test.ts
  • packages/chronicle/src/server/plugins/telemetry.ts

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Enhanced the internal telemetry system through improved endpoint normalization to ensure consistent and reliable metric collection across different route categories and request patterns for better service monitoring and observability.
    • Updated continuous integration pipeline configuration with improved Windows platform support to enhance build stability and compatibility across all supported development environments.

Walkthrough

Adds a toEndpoint(pathname) helper and routing maps to normalize URL pathnames into stable endpoint templates; updates SSR render and HTTP request metrics to use the normalized endpoint label; includes tests for mapping behavior and a CI env tweak for the dev-server smoke test on Windows.

Changes

Route Normalization for Telemetry

Layer / File(s) Summary
Endpoint normalization helper and tests
packages/chronicle/src/server/plugins/telemetry.ts, packages/chronicle/src/server/plugins/telemetry.test.ts
Adds ROUTES, ENDPOINT_MAP, STATIC_ROUTES, and exported toEndpoint(pathname) to map pathnames to stable endpoint templates; includes tests covering root, docs, apis, assets, content, static files, and versioned docs cases.
Apply normalization to SSR and HTTP metrics
packages/chronicle/src/server/plugins/telemetry.ts
Updates chronicle:ssr-rendered duration and HTTP request counter/histogram to compute pathname from requests, normalize via toEndpoint(...), and record metrics under the endpoint label.

CI Workflow

Layer / File(s) Summary
Dev-server smoke test env tweak
.github/workflows/ci.yml
Sets NITRO_DEV_RUNNER to self on windows-latest for the Smoke test dev server step via an env block.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: use endpoint templates in metrics labels' clearly and concisely describes the main change: normalizing raw request paths to endpoint templates in Prometheus metrics.
Description check ✅ Passed The description is directly related to the changeset, explaining the motivation (preventing high-cardinality explosion), approach (map-based routing), and providing concrete examples matching the code changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/metrics-route-templates

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rsbh and others added 2 commits June 3, 2026 10:59
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/chronicle/src/server/plugins/telemetry.ts`:
- Line 75: The code uses new URL(event.req.url).pathname which can throw for
relative URLs; replace that with a safe extraction like using event.path if
available or falling back to event.req.url?.split('?')[0] before calling
toEndpoint. Update the endpoint assignment in telemetry.ts (the const endpoint =
... line) to derive a safePath = event.path || event.req.url?.split('?')[0] (or
an empty string fallback) and then call toEndpoint(safePath) so toEndpoint and
endpoint are never fed an invalid URL.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bae0bef3-66c9-4d6c-ae32-f96abb005d8a

📥 Commits

Reviewing files that changed from the base of the PR and between 5ec5fa1 and 4366645.

📒 Files selected for processing (1)
  • packages/chronicle/src/server/plugins/telemetry.ts

const route = new URL(event.req.url).pathname
requestCounter.add(1, { method, route, status: res.status })
requestDuration.record(duration, { method, route, status: res.status })
const endpoint = toEndpoint(new URL(event.req.url).pathname)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for event.req.url usage patterns in the codebase to determine format

# Search for existing usage of event.req.url
rg -n -C3 'event\.req\.url' --type=ts

# Search for URL parsing patterns
rg -n -C3 'new URL.*event\.req' --type=ts

Repository: raystack/chronicle

Length of output: 2143


🌐 Web query:

Nitro h3 event.req.url format full URL or relative path

💡 Result:

Nitro/H3: event.req.url is a relative URL/path component (not a full absolute URL). In Nitro, you typically access the request URL parts via: - event.url.pathname for the matched pathname (example middleware/routing uses event.url.pathname) [1] - event.req.url is then used as the path-ish value when Nitro/H3 creates the H3 event (and is consumed as such by proxy/middleware expectations); in an H3 bug report, overwriting node req.url with a decoded path is explicitly called out as wrong because it’s “consumed by HTTP proxies and Node.js middleware that expect the percent-encoded form” [2]. That implies req.url holds the (encoded) path/relative portion, not an origin-based full URL. If you need a full absolute URL, Nitro provides getRequestURL(event) (discussed in Nitro issues about origin/hostname extraction) rather than relying on event.req.url [3]. So, the answer to “Nitro h3 event.req.url format full URL or relative path” is: relative path (path + query), not an absolute URL with scheme/host.

Citations:


Fix unsafe new URL(event.req.url) usage in telemetry (can throw).

In Nitro/H3, event.req.url is typically a relative path (path + query), so new URL(event.req.url).pathname can throw TypeError: Invalid URL and break request metrics. This matches the repo’s existing pattern using event.path || event.req.url?.split('?')[0] in packages/chronicle/src/server/routes/[...slug].md.ts.

🔧 Proposed fix
-    const endpoint = toEndpoint(new URL(event.req.url).pathname)
+    const pathname = event.path || event.req.url?.split('?')[0] || '/'
+    const endpoint = toEndpoint(pathname)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const endpoint = toEndpoint(new URL(event.req.url).pathname)
const pathname = event.path || event.req.url?.split('?')[0] || '/'
const endpoint = toEndpoint(pathname)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/chronicle/src/server/plugins/telemetry.ts` at line 75, The code uses
new URL(event.req.url).pathname which can throw for relative URLs; replace that
with a safe extraction like using event.path if available or falling back to
event.req.url?.split('?')[0] before calling toEndpoint. Update the endpoint
assignment in telemetry.ts (the const endpoint = ... line) to derive a safePath
= event.path || event.req.url?.split('?')[0] (or an empty string fallback) and
then call toEndpoint(safePath) so toEndpoint and endpoint are never fed an
invalid URL.

node-process runner uses fork() + IPC which is flaky on Windows CI
runners — child process sometimes never sends ready signal, causing
health check to hang until job timeout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@rohilsurana rohilsurana left a comment

Choose a reason for hiding this comment

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

LGTM

@rsbh rsbh merged commit 2f0de1a into main Jun 3, 2026
7 of 9 checks passed
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.

2 participants