From a246e5acb64981b70d670f980baa18dc92f1b621 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Thu, 6 Apr 2023 14:49:43 +0200 Subject: [PATCH 1/2] feat(dtmm): Log to file --- crates/dtmm/src/controller/app.rs | 9 ++++++++- crates/dtmm/src/controller/worker.rs | 12 ++++++++++++ crates/dtmm/src/state/delegate.rs | 17 +++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/crates/dtmm/src/controller/app.rs b/crates/dtmm/src/controller/app.rs index 3073b9b..d732801 100644 --- a/crates/dtmm/src/controller/app.rs +++ b/crates/dtmm/src/controller/app.rs @@ -9,7 +9,7 @@ use druid::im::Vector; use druid::{FileInfo, ImageBuf}; use dtmt_shared::ModConfig; use nexusmods::Api as NexusApi; -use tokio::fs::{self, DirEntry}; +use tokio::fs::{self, DirEntry, File}; use tokio_stream::wrappers::ReadDirStream; use tokio_stream::StreamExt; use zip::ZipArchive; @@ -424,6 +424,13 @@ pub(crate) async fn load_initial(path: PathBuf, is_default: bool) -> Result tokio::spawn(async move { + if let Ok(mut f) = OpenOptions::new() + .append(true) + .open(state.data_dir.join("dtmm.log")) + .await + { + let _ = f.write_all(&line).await; + } + }), }; } } diff --git a/crates/dtmm/src/state/delegate.rs b/crates/dtmm/src/state/delegate.rs index 1cf3cda..d5ae042 100644 --- a/crates/dtmm/src/state/delegate.rs +++ b/crates/dtmm/src/state/delegate.rs @@ -92,6 +92,7 @@ pub(crate) enum AsyncAction { SaveSettings(ActionState), CheckUpdates(ActionState), LoadInitial((PathBuf, bool)), + Log((ActionState, Vec)), } pub(crate) struct Delegate { @@ -253,10 +254,22 @@ impl AppDelegate for Delegate { let line = cmd .get(ACTION_LOG) .expect("command type matched but didn't contain the expected value"); + if let Some(line) = line.take() { - let line = String::from_utf8_lossy(&line); - state.log.push_back(ansi_to_rich_text(line.trim())); + { + let line = String::from_utf8_lossy(&line); + state.log.push_back(ansi_to_rich_text(line.trim())); + } + + if self + .sender + .send(AsyncAction::Log((state.clone().into(), line))) + .is_err() + { + tracing::error!("Failed to queue action to add mod"); + } } + Handled::Yes } cmd if cmd.is(ACTION_START_SAVE_SETTINGS) => { -- 2.45.3 From ebe8966c262e14fc782689fb77616944c8a8b5ed Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Thu, 6 Apr 2023 14:54:46 +0200 Subject: [PATCH 2/2] feat(dtmm): Add log level option Closes #12. --- crates/dtmm/src/main.rs | 19 +++++++++++++++---- crates/dtmm/src/util/log.rs | 29 +++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/crates/dtmm/src/main.rs b/crates/dtmm/src/main.rs index 5a6844c..f60bfd8 100644 --- a/crates/dtmm/src/main.rs +++ b/crates/dtmm/src/main.rs @@ -6,10 +6,8 @@ use std::path::PathBuf; use std::sync::Arc; -use clap::command; use clap::parser::ValueSource; -use clap::value_parser; -use clap::Arg; +use clap::{command, value_parser, Arg}; use color_eyre::eyre; use color_eyre::{Report, Result}; use druid::AppLauncher; @@ -19,6 +17,7 @@ use crate::controller::worker::work_thread; use crate::state::AsyncAction; use crate::state::{Delegate, State}; use crate::ui::theme; +use crate::util::log::LogLevel; mod controller; mod state; @@ -46,10 +45,22 @@ fn main() -> Result<()> { .value_parser(value_parser!(PathBuf)) .default_value(default_config_path.to_string_lossy().to_string()), ) + .arg( + Arg::new("log-level") + .long("log-level") + .help("The maximum level of log events to print") + .value_parser(value_parser!(LogLevel)) + .default_value("info"), + ) .get_matches(); let (log_tx, log_rx) = tokio::sync::mpsc::unbounded_channel(); - util::log::create_tracing_subscriber(log_tx); + let level = if matches.value_source("log-level") == Some(ValueSource::DefaultValue) { + None + } else { + matches.get_one::("log-level").cloned() + }; + util::log::create_tracing_subscriber(log_tx, level); let (action_tx, action_rx) = tokio::sync::mpsc::unbounded_channel(); diff --git a/crates/dtmm/src/util/log.rs b/crates/dtmm/src/util/log.rs index 75db550..b01ef5f 100644 --- a/crates/dtmm/src/util/log.rs +++ b/crates/dtmm/src/util/log.rs @@ -1,3 +1,4 @@ +use clap::ValueEnum; use tokio::sync::mpsc::UnboundedSender; use tracing_error::ErrorLayer; use tracing_subscriber::filter::FilterFn; @@ -7,6 +8,28 @@ use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::prelude::*; use tracing_subscriber::EnvFilter; +#[derive(Clone, Copy, ValueEnum)] +pub enum LogLevel { + Trace, + Debug, + Info, + Warn, + Error, +} + +impl From for EnvFilter { + fn from(level: LogLevel) -> Self { + let filter = match level { + LogLevel::Trace => "error,dtmm=trace,sdk=trace", + LogLevel::Debug => "error,dtmm=debug,sdk=debug", + LogLevel::Info => "error,dtmm=info", + LogLevel::Warn => "error,dtmm=warn", + LogLevel::Error => "error", + }; + EnvFilter::new(filter) + } +} + pub struct ChannelWriter { tx: UnboundedSender>, } @@ -32,8 +55,10 @@ impl std::io::Write for ChannelWriter { } } -pub fn create_tracing_subscriber(tx: UnboundedSender>) { - let env_layer = if cfg!(debug_assertions) { +pub fn create_tracing_subscriber(tx: UnboundedSender>, level: Option) { + let env_layer = if let Some(level) = level { + EnvFilter::from(level) + } else if cfg!(debug_assertions) { EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")) } else { EnvFilter::new("error,dtmm=info") -- 2.45.3