Skip to content

moq-ffi: route Android logs to logcat#1541

Merged
kixelated merged 3 commits into
moq-dev:mainfrom
Qizot:android-logger
May 30, 2026
Merged

moq-ffi: route Android logs to logcat#1541
kixelated merged 3 commits into
moq-dev:mainfrom
Qizot:android-logger

Conversation

@Qizot
Copy link
Copy Markdown
Contributor

@Qizot Qizot commented May 29, 2026

While on iOS the logs can be inspected in xcode the same thing can't be said about android. For this particular usecase, this PR adds support for a android locat tracing subscriber so the logs are properly routed and can be inspected using ADB or Android Studio (both using logcat).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 49c7b66c-8704-424b-a161-59d95e64ccf7

📥 Commits

Reviewing files that changed from the base of the PR and between 7327400 and 56b934f.

📒 Files selected for processing (1)
  • rs/moq-native/src/log.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • rs/moq-native/src/log.rs

Walkthrough

This PR adds an android-logcat feature in Cargo manifests and makes moq-native's Log::init return anyhow::Result<()>, initializing a tracing_android layer on Android when enabled or a stderr fmt layer otherwise. moq-ffi's moq_log_level now parses the level string, calls moq_native::Log::new(level).init(), and restores its initialization guard on failure. libmoq and multiple examples/binaries (hang, native examples, moq-boy, moq-cli, moq-relay) were updated to propagate logging initialization errors using ?.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'moq-ffi: route Android logs to logcat' accurately and clearly summarizes the main change: adding Android logcat support to moq-ffi for log inspection.
Description check ✅ Passed The description is directly related to the changeset, explaining the motivation (Android logs can't be inspected like iOS logs in Xcode) and the solution (Android logcat tracing subscriber support).
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
rs/moq-ffi/src/log.rs (1)

53-53: ⚡ Quick win

Use try_init() instead of init() for the Android tracing subscriber to avoid panicking when a global subscriber is already set.

SubscriberInitExt::init() panics if a global subscriber is already installed; try_init() returns an error you can map into MoqError::Log. The crate-level AtomicBool in moq_log_level only prevents re-calling moq_log_level, not initialization performed by the host before this function runs.

♻️ Proposed change
-	tracing_subscriber::registry().with(logcat_layer).init();
-
-	Ok(())
+	tracing_subscriber::registry()
+		.with(logcat_layer)
+		.try_init()
+		.map_err(|err| MoqError::Log(format!("failed to install tracing subscriber: {err}")))?;
+
+	Ok(())
🤖 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 `@rs/moq-ffi/src/log.rs` at line 53, The call to
tracing_subscriber::registry().with(logcat_layer).init() can panic if a global
subscriber is already set; change this to use SubscriberInitExt::try_init()
(i.e. tracing_subscriber::registry().with(logcat_layer).try_init()) and
map/propagate the returned Err into MoqError::Log so initialization failures
become a handled error instead of a panic; keep existing guard logic
(moq_log_level AtomicBool) but do not rely on it to prevent host-installed
subscribers.
🤖 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 `@rs/moq-ffi/src/log.rs`:
- Around line 20-26: The code sets INITIALIZED to true before calling
init_logging, which permanently blocks retries if init_logging fails; change the
flow so that either (a) set INITIALIZED only after init_logging returns Ok (use
INITIALIZED.store(true, Ordering::SeqCst) after successful init) or (b) if you
keep the current swap/check pattern, ensure you reset the flag on failure by
calling INITIALIZED.store(false, Ordering::SeqCst) before returning the Err from
init_logging; update the branch around INITIALIZED.swap(true, Ordering::SeqCst)
and the init_logging(level)? error path (referencing INITIALIZED, init_logging,
Ordering::SeqCst, and MoqError::Log) so the flag reflects the real initialized
state.

---

Nitpick comments:
In `@rs/moq-ffi/src/log.rs`:
- Line 53: The call to tracing_subscriber::registry().with(logcat_layer).init()
can panic if a global subscriber is already set; change this to use
SubscriberInitExt::try_init() (i.e.
tracing_subscriber::registry().with(logcat_layer).try_init()) and map/propagate
the returned Err into MoqError::Log so initialization failures become a handled
error instead of a panic; keep existing guard logic (moq_log_level AtomicBool)
but do not rely on it to prevent host-installed subscribers.
🪄 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: a1087238-d5d4-4266-9608-616e77a62fb9

📥 Commits

Reviewing files that changed from the base of the PR and between ab08b0c and 6585ff4.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • rs/moq-ffi/Cargo.toml
  • rs/moq-ffi/src/log.rs

Comment thread rs/moq-ffi/src/log.rs
Comment thread rs/moq-ffi/src/log.rs Outdated
Comment on lines +29 to +30
#[cfg(all(target_os = "android", feature = "android-logcat"))]
fn init_logging(level: Level) -> Result<(), MoqError> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should this be in moq-native instead?

Comment thread rs/moq-ffi/src/log.rs Outdated
Comment on lines +49 to +51
let logcat_layer = tracing_android::layer("MoQNative")
.map_err(|err| MoqError::Log(format!("failed to initialize Android logcat layer: {err}")))?
.with_filter(filter);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we move this to moq-native, this is the #[cfg] gate, while the rest is shared.

kixelated and others added 2 commits May 29, 2026 20:34
Per review, the Android-specific logging belongs in moq-native rather than
moq-ffi. The EnvFilter setup is now shared, and only the layer (logcat on
Android, stderr fmt elsewhere) is behind the cfg gate. moq-ffi's
android-logcat feature forwards to moq-native.

Log::init now returns a Result so the logcat layer's initialization error
propagates instead of being swallowed, and moq_log_level resets its
INITIALIZED guard when init fails so a transient failure doesn't permanently
block retries.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the directive .parse().unwrap() calls with ? and swap registry.init()
for try_init(), so a parse error or an already-set global subscriber surfaces
as an error instead of panicking.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@kixelated kixelated enabled auto-merge (squash) May 30, 2026 04:07
@kixelated kixelated merged commit 1982dd4 into moq-dev:main May 30, 2026
2 checks passed
@moq-bot moq-bot Bot mentioned this pull request May 30, 2026
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