ENG-10963 refactor(log): migrate the reflex CLI and runtime to logging (3/5) - #6865
ENG-10963 refactor(log): migrate the reflex CLI and runtime to logging (3/5)#6865FarhanAliRaza wants to merge 5 commits into
Conversation
Greptile SummaryMigrates Reflex CLI and runtime output from console helper calls to standard per-module loggers and introduces shared logging options, including JSON-lines output.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| 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
Merging this PR will not alter performance
Performance Changes
Comparing Footnotes
|
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
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
29505c0 to
b3d0c80
Compare
4ee5fbf to
754dbc5
Compare
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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>
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.
2b2e21e to
3578b3d
Compare
Replaces the console helper call sites with per-module loggers across
reflex/, and adds shared click log options inreflex.utils.cli_optionsincluding a new--jsonflag that switches output to JSON-lines records (REFLEX_LOG_JSONequivalent).Keeps a temporary
LogLevelconversion 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.