diff options
| author | Brendan Allan <[email protected]> | 2026-02-11 19:36:27 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-11 11:36:27 +0000 |
| commit | a25b2af05aa4fe0cc2bc3474a0b5e23eca3efe4f (patch) | |
| tree | 0097ed5f15eb009b3ab1f5d235884d4733283166 /packages/desktop/src-tauri/src/lib.rs | |
| parent | 8bfd6fdba2490aa41ef9533e3301f0272711d489 (diff) | |
| download | opencode-a25b2af05aa4fe0cc2bc3474a0b5e23eca3efe4f.tar.gz opencode-a25b2af05aa4fe0cc2bc3474a0b5e23eca3efe4f.zip | |
desktop: use tracing for logging (#13135)
Diffstat (limited to 'packages/desktop/src-tauri/src/lib.rs')
| -rw-r--r-- | packages/desktop/src-tauri/src/lib.rs | 83 |
1 files changed, 37 insertions, 46 deletions
diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs index 3e7902804..2c570b7a7 100644 --- a/packages/desktop/src-tauri/src/lib.rs +++ b/packages/desktop/src-tauri/src/lib.rs @@ -4,6 +4,7 @@ mod constants; mod job_object; #[cfg(target_os = "linux")] pub mod linux_display; +mod logging; mod markdown; mod server; mod window_customizer; @@ -16,7 +17,6 @@ use futures::{ #[cfg(windows)] use job_object::*; use std::{ - collections::VecDeque, env, net::TcpListener, path::PathBuf, @@ -85,14 +85,11 @@ impl ServerState { } } -#[derive(Clone)] -struct LogState(Arc<Mutex<VecDeque<String>>>); - #[tauri::command] #[specta::specta] fn kill_sidecar(app: AppHandle) { let Some(server_state) = app.try_state::<ServerState>() else { - println!("Server not running"); + tracing::info!("Server not running"); return; }; @@ -102,24 +99,17 @@ fn kill_sidecar(app: AppHandle) { .expect("Failed to acquire mutex lock") .take() else { - println!("Server state missing"); + tracing::info!("Server state missing"); return; }; let _ = server_state.kill(); - println!("Killed server"); + tracing::info!("Killed server"); } -async fn get_logs(app: AppHandle) -> Result<String, String> { - let log_state = app.try_state::<LogState>().ok_or("Log state not found")?; - - let logs = log_state - .0 - .lock() - .map_err(|_| "Failed to acquire log lock")?; - - Ok(logs.iter().cloned().collect::<Vec<_>>().join("")) +fn get_logs() -> String { + logging::tail() } #[tauri::command] @@ -715,10 +705,18 @@ pub fn run() { .plugin(tauri_plugin_decorum::init()) .invoke_handler(builder.invoke_handler()) .setup(move |app| { - let app = app.handle().clone(); + let handle = app.handle().clone(); + + let log_dir = app + .path() + .app_log_dir() + .expect("failed to resolve app log dir"); + // Hold the guard in managed state so it lives for the app's lifetime, + // ensuring all buffered logs are flushed on shutdown. + handle.manage(logging::init(&log_dir)); - builder.mount_events(&app); - tauri::async_runtime::spawn(initialize(app)); + builder.mount_events(&handle); + tauri::async_runtime::spawn(initialize(handle)); Ok(()) }); @@ -732,7 +730,7 @@ pub fn run() { .expect("error while running tauri application") .run(|app, event| { if let RunEvent::Exit = event { - println!("Received Exit"); + tracing::info!("Received Exit"); kill_sidecar(app.clone()); } @@ -780,9 +778,8 @@ fn test_export_types() { #[derive(tauri_specta::Event, serde::Deserialize, specta::Type)] struct LoadingWindowComplete; -// #[tracing::instrument(skip_all)] async fn initialize(app: AppHandle) { - println!("Initializing app"); + tracing::info!("Initializing app"); let (init_tx, init_rx) = watch::channel(InitStep::ServerWaiting); @@ -795,7 +792,7 @@ async fn initialize(app: AppHandle) { let loading_window_complete = event_once_fut::<LoadingWindowComplete>(&app); - println!("Main and loading windows created"); + tracing::info!("Main and loading windows created"); let sqlite_enabled = option_env!("OPENCODE_SQLITE").is_some(); @@ -806,7 +803,7 @@ async fn initialize(app: AppHandle) { async move { let mut sqlite_exists = sqlite_file_exists(); - println!("Setting up server connection"); + tracing::info!("Setting up server connection"); let server_connection = setup_server_connection(app.clone()).await; // we delay spawning this future so that the timeout is created lazily @@ -831,16 +828,13 @@ async fn initialize(app: AppHandle) { if let Some(err) = err { let _ = child.kill(); - let logs = get_logs(app.clone()) - .await - .unwrap_or_else(|e| format!("[DESKTOP] Failed to read sidecar logs: {e}\n")); - return Err(format!( - "Failed to spawn OpenCode Server ({err}). Logs:\n{logs}" + "Failed to spawn OpenCode Server ({err}). Logs:\n{}", + get_logs() )); } - println!("CLI health check OK"); + tracing::info!("CLI health check OK"); #[cfg(windows)] { @@ -868,11 +862,11 @@ async fn initialize(app: AppHandle) { if let Some(cli_health_check) = cli_health_check { if sqlite_enabled { - println!("Does sqlite file exist: {sqlite_exists}"); + tracing::debug!(sqlite_exists, "Checking sqlite file existence"); if !sqlite_exists { - println!( - "Sqlite file not found at {}, waiting for it to be generated", - opencode_db_path().expect("failed to get db path").display() + tracing::info!( + path = %opencode_db_path().expect("failed to get db path").display(), + "Sqlite file not found, waiting for it to be generated" ); let _ = init_tx.send(InitStep::SqliteWaiting); @@ -897,7 +891,7 @@ async fn initialize(app: AppHandle) { .await .is_err() { - println!("Loading task timed out, showing loading window"); + tracing::debug!("Loading task timed out, showing loading window"); let app = app.clone(); let loading_window = LoadingWindow::create(&app).expect("Failed to create loading window"); sleep(Duration::from_secs(1)).await; @@ -910,14 +904,14 @@ async fn initialize(app: AppHandle) { let _ = loading_task.await; - println!("Loading done, completing initialisation"); + tracing::info!("Loading done, completing initialisation"); let _ = init_tx.send(InitStep::Done); if loading_window.is_some() { loading_window_complete.await; - println!("Loading window completed"); + tracing::info!("Loading window completed"); } MainWindow::create(&app).expect("Failed to create main window"); @@ -931,9 +925,6 @@ fn setup_app(app: &tauri::AppHandle, init_rx: watch::Receiver<InitStep>) { #[cfg(any(target_os = "linux", all(debug_assertions, windows)))] app.deep_link().register_all().ok(); - // Initialize log state - app.manage(LogState(Arc::new(Mutex::new(VecDeque::new())))); - #[cfg(windows)] app.manage(JobObjectState::new()); @@ -943,7 +934,7 @@ fn setup_app(app: &tauri::AppHandle, init_rx: watch::Receiver<InitStep>) { fn spawn_cli_sync_task(app: AppHandle) { tokio::spawn(async move { if let Err(e) = sync_cli(app) { - eprintln!("Failed to sync CLI: {e}"); + tracing::error!("Failed to sync CLI: {e}"); } }); } @@ -963,12 +954,12 @@ enum ServerConnection { async fn setup_server_connection(app: AppHandle) -> ServerConnection { let custom_url = get_saved_server_url(&app).await; - println!("Attempting server connection to custom url: {custom_url:?}"); + tracing::info!(?custom_url, "Attempting server connection"); if let Some(url) = custom_url && server::check_health_or_ask_retry(&app, &url).await { - println!("Connected to custom server: {}", url); + tracing::info!(%url, "Connected to custom server"); return ServerConnection::Existing { url: url.clone() }; } @@ -976,15 +967,15 @@ async fn setup_server_connection(app: AppHandle) -> ServerConnection { let hostname = "127.0.0.1"; let local_url = format!("http://{hostname}:{local_port}"); - println!("Checking health of server '{}'", local_url); + tracing::debug!(url = %local_url, "Checking health of local server"); if server::check_health(&local_url, None).await { - println!("Health check OK, using existing server"); + tracing::info!(url = %local_url, "Health check OK, using existing server"); return ServerConnection::Existing { url: local_url }; } let password = uuid::Uuid::new_v4().to_string(); - println!("Spawning new local server"); + tracing::info!("Spawning new local server"); let (child, health_check) = server::spawn_local_server(app, hostname.to_string(), local_port, password.clone()); |
