iris-android-app: keep the app's own log, put it in Copy report, upload it
`app_log` is the platform half: `android_logger` as the logger the ring forwards to, and an optional destination baked in by `build.rs` from `AI_APP_LOG_HOST`/`_PORT`/`_TOKEN` plus the pinned CA -- the same build-time trust boundary the transcript config and the Compose APK's CA already use, so no token is committed and an APK is good for the server that built it. All three or none: two of the three would be a build with nowhere to send its log and no way to say so. `Copy report` now appends the ring to what goes on the clipboard (not to the pane, which is on screen and would be buried) and flushes the uploader first, so the lines are on the server by the time the message describing them arrives. The Diagnostics pane gains two lines: how many lines are held and when the last arrived, and what the uploader last did -- "not tried yet", "failing -- <why>", and "no server configured" are each their own wording, because "nothing is arriving" has three causes that look identical otherwise. Also: the re-emitted lines carry the target `ai_server::client_log`, not a bare `client_log`. `RUST_LOG=ai_server=debug` -- the filter AGENTS.md tells people to run with -- drops a bare target, so every line a phone sent vanished with nothing saying so. Found by running it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
977bdb9ee0
commit
5be9f1baac
10 files changed
+308
-34
No files matched your search
+16
-6
@@ -1417,6 +1417,16 @@ async fn defaults(State(manager): State<Arc<SessionManager>>) -> axum::Json<Defa
|
||||
/// nothing mentions is worse than a rejected batch the client retries.
|
||||
const CLIENT_LOG_MAX_LINES: usize = 500;
|
||||
|
||||
/// The tracing target every re-emitted client line carries.
|
||||
///
|
||||
/// **Under `ai_server::`, deliberately.** A bare `client_log` target is
|
||||
/// filtered out by `RUST_LOG=ai_server=debug` -- the exact filter
|
||||
/// AGENTS.md tells people to run with -- so every line a phone sent would
|
||||
/// vanish with nothing saying so. Under the crate's own path it is on
|
||||
/// wherever the server's own lines are, which is the only filter its
|
||||
/// reader knows about.
|
||||
const CLIENT_LOG_TARGET: &str = "ai_server::client_log";
|
||||
|
||||
/// One line of a client's own log. `at` is that client's clock, not this
|
||||
/// machine's -- see [`client_log`].
|
||||
#[derive(Deserialize)]
|
||||
@@ -1480,22 +1490,22 @@ async fn client_log(axum::Json(body): axum::Json<ClientLogBody>) -> Result<Statu
|
||||
// the line.
|
||||
match line.level.to_ascii_uppercase().as_str() {
|
||||
"ERROR" => {
|
||||
tracing::error!(target: "client_log", "[{source} {at} #{seq}] {target}: {message}")
|
||||
tracing::error!(target: CLIENT_LOG_TARGET, "[{source} {at} #{seq}] {target}: {message}")
|
||||
}
|
||||
"WARN" => {
|
||||
tracing::warn!(target: "client_log", "[{source} {at} #{seq}] {target}: {message}")
|
||||
tracing::warn!(target: CLIENT_LOG_TARGET, "[{source} {at} #{seq}] {target}: {message}")
|
||||
}
|
||||
"DEBUG" => {
|
||||
tracing::debug!(target: "client_log", "[{source} {at} #{seq}] {target}: {message}")
|
||||
tracing::debug!(target: CLIENT_LOG_TARGET, "[{source} {at} #{seq}] {target}: {message}")
|
||||
}
|
||||
"TRACE" => {
|
||||
tracing::trace!(target: "client_log", "[{source} {at} #{seq}] {target}: {message}")
|
||||
tracing::trace!(target: CLIENT_LOG_TARGET, "[{source} {at} #{seq}] {target}: {message}")
|
||||
}
|
||||
"INFO" => {
|
||||
tracing::info!(target: "client_log", "[{source} {at} #{seq}] {target}: {message}")
|
||||
tracing::info!(target: CLIENT_LOG_TARGET, "[{source} {at} #{seq}] {target}: {message}")
|
||||
}
|
||||
other => {
|
||||
tracing::info!(target: "client_log", "[{source} {at} #{seq}] {target}: <{other}> {message}")
|
||||
tracing::info!(target: CLIENT_LOG_TARGET, "[{source} {at} #{seq}] {target}: <{other}> {message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user