The app hands its log to Dev Updater on the phone, not through ai-server
Iris's call once the upload route was working: put it in Dev Updater properly. So the app now exposes its own ring through a ContentProvider at `<applicationId>.devlog` -- Dev Updater's contract, written down in that project's README, not something invented here -- and Dev Updater's phone app reads it on the same device and forwards it to its own build machine. No tunnel, no token, no second enrolment, and any app that server delivers can implement the same and get the same Runtime tab. `DevLogProvider.java` plus `devlog.rs` are the platform glue only: a flat `String[]` across JNI, a `MatrixCursor` on the Java side, and `nativeReady` telling Rust the authority the provider actually registered, so the Diagnostics pane can name somewhere a reader can query rather than composing a guess. `LogRing::newest_seq()` is the one addition in `client-core`: an in-memory ring starts again at zero, so it is what lets a reader notice the process restarted instead of silently skipping everything since. Deleted with it, so there is one mechanism: `client_core::log_upload`, `POST /client-log` on ai-server, the `AI_APP_LOG_*` baking (which left `build.rs` with nothing to do), and the uploader on both Android clients. Kept: the ring, `RingLogger`, `install_process_logger`, and the Diagnostics line -- whose second half is now `devlog provider: content://<authority>`. Verified end to end on this checkout's emulator: iris's own `iris::android::view` startup lines read out of the provider by the shell, forwarded by Dev Updater's Runtime tab, and served back from `GET /apps/android-app/components/app/logs?kind=runtime`. A component whose package has no provider says so in as many words. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
e10582a2cd
commit
06b8a1f4b0
15 files changed
+618
-842
No files matched your search
+19
-12
@@ -46,10 +46,9 @@ scrolling never consults the one in `ViewConfiguration`.
|
||||
## 2026-09-07: `client-core` carries the app's own log
|
||||
|
||||
Not iris itself but the crate beside it, and it is a new public surface an
|
||||
app author will use: `client_core::log_ring` and `client_core::log_upload`.
|
||||
Because Iris's phone has no `logcat`, an app now keeps a bounded copy of
|
||||
its own log and can send it to `ai-server`, where Dev Updater already
|
||||
shows it.
|
||||
app author will use: `client_core::log_ring`. Because Iris's phone has no
|
||||
`logcat`, an app now keeps a bounded copy of its own log and hands it to
|
||||
Dev Updater on the device.
|
||||
|
||||
Before, an app installed a platform logger and that was the end of it:
|
||||
|
||||
@@ -68,17 +67,25 @@ what they saw before:
|
||||
ring.to_text(); // for a report
|
||||
ring.summary(); // "1801 lines held, 12 dropped, last 20:09:24"
|
||||
|
||||
// and, where the app has a server:
|
||||
let upload = LogUpload::spawn(ring.clone(), transport, "iris-bench", Duration::from_secs(10));
|
||||
upload.flush_now(); // what `Copy report` calls
|
||||
upload.status().summary(); // "not tried yet" / "failing -- <why>" / "N lines sent"
|
||||
// and, for whatever hands the log out of the process:
|
||||
let (lines, next) = ring.since(cursor); // inclusive of `cursor`
|
||||
ring.newest_seq(); // None for a ring nothing was written to
|
||||
|
||||
`process_ring` is a deliberate process-global, unusually for this project:
|
||||
`log` already has exactly one backend per process, and a ring passed around
|
||||
as a parameter would be a second answer to "which lines exist". Dropping
|
||||
the `LogUpload` handle stops and joins its thread. The wire format is one
|
||||
new route on `ai-server`, `POST /client-log`; the reasoning and the
|
||||
rejected alternatives are in docs/DECISIONS.md, 2026-09-07.
|
||||
as a parameter would be a second answer to "which lines exist".
|
||||
|
||||
**Amended later the same day.** `client_core::log_upload` and
|
||||
`ai-server`'s `POST /client-log` are **gone** -- an app no longer sends
|
||||
its log anywhere. It exposes it on the device instead, and Dev Updater
|
||||
reads it there: on Android that is a `ContentProvider` at
|
||||
`<applicationId>.devlog`, which is Dev Updater's own contract (its
|
||||
`README.md`, "An app's own log") rather than anything iris-specific.
|
||||
`LogRing::newest_seq()` is the one addition that went with it: a reader
|
||||
holding a cursor uses it to notice the process **restarted**, since the
|
||||
ring is in memory and a new process starts again at sequence zero.
|
||||
The reasoning and the rejected alternatives are in docs/DECISIONS.md,
|
||||
2026-09-07.
|
||||
|
||||
## 2026-09-07: `TextData` no longer bundles a font
|
||||
|
||||
|
||||
Reference in new issue
Block a user