@@ -12,7 +12,8 @@ use dialoguer::Confirm;
12use time::OffsetDateTime;
12use time::OffsetDateTime;
13use time::format_description::well_known::Rfc3339;
13use time::format_description::well_known::Rfc3339;
14use tracing_subscriber::filter::LevelFilter;
14use tracing_subscriber::filter::LevelFilter;
15−use tracing_subscriber::{EnvFilter, fmt, prelude::*};
15+use tracing_subscriber::registry::Registry;
16+use tracing_subscriber::{EnvFilter, fmt, prelude::*, reload};
17use vibebox::tui::{AppState, VmInfo};
18use vibebox::tui::{AppState, VmInfo};
18use vibebox::{
19use vibebox::{
@@ -42,7 +43,7 @@ enum Command {
42fn main() -> Result<()> {
43fn main() -> Result<()> {
43 color_eyre::install()?;
44 color_eyre::install()?;
44 let cwd = env::current_dir().map_err(|err| color_eyre::eyre::eyre!(err.to_string()))?;
45 let cwd = env::current_dir().map_err(|err| color_eyre::eyre::eyre!(err.to_string()))?;
45− init_tracing(&cwd);
46+ let stderr_handle = init_tracing(&cwd);
47 let cli = Cli::parse();
48 let cli = Cli::parse();
48 tracing::info!(cwd = %cwd.display(), "starting vibebox cli");
49 tracing::info!(cwd = %cwd.display(), "starting vibebox cli");
@@ -106,6 +107,9 @@ fn main() -> Result<()> {
106 writeln!(stdout)?;
107 writeln!(stdout)?;
107 stdout.flush()?;
108 stdout.flush()?;
110+ if let Some(handle) = stderr_handle {
111+ let _ = handle.modify(|filter| *filter = LevelFilter::INFO);
110 tracing::info!(auto_shutdown_ms, "auto shutdown config");
114 tracing::info!(auto_shutdown_ms, "auto shutdown config");
111 let manager_conn =
115 let manager_conn =
@@ -250,8 +254,11 @@ fn format_last_active(value: Option<&str>) -> String {
250 format!("{} day{} ago", days, if days == 1 { "" } else { "s" })
254 format!("{} day{} ago", days, if days == 1 { "" } else { "s" })
257+type StderrHandle = reload::Handle<LevelFilter, Registry>;
253−fn init_tracing(cwd: &Path) {
259+fn init_tracing(cwd: &Path) -> Option<StderrHandle> {
254 let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
260 let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
261+ let file_filter = filter.clone();
255 let stderr_is_tty = std::io::stderr().is_terminal();
262 let stderr_is_tty = std::io::stderr().is_terminal();
256 let ansi = stderr_is_tty && env::var("VIBEBOX_LOG_NO_COLOR").is_err();
263 let ansi = stderr_is_tty && env::var("VIBEBOX_LOG_NO_COLOR").is_err();
257 let file = instance::ensure_instance_dir(cwd)
264 let file = instance::ensure_instance_dir(cwd)
@@ -267,41 +274,42 @@ fn init_tracing(cwd: &Path) {
269 if stderr_is_tty {
276 if stderr_is_tty {
277+ let (stderr_filter, handle) = reload::Layer::new(LevelFilter::OFF);
270 let stderr_layer = fmt::layer()
278 let stderr_layer = fmt::layer()
271 .with_target(false)
279 .with_target(false)
272 .with_ansi(ansi)
280 .with_ansi(ansi)
273 .without_time()
281 .without_time()
274 .with_writer(std::io::stderr)
282 .with_writer(std::io::stderr)
275− .with_filter(LevelFilter::INFO);
283+ .with_filter(stderr_filter);
276− let subscriber = tracing_subscriber::registry()
284+ let subscriber = tracing_subscriber::registry().with(stderr_layer);
278− .with(stderr_layer);
279 if let Some(file) = file {
285 if let Some(file) = file {
280 let file_layer = fmt::layer()
286 let file_layer = fmt::layer()
281 .with_target(false)
287 .with_target(false)
282 .with_ansi(false)
288 .with_ansi(false)
283− .with_writer(file);
289+ .with_writer(file)
290+ .with_filter(file_filter);
284 let _ = subscriber.with(file_layer).try_init();
291 let _ = subscriber.with(file_layer).try_init();
286 let _ = subscriber.try_init();
293 let _ = subscriber.try_init();
289 let stderr_layer = fmt::layer()
297 let stderr_layer = fmt::layer()
290 .with_target(false)
298 .with_target(false)
291 .with_ansi(ansi)
299 .with_ansi(ansi)
292 .with_writer(std::io::stderr)
300 .with_writer(std::io::stderr)
293− .with_filter(LevelFilter::INFO);
301+ .with_filter(filter);
294− let subscriber = tracing_subscriber::registry()
302+ let subscriber = tracing_subscriber::registry().with(stderr_layer);
296− .with(stderr_layer);
297 if let Some(file) = file {
303 if let Some(file) = file {
298 let file_layer = fmt::layer()
304 let file_layer = fmt::layer()
299 .with_target(false)
305 .with_target(false)
300 .with_ansi(false)
306 .with_ansi(false)
301− .with_writer(file);
307+ .with_writer(file)
308+ .with_filter(file_filter);
302 let _ = subscriber.with(file_layer).try_init();
309 let _ = subscriber.with(file_layer).try_init();
304 let _ = subscriber.try_init();
311 let _ = subscriber.try_init();