app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit d4562290c6f90f43802fece7004fceb0d182699d
parent 4ee4535921f8c39bfbd81836aced5bcb7cfb9ebb
Author: triesap <triesap@radroots.dev>
Date:   Wed, 21 Jan 2026 14:11:58 +0000

app: prepend log dump header

- add dump composer that injects header

- use headered dump for logs UI

- keep empty dump when no entries

- add unit test for dump header

Diffstat:
Mapp/src/logs.rs | 30+++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/app/src/logs.rs b/app/src/logs.rs @@ -16,6 +16,7 @@ use std::rc::Rc; use crate::{ app_context, app_log_buffer_flush_no_prune, + app_log_dump_header, app_log_entries_clear, app_log_entries_dump, app_log_entries_load, @@ -75,6 +76,13 @@ fn log_entry_matches(entry: &RadrootsAppLogEntry, level_filter: &str, query: &st log_level_matches(entry.level, level_filter) && log_query_matches(entry, query) } +fn log_dump_with_header(entries: &[RadrootsAppLogEntry]) -> String { + if entries.is_empty() { + return String::new(); + } + format!("{}\n{}", app_log_dump_header(), app_log_entries_dump(entries)) +} + #[cfg(any(test, target_arch = "wasm32"))] fn log_dump_filename_from_ms(timestamp_ms: i64) -> String { format!("radroots-logs-{timestamp_ms}.jsonl") @@ -169,7 +177,7 @@ pub fn RadrootsAppLogsPage() -> impl IntoView { return err; } let items = filtered_entries.get(); - app_log_entries_dump(&items) + log_dump_with_header(&items) }); let resolve_backends = { let context = Rc::clone(&context); @@ -416,6 +424,7 @@ pub fn RadrootsAppLogsPage() -> impl IntoView { mod tests { use super::{ log_dump_filename_from_ms, + log_dump_with_header, log_entry_matches, logs_auto_refresh_ms, logs_max_visible, @@ -453,4 +462,23 @@ mod tests { assert!(!log_entry_matches(&entry, "error", "hello")); assert!(!log_entry_matches(&entry, "info", "missing")); } + + #[test] + fn log_dump_with_header_prefixes_dump() { + let entry = RadrootsAppLogEntry { + id: String::from("a"), + timestamp_ms: 1, + level: RadrootsAppLogLevel::Info, + code: String::from("log.code.test"), + message: String::from("Hello"), + context: None, + metadata: RadrootsAppLogMetadata::default(), + }; + let dump = log_dump_with_header(&[entry]); + let mut lines = dump.lines(); + let header = lines.next().expect("header"); + assert!(header.contains("radroots_log_dump")); + let entry_line = lines.next().expect("entry"); + assert!(entry_line.contains("\"log.code.test\"")); + } }