Skip to content

ENG-10963 refactor(log): migrate the reflex CLI and runtime to logging (3/5) - #6865

Open
FarhanAliRaza wants to merge 5 commits into
farhan/eng-10963-log-2-migrate-basefrom
farhan/eng-10963-log-3-migrate-core
Open

ENG-10963 refactor(log): migrate the reflex CLI and runtime to logging (3/5)#6865
FarhanAliRaza wants to merge 5 commits into
farhan/eng-10963-log-2-migrate-basefrom
farhan/eng-10963-log-3-migrate-core

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Replaces the console helper call sites with per-module loggers across reflex/, and adds shared click log options in reflex.utils.cli_options including a new --json flag that switches output to JSON-lines records (REFLEX_LOG_JSON equivalent).

Keeps a temporary LogLevel conversion mapper for the hosting CLI boundary; it is removed in the next PR when the enums unify.

Stack (ENG-10963)

#6863#6864 → this → hosting CLI → deprecate.
Merge in order; each PR is based on the previous branch.

Review in cubic

@FarhanAliRaza
FarhanAliRaza requested a review from a team as a code owner August 10, 2026 20:36
@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown

ENG-10963

@greptile-apps

greptile-apps Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Migrates Reflex CLI and runtime output from console helper calls to standard per-module loggers and introduces shared logging options, including JSON-lines output.

  • Replaces console logging calls throughout CLI, compiler, state, runtime, and utility modules.
  • Centralizes Click logging options and managed logging initialization.
  • Preserves machine-readable progress output in JSON mode.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
reflex/utils/cli_options.py Centralizes CLI log-level and JSON output options for reuse across commands.
reflex/reflex.py Initializes managed logging at the CLI boundary and adopts the shared logging options.
reflex/compiler/compiler.py Migrates compiler diagnostics and timing to logging while retaining JSON-compatible progress behavior.
packages/reflex-base/src/reflex_base/utils/console.py The inherited progress implementation routes fallback progress messages through JSON-aware console output.

Reviews (9): Last reviewed commit: "fix(istate): resolve the disk states dir..." | Re-trigger Greptile

Comment thread reflex/compiler/compiler.py
@codspeed-hq

codspeed-hq Bot commented Aug 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
🆕 1 new benchmark
⏩ 8 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Simulation test_import_reflex N/A 4.9 ms N/A

Comparing farhan/eng-10963-log-3-migrate-core (3578b3d) with main (852ef91)2

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.

  2. No successful run was found on farhan/eng-10963-log-2-migrate-base (ee282c1) during the generation of this report, so main (852ef91) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@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: 29505c0626

ℹ️ 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 reflex/reflex.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.

4 issues found across 39 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="reflex/reflex.py">

<violation number="1" location="reflex/reflex.py:96">
P2: The `login` command now exposes `--json` via `@log_options`, but it delegates to `reflex_cli.v2.cli.login()`, which prints through `reflex_cli.utils.console` (Rich's `_console.print`) and never checks the JSON log mode. Running `reflex login --json` will mix plain-text hosting CLI output with JSON-lines records, breaking JSON-lines consumers. Consider bridging/migrating the hosting console before exposing `--json` on hosting-backed commands, or withhold the option there until the hosting CLI is migrated.</violation>

<violation number="2" location="reflex/reflex.py:717">
P2: `reflex db` commands cannot accept the new `--json` flag, so their migrated log output is only JSON-capable through the environment variable. Apply `log_options` to the database subcommands (or provide equivalent group-level options) so CLI JSON output covers this command family.</violation>
</file>

<file name="tests/units/utils/test_utils.py">

<violation number="1" location="tests/units/utils/test_utils.py:790">
P2: This test no longer exercises the debug path it intends to. `output_system_info()` gates its body on `console.is_debug()` (`reflex_base.utils.console.is_debug`), which reads `console._LOG_LEVEL` — not `log._log_level`. The old test patched `reflex_base.utils.console._LOG_LEVEL` directly; the new one patches `reflex_base.utils.log._log_level`, which is a separate module global that only changes when `console.set_log_level()` is called. As a result `console.is_debug()` still returns `False` (default INFO), so `output_system_info()` returns early and the imports/iteration under the debug branch are no longer covered. The test still passes (its only assertion is that it doesn't crash), silently reducing coverage.</violation>
</file>

<file name="reflex/compiler/compiler.py">

<violation number="1" location="reflex/compiler/compiler.py:1191">
P2: When `reflex compile` is run with `--json --no-rich`, `console.PoorProgress()` is selected as the fallback progress renderer, and its `advance` method writes plain-text `Progress: N/M` lines directly to stdout. This mixes non-JSON text into the output stream expected to be JSON-lines, breaking machine parsing for `--json` consumers.</violation>
</file>

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

Re-trigger cubic

Comment thread reflex/reflex.py
Comment thread tests/units/utils/test_utils.py
Comment thread reflex/compiler/compiler.py
Comment thread reflex/reflex.py
Comment thread tests/units/test_app.py Outdated
Comment thread tests/units/test_state.py Outdated
@FarhanAliRaza
FarhanAliRaza force-pushed the farhan/eng-10963-log-3-migrate-core branch from 29505c0 to b3d0c80 Compare August 12, 2026 10:37
masenf
masenf previously approved these changes Aug 18, 2026

@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.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/units/istate/manager/test_disk.py">

<violation number="1" location="tests/units/istate/manager/test_disk.py:24">
P3: The test claims purge resolves against the original directory, but it never verifies that: no .pkl state files are created before the chdir, and `_purge_expired_states()` ends with no assertion, so it is a no-op that would pass regardless of which cwd is used. Add a stale pickle to states_dir before chdir and assert it is removed, to actually cover the regression this PR fixes. Also use `monkeypatch.chdir(tmp_path)` instead of raw `os.chdir(tmp_path)` for consistent cwd restoration.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

assert states_dir.is_absolute()
assert states_dir.is_dir()

os.chdir(tmp_path)

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.

P3: The test claims purge resolves against the original directory, but it never verifies that: no .pkl state files are created before the chdir, and _purge_expired_states() ends with no assertion, so it is a no-op that would pass regardless of which cwd is used. Add a stale pickle to states_dir before chdir and assert it is removed, to actually cover the regression this PR fixes. Also use monkeypatch.chdir(tmp_path) instead of raw os.chdir(tmp_path) for consistent cwd restoration.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/units/istate/manager/test_disk.py, line 24:

<comment>The test claims purge resolves against the original directory, but it never verifies that: no .pkl state files are created before the chdir, and `_purge_expired_states()` ends with no assertion, so it is a no-op that would pass regardless of which cwd is used. Add a stale pickle to states_dir before chdir and assert it is removed, to actually cover the regression this PR fixes. Also use `monkeypatch.chdir(tmp_path)` instead of raw `os.chdir(tmp_path)` for consistent cwd restoration.</comment>

<file context>
@@ -0,0 +1,27 @@
+    assert states_dir.is_absolute()
+    assert states_dir.is_dir()
+
+    os.chdir(tmp_path)
+    assert manager.states_directory == states_dir
+    # Purge resolves against the original directory, not the new cwd.
</file context>

FarhanAliRaza and others added 5 commits August 19, 2026 03:03
Replace console.debug/info/warn/error call sites with per-module
loggers across reflex/, add shared click log options in
reflex.utils.cli_options including a new --json flag that switches
output to JSON-lines records (REFLEX_LOG_JSON equivalent).
- clear the deprecation dedupe set that console.deprecate actually uses in
  the legacy-token state manager test
- scope the app tests' caplog assertions to the reflex.app logger
- name the news fragment after the PR
…of the session

Invoking the real ``cli`` group runs its callback, which sets
REFLEX_MANAGED_LOGGING in os.environ and attaches the sinks for the whole
process. Snapshot the marker with monkeypatch and detach the sinks after
the invocation so later tests (and their subprocesses) start clean.
The default frontend/backend exception handlers now log through the
pipeline. Under AppHarness the backend runs in-process in library mode,
where records propagate to the root logger (pytest's caplog) and nothing
is written to stderr, so the capsys assertions could never match. The
React assertion also carried a line break from rich's console wrapping;
log records are unwrapped.
StateManagerDisk resolved the relative .states path on every call, so a
cwd change after startup (as AppHarness does) made every write-queue
cycle raise FileNotFoundError from _purge_expired_states. Resolve it to
an absolute path in the cached property. Log the expected closed-file
ValueError in AppHarness at debug instead of error.
@FarhanAliRaza
FarhanAliRaza force-pushed the farhan/eng-10963-log-3-migrate-core branch from 2b2e21e to 3578b3d Compare August 18, 2026 22:03
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.

3 participants