feat: experimental tracing logger#4406
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR adds Node diagnostics-channel-based tracing to Nitro, including OTLP span models, traced channel subscription, a console logger plugin, Vercel telemetry wiring, tracing config options, and a tracing example app. ChangesTracing infrastructure and integrations
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/config/resolvers/tracing.ts (1)
18-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSilent override of
features.runtimeHookswhen a user explicitly disabled it.
options.features.runtimeHooks = trueunconditionally overwrites any explicitfalsethe user may have set (e.g. to opt out for perf reasons). Since this is a hard requirement fortracingLoggerto function, consider logging a short notice when overriding an explicitfalseso the behavior isn't silently surprising.🤖 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 `@src/config/resolvers/tracing.ts` around lines 18 - 24, The tracing logger setup in the tracing resolver unconditionally flips options.features.runtimeHooks to true, which can silently override an explicit false. Update the logic in the tracingLogger branch to detect when the user has set runtimeHooks to false, then emit a short notice through the existing logging mechanism before overriding it; keep the current behavior that forces runtimeHooks on for the logger-plugin and preserve the existing options.plugins.unshift and options.features initialization flow.src/runtime/internal/telemetry/channels.ts (1)
106-128: 📐 Maintainability & Code Quality | 🔵 TrivialRedundant re-derivation of
operationinside the closure.The describer recomputes
operationfromchannel.slice(...), shadowing the outeroperationalready captured from the.map()iteration that produced this exact key. Since the closure is keyed to a specific channel name, the outer variable can be used directly.♻️ Suggested simplification
].map((operation) => [ `unstorage.${operation}`, (channel: string, data: unknown) => { const { driver, base, keys } = data as { driver?: { name?: string }; base?: string; keys?: unknown[]; }; - const operation = channel.slice("unstorage.".length); // CLIENT: storage is a known outbound dependency (OTEL database semconv).🤖 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 `@src/runtime/internal/telemetry/channels.ts` around lines 106 - 128, The channel describer in `channels.ts` recomputes and shadows `operation` inside the `unstorage.${operation}` callback even though the outer `.map()` iteration already provides the exact value. Update the closure to use the captured outer `operation` directly in the `attributes` and span `name` construction, and remove the redundant `channel.slice(...)` re-derivation so the logic stays simpler and avoids shadowing.src/runtime/internal/telemetry/span.ts (2)
31-37: 📐 Maintainability & Code Quality | 🔵 TrivialConstructor takes 5 positional args instead of an options object.
As per coding guidelines,
src/**/*.{ts,js}should use "an options object as the second parameter" for multi-argument functions. This constructor takestraceId, parentSpanId, info, startTimeUnixNano, errorpositionally, which is error-prone to call correctly (e.g. mixing upparentSpanId/startTimeUnixNano, both strings) and harder to extend later.♻️ Suggested signature
- constructor( - traceId: string, - parentSpanId: string, - info: SpanInfo, - startTimeUnixNano: string, - error: unknown - ) { - this.traceId = traceId; + constructor( + traceId: string, + info: SpanInfo, + options: { parentSpanId: string; startTimeUnixNano: string; error?: unknown } + ) { + this.traceId = traceId; + const { parentSpanId, startTimeUnixNano, error } = options;🤖 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 `@src/runtime/internal/telemetry/span.ts` around lines 31 - 37, The Span constructor currently accepts five positional arguments, which violates the options-object guideline and makes call sites easy to misuse. Update the Span class constructor to take a single options object (including traceId, parentSpanId, info, startTimeUnixNano, and error) and adjust any instantiation sites to pass named properties instead of ordered parameters. Keep the Span class and its constructor as the primary symbols to locate and refactor.Source: Coding guidelines
81-90: 📐 Maintainability & Code Quality | 🔵 TrivialConsider a stronger RNG for span IDs.
Math.random()is not collision-resistant; the Web Crypto API (crypto.getRandomValues), which is available globally and fits the "prefer Web APIs" guideline forsrc/runtime/, would reduce collision risk at negligible cost.♻️ Suggested implementation
- static randomSpanId(): string { - let id = ""; - for (let i = 0; i < 8; i++) { - id += Math.floor(Math.random() * 256) - .toString(16) - .padStart(2, "0"); - } - return id === "0000000000000000" ? "0000000000000001" : id; - } + static randomSpanId(): string { + const bytes = crypto.getRandomValues(new Uint8Array(8)); + const id = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join(""); + return id === "0000000000000000" ? "0000000000000001" : id; + }🤖 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 `@src/runtime/internal/telemetry/span.ts` around lines 81 - 90, The span ID generator in `Span.randomSpanId()` currently uses `Math.random()`, which is too weak for collision resistance. Update it to use the Web Crypto API via `crypto.getRandomValues` to generate the 8 random bytes, keeping the same hex-encoded 16-character output and the existing all-zero sentinel fallback. Make the change within `src/runtime/internal/telemetry/span.ts` so the runtime follows the preferred Web API approach.Source: Coding guidelines
🤖 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 `@src/presets/vercel/runtime/telemetry/plugin.ts`:
- Around line 69-96: The fire-and-forget flush inside the telemetry plugin can
reject if sink.reportSpans() throws, which leaves the context.waitUntil task
unhandled. Update the flush callback in plugin.ts to wrap the sink.reportSpans
call in a try/catch and swallow or safely log failures so the pendingSpans batch
cleanup still runs and the request lifecycle is not destabilized. Use the
existing root.traceId, pendingSpans, and sink references to locate the flush
path.
---
Nitpick comments:
In `@src/config/resolvers/tracing.ts`:
- Around line 18-24: The tracing logger setup in the tracing resolver
unconditionally flips options.features.runtimeHooks to true, which can silently
override an explicit false. Update the logic in the tracingLogger branch to
detect when the user has set runtimeHooks to false, then emit a short notice
through the existing logging mechanism before overriding it; keep the current
behavior that forces runtimeHooks on for the logger-plugin and preserve the
existing options.plugins.unshift and options.features initialization flow.
In `@src/runtime/internal/telemetry/channels.ts`:
- Around line 106-128: The channel describer in `channels.ts` recomputes and
shadows `operation` inside the `unstorage.${operation}` callback even though the
outer `.map()` iteration already provides the exact value. Update the closure to
use the captured outer `operation` directly in the `attributes` and span `name`
construction, and remove the redundant `channel.slice(...)` re-derivation so the
logic stays simpler and avoids shadowing.
In `@src/runtime/internal/telemetry/span.ts`:
- Around line 31-37: The Span constructor currently accepts five positional
arguments, which violates the options-object guideline and makes call sites easy
to misuse. Update the Span class constructor to take a single options object
(including traceId, parentSpanId, info, startTimeUnixNano, and error) and adjust
any instantiation sites to pass named properties instead of ordered parameters.
Keep the Span class and its constructor as the primary symbols to locate and
refactor.
- Around line 81-90: The span ID generator in `Span.randomSpanId()` currently
uses `Math.random()`, which is too weak for collision resistance. Update it to
use the Web Crypto API via `crypto.getRandomValues` to generate the 8 random
bytes, keeping the same hex-encoded 16-character output and the existing
all-zero sentinel fallback. Make the change within
`src/runtime/internal/telemetry/span.ts` so the runtime follows the preferred
Web API approach.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 50502117-a3b9-4ee2-9826-cbe864816984
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
examples/tracing/README.mdexamples/tracing/nitro.config.tsexamples/tracing/package.jsonexamples/tracing/server/middleware/timing.tsexamples/tracing/server/routes/index.tsexamples/tracing/server/routes/users/[id].tsexamples/tracing/tsconfig.jsonexamples/tracing/vite.config.tssrc/config/resolvers/tracing.tssrc/presets/vercel/preset.tssrc/presets/vercel/runtime/telemetry/plugin.tssrc/runtime/internal/telemetry/channels.tssrc/runtime/internal/telemetry/logger-plugin.tssrc/runtime/internal/telemetry/span.tssrc/runtime/internal/telemetry/subscribe.tssrc/runtime/internal/telemetry/types.tssrc/types/config.tstest/unit/telemetry-logger.test.tstest/unit/vercel-telemetry.test.ts
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/config/resolvers/tracing.ts (1)
18-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSilent override of
features.runtimeHookswhen a user explicitly disabled it.
options.features.runtimeHooks = trueunconditionally overwrites any explicitfalsethe user may have set (e.g. to opt out for perf reasons). Since this is a hard requirement fortracingLoggerto function, consider logging a short notice when overriding an explicitfalseso the behavior isn't silently surprising.🤖 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 `@src/config/resolvers/tracing.ts` around lines 18 - 24, The tracing logger setup in the tracing resolver unconditionally flips options.features.runtimeHooks to true, which can silently override an explicit false. Update the logic in the tracingLogger branch to detect when the user has set runtimeHooks to false, then emit a short notice through the existing logging mechanism before overriding it; keep the current behavior that forces runtimeHooks on for the logger-plugin and preserve the existing options.plugins.unshift and options.features initialization flow.src/runtime/internal/telemetry/channels.ts (1)
106-128: 📐 Maintainability & Code Quality | 🔵 TrivialRedundant re-derivation of
operationinside the closure.The describer recomputes
operationfromchannel.slice(...), shadowing the outeroperationalready captured from the.map()iteration that produced this exact key. Since the closure is keyed to a specific channel name, the outer variable can be used directly.♻️ Suggested simplification
].map((operation) => [ `unstorage.${operation}`, (channel: string, data: unknown) => { const { driver, base, keys } = data as { driver?: { name?: string }; base?: string; keys?: unknown[]; }; - const operation = channel.slice("unstorage.".length); // CLIENT: storage is a known outbound dependency (OTEL database semconv).🤖 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 `@src/runtime/internal/telemetry/channels.ts` around lines 106 - 128, The channel describer in `channels.ts` recomputes and shadows `operation` inside the `unstorage.${operation}` callback even though the outer `.map()` iteration already provides the exact value. Update the closure to use the captured outer `operation` directly in the `attributes` and span `name` construction, and remove the redundant `channel.slice(...)` re-derivation so the logic stays simpler and avoids shadowing.src/runtime/internal/telemetry/span.ts (2)
31-37: 📐 Maintainability & Code Quality | 🔵 TrivialConstructor takes 5 positional args instead of an options object.
As per coding guidelines,
src/**/*.{ts,js}should use "an options object as the second parameter" for multi-argument functions. This constructor takestraceId, parentSpanId, info, startTimeUnixNano, errorpositionally, which is error-prone to call correctly (e.g. mixing upparentSpanId/startTimeUnixNano, both strings) and harder to extend later.♻️ Suggested signature
- constructor( - traceId: string, - parentSpanId: string, - info: SpanInfo, - startTimeUnixNano: string, - error: unknown - ) { - this.traceId = traceId; + constructor( + traceId: string, + info: SpanInfo, + options: { parentSpanId: string; startTimeUnixNano: string; error?: unknown } + ) { + this.traceId = traceId; + const { parentSpanId, startTimeUnixNano, error } = options;🤖 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 `@src/runtime/internal/telemetry/span.ts` around lines 31 - 37, The Span constructor currently accepts five positional arguments, which violates the options-object guideline and makes call sites easy to misuse. Update the Span class constructor to take a single options object (including traceId, parentSpanId, info, startTimeUnixNano, and error) and adjust any instantiation sites to pass named properties instead of ordered parameters. Keep the Span class and its constructor as the primary symbols to locate and refactor.Source: Coding guidelines
81-90: 📐 Maintainability & Code Quality | 🔵 TrivialConsider a stronger RNG for span IDs.
Math.random()is not collision-resistant; the Web Crypto API (crypto.getRandomValues), which is available globally and fits the "prefer Web APIs" guideline forsrc/runtime/, would reduce collision risk at negligible cost.♻️ Suggested implementation
- static randomSpanId(): string { - let id = ""; - for (let i = 0; i < 8; i++) { - id += Math.floor(Math.random() * 256) - .toString(16) - .padStart(2, "0"); - } - return id === "0000000000000000" ? "0000000000000001" : id; - } + static randomSpanId(): string { + const bytes = crypto.getRandomValues(new Uint8Array(8)); + const id = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join(""); + return id === "0000000000000000" ? "0000000000000001" : id; + }🤖 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 `@src/runtime/internal/telemetry/span.ts` around lines 81 - 90, The span ID generator in `Span.randomSpanId()` currently uses `Math.random()`, which is too weak for collision resistance. Update it to use the Web Crypto API via `crypto.getRandomValues` to generate the 8 random bytes, keeping the same hex-encoded 16-character output and the existing all-zero sentinel fallback. Make the change within `src/runtime/internal/telemetry/span.ts` so the runtime follows the preferred Web API approach.Source: Coding guidelines
🤖 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 `@src/presets/vercel/runtime/telemetry/plugin.ts`:
- Around line 69-96: The fire-and-forget flush inside the telemetry plugin can
reject if sink.reportSpans() throws, which leaves the context.waitUntil task
unhandled. Update the flush callback in plugin.ts to wrap the sink.reportSpans
call in a try/catch and swallow or safely log failures so the pendingSpans batch
cleanup still runs and the request lifecycle is not destabilized. Use the
existing root.traceId, pendingSpans, and sink references to locate the flush
path.
---
Nitpick comments:
In `@src/config/resolvers/tracing.ts`:
- Around line 18-24: The tracing logger setup in the tracing resolver
unconditionally flips options.features.runtimeHooks to true, which can silently
override an explicit false. Update the logic in the tracingLogger branch to
detect when the user has set runtimeHooks to false, then emit a short notice
through the existing logging mechanism before overriding it; keep the current
behavior that forces runtimeHooks on for the logger-plugin and preserve the
existing options.plugins.unshift and options.features initialization flow.
In `@src/runtime/internal/telemetry/channels.ts`:
- Around line 106-128: The channel describer in `channels.ts` recomputes and
shadows `operation` inside the `unstorage.${operation}` callback even though the
outer `.map()` iteration already provides the exact value. Update the closure to
use the captured outer `operation` directly in the `attributes` and span `name`
construction, and remove the redundant `channel.slice(...)` re-derivation so the
logic stays simpler and avoids shadowing.
In `@src/runtime/internal/telemetry/span.ts`:
- Around line 31-37: The Span constructor currently accepts five positional
arguments, which violates the options-object guideline and makes call sites easy
to misuse. Update the Span class constructor to take a single options object
(including traceId, parentSpanId, info, startTimeUnixNano, and error) and adjust
any instantiation sites to pass named properties instead of ordered parameters.
Keep the Span class and its constructor as the primary symbols to locate and
refactor.
- Around line 81-90: The span ID generator in `Span.randomSpanId()` currently
uses `Math.random()`, which is too weak for collision resistance. Update it to
use the Web Crypto API via `crypto.getRandomValues` to generate the 8 random
bytes, keeping the same hex-encoded 16-character output and the existing
all-zero sentinel fallback. Make the change within
`src/runtime/internal/telemetry/span.ts` so the runtime follows the preferred
Web API approach.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 50502117-a3b9-4ee2-9826-cbe864816984
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
examples/tracing/README.mdexamples/tracing/nitro.config.tsexamples/tracing/package.jsonexamples/tracing/server/middleware/timing.tsexamples/tracing/server/routes/index.tsexamples/tracing/server/routes/users/[id].tsexamples/tracing/tsconfig.jsonexamples/tracing/vite.config.tssrc/config/resolvers/tracing.tssrc/presets/vercel/preset.tssrc/presets/vercel/runtime/telemetry/plugin.tssrc/runtime/internal/telemetry/channels.tssrc/runtime/internal/telemetry/logger-plugin.tssrc/runtime/internal/telemetry/span.tssrc/runtime/internal/telemetry/subscribe.tssrc/runtime/internal/telemetry/types.tssrc/types/config.tstest/unit/telemetry-logger.test.tstest/unit/vercel-telemetry.test.ts
🛑 Comments failed to post (1)
src/presets/vercel/runtime/telemetry/plugin.ts (1)
69-96: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Wrap
sink.reportSpans()in try/catch to avoid an unhandled rejection from the fire-and-forget flush task.The async task handed to
context.waitUntilcallssink.reportSpans(data)(line 80) with no error handling. If this throws (network hiccup, malformed payload rejected by Vercel's IPC layer, etc.), the returned promise rejects with nothing to catch it — this telemetry sink should never risk destabilizing the request lifecycle it's attached to.🛡️ Proposed fix
context.waitUntil(async () => { const batch = pendingSpans.get(traceId); pendingSpans.delete(traceId); if (!batch || batch.length === 0) return; - // Wrap the batch in a single OTLP `ExportTraceServiceRequest` envelope. - sink.reportSpans({ - resourceSpans: [ - { - resource: { attributes: [], droppedAttributesCount: 0 }, - scopeSpans: [ - { - scope: { name: SCOPE_NAME, version: "", attributes: [], droppedAttributesCount: 0 }, - spans: batch, - schemaUrl: "", - }, - ], - schemaUrl: "", - }, - ], - }); + try { + // Wrap the batch in a single OTLP `ExportTraceServiceRequest` envelope. + sink.reportSpans({ + resourceSpans: [ + { + resource: { attributes: [], droppedAttributesCount: 0 }, + scopeSpans: [ + { + scope: { name: SCOPE_NAME, version: "", attributes: [], droppedAttributesCount: 0 }, + spans: batch, + schemaUrl: "", + }, + ], + schemaUrl: "", + }, + ], + }); + } catch { + // Telemetry export failures must never surface to the request lifecycle. + } });📝 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.// Buffer per request; the first span schedules a single flush at freeze time. let spans = pendingSpans.get(root.traceId); if (!spans) { spans = []; const { traceId } = root; const sink = telemetry; context.waitUntil(async () => { const batch = pendingSpans.get(traceId); pendingSpans.delete(traceId); if (!batch || batch.length === 0) return; try { // Wrap the batch in a single OTLP `ExportTraceServiceRequest` envelope. sink.reportSpans({ resourceSpans: [ { resource: { attributes: [], droppedAttributesCount: 0 }, scopeSpans: [ { scope: { name: SCOPE_NAME, version: "", attributes: [], droppedAttributesCount: 0 }, spans: batch, schemaUrl: "", }, ], schemaUrl: "", }, ], }); } catch { // Telemetry export failures must never surface to the request lifecycle. } }); pendingSpans.set(traceId, spans);🤖 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 `@src/presets/vercel/runtime/telemetry/plugin.ts` around lines 69 - 96, The fire-and-forget flush inside the telemetry plugin can reject if sink.reportSpans() throws, which leaves the context.waitUntil task unhandled. Update the flush callback in plugin.ts to wrap the sink.reportSpans call in a try/catch and swallow or safely log failures so the pendingSpans batch cleanup still runs and the request lifecycle is not destabilized. Use the existing root.traceId, pendingSpans, and sink references to locate the flush path.
Add `experimental.tracingLogger`, a built-in, dependency-free telemetry sink that groups each request's tracing-channel spans (h3, srvx, unstorage) into a per-request console timeline. Grouping uses the `request`/`response` runtime hooks + async context, so it works in both `vite dev` and production. Move the platform-agnostic telemetry core (channels, span, OTLP types) from the vercel preset to `src/runtime/internal/telemetry` as the shared source of truth; the vercel exporter and the new logger both consume it via `subscribeTracedChannels`. Includes an `examples/tracing` demo. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
There was a problem hiding this comment.
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 `@examples/tracing/README.md`:
- Around line 32-38: The rendered example block in the tracing README is missing
a language tag, which triggers markdownlint MD040. Update the fenced code block
in the example output to use a plain text/console label so the docs stay
lint-clean, and keep the content unchanged otherwise.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0f233ec9-b8af-4b89-8c7c-b1bcffcfa5b5
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (18)
examples/tracing/README.mdexamples/tracing/nitro.config.tsexamples/tracing/package.jsonexamples/tracing/server/middleware/timing.tsexamples/tracing/server/routes/index.tsexamples/tracing/server/routes/users/[id].tsexamples/tracing/tsconfig.jsonexamples/tracing/vite.config.tssrc/config/resolvers/tracing.tssrc/presets/vercel/runtime/telemetry/plugin.tssrc/runtime/internal/telemetry/channels.tssrc/runtime/internal/telemetry/logger-plugin.tssrc/runtime/internal/telemetry/span.tssrc/runtime/internal/telemetry/subscribe.tssrc/runtime/internal/telemetry/types.tssrc/types/config.tstest/unit/telemetry-logger.test.tstest/unit/vercel-telemetry.test.ts
✅ Files skipped from review due to trivial changes (2)
- examples/tracing/tsconfig.json
- examples/tracing/server/middleware/timing.ts
🚧 Files skipped from review as they are similar to previous changes (11)
- examples/tracing/vite.config.ts
- examples/tracing/package.json
- examples/tracing/server/routes/index.ts
- examples/tracing/server/routes/users/[id].ts
- src/types/config.ts
- examples/tracing/nitro.config.ts
- src/config/resolvers/tracing.ts
- src/runtime/internal/telemetry/subscribe.ts
- test/unit/telemetry-logger.test.ts
- src/presets/vercel/runtime/telemetry/plugin.ts
- src/runtime/internal/telemetry/logger-plugin.ts
continue from #4001 > #4355
This PR refactors span creation logic from vercel preset into generic internals and adds new
experimental.tracingLoggerto easily do tracing in dev and prod via console