Skip to content

ENG-9166 feat(otel): browser tracing plugin — traceparent per event, web vitals, render timing (3/3) - #6901

Open
FarhanAliRaza wants to merge 5 commits into
farhan/eng-9166-reflex-otel-3from
farhan/eng-9166-reflex-otel-4
Open

ENG-9166 feat(otel): browser tracing plugin — traceparent per event, web vitals, render timing (3/3)#6901
FarhanAliRaza wants to merge 5 commits into
farhan/eng-9166-reflex-otel-3from
farhan/eng-9166-reflex-otel-4

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Part of #6227 (ENG-9166). Stack: 1/32/33/3 (this). Base is farhan/eng-9166-reflex-otel-3; the diff is the two commits on top of 2/3.

What

reflex_otel.OtelPlugin (add to rx.Config(plugins=[...])) compiles a small OpenTelemetry web bundle into the frontend:

  • every event sent to the backend gets a PRODUCER span and a W3C traceparent, so one user interaction is one trace: browser → backend SERVER event → chained INTERNAL events;
  • web vitals (web_vital.LCP/CLS/INP/FCP/TTFB) as spans with value/rating attributes;
  • socket.connect / socket.disconnect spans (unintentional disconnects marked ERROR);
  • opt-in render_timing=True: react.render span per React commit via a root <Profiler>; the plugin aliases react-dom/client → react-dom/profiling in vite.config.js because <Profiler> is a no-op in production builds otherwise. Off by default (span volume). Verified in a --env prod build.

Wiring: get_frontend_dependencies (pinned @opentelemetry/*, web-vitals), get_static_assets (utils/otel.js), update_env_json (OTEL entry: endpoint, service name, headers, flags), add_modify_task on entry.client.js (import + root wrap). Endpoint defaults follow OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / OTEL_EXPORTER_OTLP_ENDPOINT/v1/traces; must allow CORS. headers are compiled into the public bundle (documented).

Framework seam: state.js calls window.__reflex_otel?.onEventSend/onSocketConnect/onSocketDisconnect — undefined unless the plugin is active.

Docs: new docs/api-reference/observability.md (backend + frontend setup, hot-reload-safe guard, metrics table). Log correlation is out of this stack (follow-up: #6903).

Known limitation: the browser has no per-event completion signal, so the browser event span has no duration; it exists to carry the trace context.

Tests

tests/units/reflex_otel/test_plugin.py (env/endpoint resolution, asset, env.json, entry patch idempotency + warning, profiling alias patch).

Review in cubic

@FarhanAliRaza
FarhanAliRaza requested review from a team and Alek99 as code owners August 17, 2026 20:58
@linear-code

linear-code Bot commented Aug 17, 2026

Copy link
Copy Markdown

ENG-9166

@codspeed-hq

codspeed-hq Bot commented Aug 17, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing farhan/eng-9166-reflex-otel-4 (4e1d604) with farhan/eng-9166-reflex-otel-3 (7427498)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds opt-in browser OpenTelemetry instrumentation and wires it into the generated frontend event and socket lifecycle.

  • Adds per-event trace-context propagation, web-vital spans, socket lifecycle spans, and optional React render timing.
  • Adds compile-time plugin configuration, frontend dependencies, entry-point wrapping, and production profiling alias support.
  • Documents frontend observability setup and adds unit coverage for plugin configuration and source patching.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/.templates/web/utils/state.js Adds optional frontend telemetry callbacks around event sending and socket connect/disconnect handling; no eligible unresolved follow-up issue remains.
packages/reflex-otel/src/reflex_otel/otel.js Implements browser tracing, web-vital reporting, socket spans, and optional React Profiler spans.
packages/reflex-otel/src/reflex_otel/plugin.py Adds the compile-time plugin, validated sampling configuration, frontend assets and dependencies, environment data, and source patching.
tests/units/reflex_otel/test_plugin.py Covers endpoint resolution, generated configuration, static assets, entry patching, profiling aliasing, idempotency, and sampling validation.
docs/api-reference/observability.md Documents backend and browser OpenTelemetry setup, emitted telemetry, defaults, sampling, and public-header constraints.

Reviews (7): Last reviewed commit: "fix(otel): reject out-of-range sample_ra..." | Re-trigger Greptile

Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/state.js

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 81df35005c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/state.js
Comment thread packages/reflex-otel/src/reflex_otel/plugin.py

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 11 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/reflex-otel/src/reflex_otel/plugin.py Outdated
Comment thread packages/reflex-otel/src/reflex_otel/plugin.py
Comment thread tests/units/reflex_otel/test_plugin.py

@Alek99 Alek99 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The browser → backend → chained-event parentage, production render spans, FCP, and TTFB all worked in a local Reflex app. These remaining browser-policy/lifecycle issues are not covered by the happy path.

Comment thread packages/reflex-otel/src/reflex_otel/otel.js
Comment thread packages/reflex-otel/src/reflex_otel/otel.js Outdated
Comment thread packages/reflex-otel/src/reflex_otel/otel.js
@FarhanAliRaza
FarhanAliRaza force-pushed the farhan/eng-9166-reflex-otel-4 branch from e8571d8 to d3bfbe1 Compare August 18, 2026 16:54

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 4 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/reflex-otel/src/reflex_otel/plugin.py
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