Skip to content

Add AdbRunner structured logcat streaming API #12085

Description

@rmarinho

Summary

Add structured logcat streaming to Xamarin.Android.Tools.AdbRunner so the MAUI DevTools CLI can surface device logs to agents and IDEs without consumers parsing raw adb logcat output.

Context

adb logcat is the only way to see app logs from an Android device until the DevFlow agent in the app is up and running. Even after that, system-level logs (ART runtime, app crashes, native binder errors) only appear in logcat. The MAUI DevTools CLI and DevFlow skills currently advise raw adb logcat … as a fallback — see maui-labs#197 audit. We want a typed stream so consumers can filter and emit structured JSON.

Proposed API

namespaceXamarin.Android.Tools;publicpartialclassAdbRunner{/// adb -s <serial> logcat [-v threadtime] [-T 'YYYY-MM-DD HH:mm:ss.SSS' | -d] <filterspec>publicvirtualIAsyncEnumerable<LogcatEntry>LogcatAsync(stringserial,LogcatOptions?options=null,CancellationTokencancellationToken=default);/// adb -s <serial> logcat -c — clear the device log buffer.publicvirtualTaskClearLogcatAsync(stringserial,CancellationTokencancellationToken=default);}publicrecordLogcatOptions(/// Tag/priority filter pairs. Examples: ("MauiDevFlow","V"), ("DOTNET","I"), ("*","W")IReadOnlyList<LogcatFilter>?Filters=null,/// Restrict to a process. When set, runs `adb shell pidof <package>` to resolve PID once.string?PackageName=null,int?Pid=null,/// `-T <epoch|date>`: only entries since this point. Implies `-d` is false.DateTimeOffset?Since=null,/// `-d`: dump existing buffer and exit (no streaming).boolDumpAndExit=false,/// Buffer to read: main, system, crash, events, all.LogcatBufferBuffers=LogcatBuffer.Main|LogcatBuffer.System|LogcatBuffer.Crash);publicrecordLogcatFilter(stringTag,LogcatLevelMinimum);publicenumLogcatLevel{Verbose,Debug,Info,Warning,Error,Fatal,Silent}[Flags]publicenumLogcatBuffer{Main=1,System=2,Radio=4,Events=8,Crash=16,All=Main|System|Radio|Events|Crash}publicrecordLogcatEntry(DateTimeOffsetTimestamp,intPid,intTid,LogcatLevelLevel,stringTag,stringMessage);

Implementation notes:

  • Use -v threadtime format (well-defined columns) and parse line-by-line. Format spec: MM-DD HH:MM:SS.mmm PID TID L tag: message.
  • The async enumerable yields one LogcatEntry per parsed line. Cancellation kills the underlying adb logcat process.
  • When PackageName is set and PID resolution returns nothing, retry once after a short delay (covers app-not-yet-launched). After two failures, throw.
  • ClearLogcatAsync is separate so streaming can resume from a known point.

Consumer

  • MAUI DevTools CLI (dotnet/maui-labs) — maui android device logcat [--package …] [--tag …] [--since …] [--json] with sensible MAUI defaults (tags MauiDevFlow, DOTNET, mono-rt, ART, level Info on the rest). See maui-labs#197 audit.
  • DevFlow agent debugging — pre-agent diagnostics (the agent itself emits structured logs via the HTTP API once up; this gap covers the pre-agent window).
  • Integration test fixtures that need to assert "log line X appeared within Y seconds" without a manual parser.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    android-toolsIssues migrated from dotnet/android-tools / relates to the xamarin-android-tools subtreeneeds-triageIssues that need to be assigned.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions