Pipe Android/ADB logs into CLI (#4853)

* Enhance Android log handling in AppBuilder

- Introduced adb_logcat fields to manage Android logcat output.
- Implemented logcat spawning and parsing to differentiate log levels.
- Updated push_stdio method to filter Android logs based on trace settings.
- Added utility functions for retrieving app PID and parsing logcat levels.

* automatic retry to get pid

* pipe RustStdoutStderr as well

* strip logcat prefix

* filter in rust instead

* Refine log filtering in Rust output handling

- Improved log level detection by checking for prefixes after the colon in messages.
- Enhanced filtering to only show logs with standard tracing levels or fatal errors.
- Streamlined the process of stripping logcat metadata while preserving message content.

* cleanup output and kill proc

* capture logs from ios device

* clippy

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Sabin RegmiandJonathan Kelley authored and GitHub committed 2025-10-28 12:35:34 -07:00
1 parent 24df6439ea
commit 6e3f362872
2 files changed
+162 -12

No files matched your search

+37 -1
View File
@@ -337,7 +337,43 @@ impl Output {
/// This will queue the stderr message as a TraceMsg and print it on the next render
/// We'll use the `App` TraceSrc for the msg, and whatever level is provided
pub fn push_stdio(&mut self, bundle: BundleFormat, msg: String, level: Level) {
self.push_log(TraceMsg::text(TraceSrc::App(bundle), level, msg));
match bundle {
// If tracing is disabled, we need to filter out all the noise from Android logcat
BundleFormat::Android if !self.trace => {
// By default (trace off): only show RustStdoutStderr logs with proper log levels
// Filter out raw output like GL bindings, WebView internals, etc.
let is_rust_log = msg.contains("RustStdoutStderr");
let is_fatal = msg.contains("AndroidRuntime") || msg.starts_with('F');
let mut rendered_msg = None;
// If we're not in trace mode, then we need to filter out non-log messages and clean them up
// Only show logs with standard tracing level prefixes (check in the message after the colon)
if is_rust_log {
if let Some(colon_pos) = msg.find(':') {
let content = &msg[colon_pos + 1..];
if content.contains(" TRACE ")
|| content.contains(" DEBUG ")
|| content.contains(" INFO ")
|| content.contains(" WARN ")
|| content.contains(" ERROR ")
{
rendered_msg = Some(content.trim().to_string());
}
}
}
// Always show fatal errors, even if they don't come from Rust logging
if is_fatal {
rendered_msg = Some(msg);
}
if let Some(msg) = rendered_msg {
self.push_log(TraceMsg::text(TraceSrc::App(bundle), level, msg));
}
}
_ => self.push_log(TraceMsg::text(TraceSrc::App(bundle), level, msg)),
}
}
/// Push a message from the websocket to the logs