Skip to content

feat: add console logger module - #109

Open
MaxMichel2 wants to merge 9 commits into
mainfrom
feat/console-logger-module
Open

feat: add console logger module#109
MaxMichel2 wants to merge 9 commits into
mainfrom
feat/console-logger-module

Conversation

@MaxMichel2

Copy link
Copy Markdown
Collaborator

Summary

  • Adds devview-consolelogger: an in-app viewer for the device's native console output (logcat on Android, a stdout/stderr redirect on iOS), with per-level filter chips, text search, and auto-follow — closes Console Logger Module #41.
  • Native capture works on an untethered device on both platforms (no debugger required), which was the key requirement — see the capture matrix and the one known gap (NSLog/os_log on iOS with no debugger) in docs/modules/consolelogger.md.
  • An optional DevViewLogWriter routes Kermit-based logging into the same view, closing that iOS gap for apps that log through Kermit.
  • Log-level colors are a fixed, hand-tuned palette (ported from a prior Android-only implementation) overridable via a LocalLogColorScheme CompositionLocal at the host's theme site, with a warn-once + theme-luminance fallback.
  • Wired into the sample app and documented (module page, theming guide, module CLAUDE.md, README, CHANGELOG).

Test plan

  • :devview-consolelogger:testAndroidHostTest — 16 unit tests pass (sink ring-buffer eviction, logcat line parsing, Kermit severity mapping, module metadata, color scheme lookup/copy)
  • :konsist:test — architecture rules pass
  • detektFull — clean project-wide
  • :sample:androidApp:assembleDebug — builds successfully
  • :devview-consolelogger:metalavaGenerateSignature — API surface recorded in devview-consolelogger/api/api.txt
  • CI ios-build job (compileKotlinIosArm64 iosSimulatorArm64Test) — the iOS actual (posix pipe redirect) can't be compiled from this Windows dev machine; needs the macos-26 CI runner to verify
  • Android instrumented tests (connectedAndroidDeviceTest) — no emulator/device available locally
  • Manual on-device verification (Android + iOS, tethered and untethered) — see docs/modules/consolelogger.md

🤖 Generated with Claude Code

@MaxMichel2 MaxMichel2 self-assigned this Sep 8, 2026
@MaxMichel2 MaxMichel2 added the enhancement New feature or request label Sep 8, 2026
@MaxMichel2 MaxMichel2 added this to the 0.2.0 milestone Sep 8, 2026
matthiaslao
matthiaslao previously approved these changes Sep 8, 2026
Registers the new module (settings.gradle.kts), wires it into
devview's Kover coverage aggregation and internal/dokka's API doc
aggregation (mirrors devview-timecapsule's build setup), and
allowlists the module's two new CompositionLocals for Detekt's
compose-rules CompositionLocalAllowlist check. Part of issue #41
(Console Logger module).
ConsoleLogger is the bounded, drop-oldest sink: log() writes into a
Channel so it is safe to call from background capture threads, and a
single collector drains it into the retained SnapshotStateList,
evicting from the head past maxEntries. This bounds memory under a
logcat-speed firehose, unlike a naive unbounded mutableStateListOf.

Native capture is untethered-safe on both platforms:
- Android tails `logcat --pid=<self>` (parsed by parseLogcatLine,
  falling back to UNKNOWN rather than dropping unparseable lines).
- iOS redirects stdout/stderr through an in-process posix pipe,
  teeing bytes back to the original fd so Xcode's console is
  unaffected when tethered, and marks the write end O_NONBLOCK so a
  stalled reader drops lines instead of hanging the host app.

DevViewLogWriter is an optional Kermit LogWriter that forwards
structured log calls into the same sink — the one reliable way to
capture logging on an iOS device with no debugger attached, since
NSLog/os_log bypass the stdout/stderr redirect entirely.

Part of issue #41 (Console Logger module).
Ports the light/dark log-level palettes verbatim from the prior
Android-only implementation (28 hand-tuned colors covering all seven
LogLevel entries), restructured from flat properties into a
LogColorScheme.get(level) lookup.

Palette selection is a LocalLogColorScheme CompositionLocal provided
at the host app's theme site, not a Console constructor parameter:
rememberModules() runs before the host's dark-mode state is readable
in the sample app, and a constructor param would be captured once
rather than staying reactive to a runtime theme toggle. When not
provided, rememberLogColorScheme() logs a one-time warning and falls
back to a palette guessed from the ambient MaterialTheme's surface
luminance (not isSystemInDarkTheme(), since DevView's theme can be
driven by something other than the system setting).
ConsoleScreen renders the captured log list: per-LogLevel filter
chips (no chip selected shows everything), a text filter over
tag/message, and auto-follow that disables on manual scroll with a
FAB to jump back to the latest entry and resume — the one piece of
the prior Android-only screen worth carrying over verbatim, since a
console needs to tail.

Console is the Module entry point (Section.LOGGING), wiring
ConsoleLogger's channel drain and the platform capture coroutine
together in initModule(), with a Clear action on the top app bar.
Capture failures are isolated in their own coroutine so a crash
there (e.g. an OEM ROM blocking logcat) can't take down the log
drain job running alongside it.

Part of issue #41 (Console Logger module).
commonTest: ring-buffer eviction and clear() on ConsoleLogger, every
logcat priority prefix and the UNKNOWN fallback in LogcatLine,
Severity->LogLevel mapping and throwable formatting in
DevViewLogWriter, Console module metadata/actions, and
LogColorScheme's per-level lookup and copy() overriding.

androidDeviceTest: ConsoleScreen empty state, text filter + clear,
level-chip filtering, and rememberLogColorScheme()'s resolution
(explicit CompositionLocal honoured; falls back by theme luminance
when not provided).

Part of issue #41 (Console Logger module).
Registers Console() alongside the other DevView modules, provides
LocalConsoleLogs next to the existing LocalAnalytics/LocalFeatureHandler
locals, and provides LocalLogColorScheme (driven by the existing
darkMode feature flag) inside MaterialTheme so the console palette
tracks the sample's own theme toggle. Also registers DevViewLogWriter
once via a LaunchedEffect so sample:network's Kermit-based HTTP
logging shows up in the Console screen too.

Part of issue #41 (Console Logger module).
Adds docs/modules/consolelogger.md (capture matrix, API, theming
pointer) following the timecapsule.md template, links it from
docs/modules/index.md and zensical.toml, and adds a "Console Log
Level Colors" section to the theming guide covering
LocalLogColorScheme and the warn-once fallback.

Adds devview-consolelogger/CLAUDE.md (module guide, including the
Platform-Specific Code section — the first feature module with real
androidMain/iosMain source sets), updates README.md's installation
snippet/module table/quick-setup section, and records the initial
CHANGELOG.md entry and generated api/api.txt.

Part of issue #41 (Console Logger module).
CI previously failed compileKotlinIosArm64 with Dispatchers.IO reported
as internal in kotlinx.coroutines.Dispatchers for iosArm64, but a local
Windows cross-compile of the same code/dependency version succeeds
without error. Deferring to the macos-26 CI runner to confirm whether
this is still an issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Console Logger Module

2 participants