Skip to content

feat(telemetry): emit compile events with page/component/state breakdown#6507

Open
FarhanAliRaza wants to merge 4 commits into
reflex-dev:mainfrom
FarhanAliRaza:compile-events
Open

feat(telemetry): emit compile events with page/component/state breakdown#6507
FarhanAliRaza wants to merge 4 commits into
reflex-dev:mainfrom
FarhanAliRaza:compile-events

Conversation

@FarhanAliRaza
Copy link
Copy Markdown
Contributor

@FarhanAliRaza FarhanAliRaza commented May 14, 2026

Capture per-compile telemetry (trigger, duration, page/component/state counts, plugin usage, sanitized exception) so we can see how Reflex apps are actually built. Backend-only and short-circuited compiles are excluded so the event tracks real frontend builds.

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Capture per-compile telemetry (trigger, duration, page/component/state
counts, plugin usage, sanitized exception) so we can see how Reflex apps
are actually built. Backend-only and short-circuited compiles are
excluded so the event tracks real frontend builds.
@FarhanAliRaza FarhanAliRaza requested a review from a team as a code owner May 14, 2026 11:56
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 14, 2026

Merging this PR will not alter performance

✅ 24 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing FarhanAliRaza:compile-events (3f6b004) with main (c3c720f)2

Open in CodSpeed

Footnotes

  1. 2 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.

  2. No successful run was found on main (39c74cb) during the generation of this report, so c3c720f was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR adds a compile telemetry event to PostHog that captures per-build metadata (trigger, duration, page/component/state counts, plugin usage, and sanitized exception class). Two new modules handle the context (telemetry_context.py) and payload assembly (telemetry_accounting.py), and compiler.compile_app is changed from -> None to -> bool so backend-only short-circuit paths can suppress the event.

  • TelemetryContext is a frozen dataclass that uses a ContextVar to bind the active compile context; set_exception and mutable features_used are intentionally accessible despite frozen=True.
  • _prepare_event in telemetry.py is also fixed to shallow-copy the cached default properties before merging kwargs, eliminating a pre-existing mutation bug.
  • features_used is wired into the payload schema and tested, but no code in this PR actually writes to it during compilation, so every emitted event will report \"features_used\": {}.

Confidence Score: 4/5

Safe to merge; telemetry errors are fully swallowed so the new code cannot affect compilation outcomes.

The change is well-structured and well-tested. The main gap is that features_used is defined, exposed in the schema, and tested with manual population, but nothing in this PR actually writes to it during a real compile. Additionally, hot-reload recompilations will emit trigger:null since no hot_reload variant exists in CompileTrigger.

reflex/utils/telemetry_context.py (missing hot_reload trigger variant, missing unit comment) and reflex/utils/telemetry_accounting.py (features_used always empty).

Important Files Changed

Filename Overview
reflex/utils/telemetry_context.py New frozen dataclass wrapping a ContextVar-based compile context; set_exception correctly bypasses frozen enforcement via object.setattr; elapsed_ms missing a unit comment per team convention; CompileTrigger missing a hot_reload variant.
reflex/utils/telemetry_accounting.py New module building the compile-event payload; record_compile correctly swallows errors so telemetry never breaks builds; features_used collection is wired up but nothing in this PR populates the dict, so it will always be empty.
reflex/app.py _compile now branches on TelemetryContext.start(); exception path correctly sets did_real_compile=True before re-raising; telemetry disabled path preserves existing behavior.
reflex/compiler/compiler.py compile_app return type changed from None to bool; False for short-circuit paths, True for real frontend compiles; straightforward and correct.
reflex/utils/telemetry.py Adds a properties kwarg to _prepare_event/_send/send and fixes a pre-existing mutation bug where kwargs were written directly into the cached event_data properties dict; now makes a shallow copy first.
reflex/utils/prerequisites.py trigger parameter threaded through get_compiled_app and compile_or_validate_app; mechanical plumbing, no logic changes.
tests/units/test_app.py Four new tests covering telemetry enabled/disabled, exception capture, and short-circuit suppression; well-structured and cover the key branches.
tests/units/utils/test_telemetry_accounting.py Comprehensive unit tests for all accounting helpers; notably tests exception sanitization, depth hierarchy, and snapshot immunity of features_used.
tests/units/utils/test_telemetry_context.py Tests nested context entry/exit, identity equality required by BaseContext, get() returning None before entry, and set_exception on frozen dataclass; thorough coverage.

Reviews (1): Last reviewed commit: "feat(telemetry): emit compile events wit..." | Re-trigger Greptile

Comment thread reflex/utils/telemetry_context.py Outdated
Comment thread reflex/utils/telemetry_accounting.py
Comment thread reflex/utils/telemetry_context.py Outdated
FarhanAliRaza and others added 3 commits May 14, 2026 17:06
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Dev backend workers re-run App.__call__ on each uvicorn/granian reload. A
marker file under the web dir, written after the first worker boot, lets
subsequent compiles in the same dev session report as hot_reload instead
of backend_startup.
…unting

- Consolidate dev backend reload-marker handling into a single
  ``get_backend_compile_trigger`` that atomically claims the marker, so a
  failed first compile is still treated as backend_startup on the retry.
- Bucket memo wrappers under the user-authored component via
  ``_wrapped_component_type`` to keep telemetry cardinality bounded.
- Skip framework-internal states when walking the state tree but descend
  through them so user subclasses (e.g. ``SharedState``) still surface.
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.

1 participant