app

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

commit e9efb1e8a8eb3038c83cfa4c1810229dcdf40d7d
parent ae1009c9680ad49302c35d090a1beaa513cdd1ef
Author: triesap <triesap@radroots.dev>
Date:   Tue, 20 Jan 2026 14:36:13 +0000

app: log health check errors

- emit error-level entries for failed health checks

- keep debug start/end entries for successful checks

- add health log entry helper for consistent context

- add unit test for error log formatting

Diffstat:
Mapp/src/health.rs | 30+++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/app/src/health.rs b/app/src/health.rs @@ -85,24 +85,36 @@ use crate::{ app_datastore_key_nostr_key, app_datastore_read_app_data, app_log_debug_emit, + app_log_entry_new, + app_log_entry_record, app_key_maps_validate, AppNotifications, + AppLogLevel, AppTangleClient, AppKeyMapConfig, }; use radroots_app_core::datastore::{RadrootsClientDatastore, RadrootsClientDatastoreError}; use radroots_app_core::keystore::{RadrootsClientKeystoreError, RadrootsClientKeystoreNostr}; +fn log_health_context(result: &AppHealthCheckResult) -> Option<String> { + match result.message.as_deref() { + Some(message) => Some(format!("status={},detail={message}", result.status.as_str())), + None => Some(format!("status={}", result.status.as_str())), + } +} + fn log_health_start(name: &str) { let _ = app_log_debug_emit("log.app.health.start", name, None); } fn log_health_end(name: &str, result: &AppHealthCheckResult) { - let context = match result.message.as_deref() { - Some(message) => Some(format!("status={},detail={message}", result.status.as_str())), - None => Some(format!("status={}", result.status.as_str())), - }; - let _ = app_log_debug_emit("log.app.health.end", name, context); + let context = log_health_context(result); + if result.status == AppHealthCheckStatus::Error { + let entry = app_log_entry_new(AppLogLevel::Error, "log.app.health.end", name, context); + let _ = app_log_entry_record(entry); + } else { + let _ = app_log_debug_emit("log.app.health.end", name, context); + } } pub fn app_health_check_key_maps(key_maps: &AppKeyMapConfig) -> AppHealthCheckResult { @@ -283,6 +295,7 @@ mod tests { app_health_check_keystore_access, app_health_check_notifications, app_health_check_tangle, + log_health_context, AppHealthCheckResult, AppHealthCheckStatus, AppHealthReport, @@ -325,6 +338,13 @@ mod tests { } #[test] + fn health_log_context_formats_error_detail() { + let result = AppHealthCheckResult::error("missing"); + let context = log_health_context(&result); + assert_eq!(context.as_deref(), Some("status=error,detail=missing")); + } + + #[test] fn health_report_defaults_skipped() { let report = AppHealthReport::default(); assert_eq!(report.key_maps.status, AppHealthCheckStatus::Skipped);