Skip to content

Commit

Permalink
Dynamic log filter
Browse files Browse the repository at this point in the history
  • Loading branch information
AurevoirXavier committed Jul 10, 2024
1 parent 70f6ec6 commit b336d10
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 28 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ objc2-foundation = { version = "0.2" }
# accessibility-sys = { version = "0.1" }
# core-foundation = { version = "0.9" }
# objc2 = { version = "0.5" }

# Development only.
# [patch.crates-io]
# async-openai = { path = "tmp/async-openai/async-openai" }
19 changes: 10 additions & 9 deletions src/air.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::sync::Once;
// crates.io
use eframe::{egui::*, glow::Context as GlowContext, Frame, *};
use tracing_subscriber::{reload::Handle, EnvFilter, Registry};
// self
use crate::{
component::Components, os::Os, prelude::Result, service::Services, state::State, ui::Uis,
Expand All @@ -16,15 +17,15 @@ struct AiR {
uis: Uis,
}
impl AiR {
fn new(ctx: &Context) -> Result<Self> {
fn new(log_filter_handle: Handle<EnvFilter, Registry>, ctx: &Context) -> Result<Self> {
Self::set_fonts(ctx);

// To enable SVG.
egui_extras::install_image_loaders(ctx);

let once = Once::new();
let components = Components::new()?;
let state = State::new(&components.setting);
let state = State::new(log_filter_handle, &components.setting)?;
let services = Services::new(ctx, &components, &state)?;
let uis = Uis::new();

Expand Down Expand Up @@ -88,13 +89,13 @@ impl App for AiR {
self.once.call_once(Os::set_move_to_active_space);
}
// TODO: https://github.com/emilk/egui/issues/4468.
// Allow 1 second for initialization during the first boot.
else if raw_input.time.unwrap_or_default() >= 1.
// Allow 250ms for initialization during the first boot.
else if raw_input.time.unwrap_or_default() >= 0.25
&& self.components.setting.general.hide_on_lost_focus
{
// TODO: https://github.com/emilk/egui/discussions/4635.
// We can get rid of the OS API if this works.
// ctx.send_viewport_cmd(ViewportCommand::Minimized(false));
// ctx.send_viewport_cmd(ViewportCommand::Minimized(true));
Os::hide();
}
}
Expand All @@ -113,7 +114,7 @@ pub struct AiRContext<'a> {
pub services: &'a mut Services,
}

pub fn launch() -> Result<()> {
pub fn launch(log_filter_handle: Handle<EnvFilter, Registry>) -> Result<()> {
eframe::run_native(
"AiR",
NativeOptions {
Expand All @@ -124,12 +125,12 @@ pub fn launch() -> Result<()> {
)
.with_inner_size((720., 360.))
.with_min_inner_size((720., 360.)),
// TODO?: transparent window.
// .with_transparent(true),
// TODO?: transparent window.
// .with_transparent(true),
follow_system_theme: true,
..Default::default()
},
Box::new(|c| Ok(Box::new(AiR::new(&c.egui_ctx).unwrap()))),
Box::new(|c| Ok(Box::new(AiR::new(log_filter_handle, &c.egui_ctx).unwrap()))),
)?;

Ok(())
Expand Down
53 changes: 53 additions & 0 deletions src/component/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{borrow::Cow, fs, path::PathBuf};
use app_dirs2::AppDataType;
use async_openai::config::OPENAI_API_BASE;
use serde::{Deserialize, Serialize};
use tracing::Level;
// self
use super::{function::Function, openai::Model};
use crate::{prelude::*, widget::ComboBoxItem, APP_INFO};
Expand All @@ -15,6 +16,7 @@ pub struct Setting {
pub ai: Ai,
pub chat: Chat,
pub hotkeys: Hotkeys,
pub development: Development,
}
impl Setting {
pub fn path() -> Result<PathBuf> {
Expand Down Expand Up @@ -187,3 +189,54 @@ impl Default for Hotkeys {
}
}
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Development {
pub log_level: LogLevel,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum LogLevel {
Trace,
Debug,
Info,
Warn,
Error,
}
impl Default for LogLevel {
fn default() -> Self {
Self::Warn
}
}
impl From<LogLevel> for Level {
fn from(l: LogLevel) -> Self {
match l {
LogLevel::Trace => Level::TRACE,
LogLevel::Debug => Level::DEBUG,
LogLevel::Info => Level::INFO,
LogLevel::Warn => Level::WARN,
LogLevel::Error => Level::ERROR,
}
}
}
impl ComboBoxItem for LogLevel {
type Array = [Self; Self::COUNT];

const COUNT: usize = 5;

fn all() -> Self::Array {
[Self::Trace, Self::Debug, Self::Info, Self::Warn, Self::Error]
}

fn as_str(&self) -> &'static str {
match self {
Self::Trace => "Trace",
Self::Debug => "Debug",
Self::Info => "Info",
Self::Warn => "Warn",
Self::Error => "Error",
}
}
}
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub enum Error {
Reqwew(#[from] reqwew::error::Error),
#[error(transparent)]
Toml(#[from] toml::de::Error),
#[error(transparent)]
TracingSubscriber(#[from] tracing_subscriber::reload::Error),

#[error(transparent)]
Enigo(#[from] EnigoError),
Expand Down
14 changes: 7 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ mod prelude {
use app_dirs2::{AppDataType, AppInfo};
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::{
filter::LevelFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter,
filter::LevelFilter, fmt, layer::SubscriberExt, reload::Layer, util::SubscriberInitExt,
EnvFilter,
};

const APP_INFO: AppInfo = AppInfo { name: "AiR", author: "[email protected]" };
Expand All @@ -44,20 +45,19 @@ fn main() {
.build(app_dirs2::get_app_root(AppDataType::UserData, &APP_INFO).unwrap())
.unwrap(),
);
let filter =
EnvFilter::builder().with_default_directive(LevelFilter::INFO.into()).from_env_lossy();
let (reloadable_filter, filter_handle) = Layer::new(filter);
let file_layer = fmt::layer().with_ansi(false).with_writer(non_blocking);
let subscriber = tracing_subscriber::registry().with(reloadable_filter).with(file_layer);
#[cfg(feature = "dev")]
let console_layer = fmt::layer();
let subscriber = tracing_subscriber::registry()
.with(
EnvFilter::builder().with_default_directive(LevelFilter::INFO.into()).from_env_lossy(),
)
.with(file_layer);
#[cfg(feature = "dev")]
let subscriber = subscriber.with(console_layer);

subscriber.init();

#[cfg(not(feature = "dev"))]
panic::set_hook(Box::new(|p| tracing::error!("{p}")));
air::launch().unwrap();
air::launch(filter_handle).unwrap();
}
38 changes: 27 additions & 11 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,30 @@ use std::sync::{
};
// crates.io
use parking_lot::RwLock;
use tracing::Level;
use tracing_subscriber::{reload::Handle, EnvFilter, Registry};
// self
use crate::component::setting::Setting;
use crate::{component::setting::Setting, prelude::*};

#[derive(Debug)]
pub struct State {
pub general: General,
pub chat: Chat,
pub development: Development,
}
impl State {
pub fn new(setting: &Setting) -> Self {
Self {
pub fn new(log_filter_handle: Handle<EnvFilter, Registry>, setting: &Setting) -> Result<Self> {
let development = Development { log_filter_handle };

development.reload_log_filter(setting.development.log_level.clone().into())?;

Ok(Self {
general: General {
hide_on_lost_focus: Arc::new(AtomicBool::new(setting.general.hide_on_lost_focus)),
},
chat: Chat {
quote: Arc::new(RwLock::new(String::new())),
input: Arc::new(RwLock::new(String::new())),
output: Arc::new(RwLock::new(String::new())),
token_counts: Arc::new((AtomicU32::new(0), AtomicU32::new(0))),
},
}
chat: Default::default(),
development,
})
}
}

Expand All @@ -34,10 +37,23 @@ pub struct General {
pub hide_on_lost_focus: Arc<AtomicBool>,
}

#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Chat {
pub quote: Arc<RwLock<String>>,
pub input: Arc<RwLock<String>>,
pub output: Arc<RwLock<String>>,
pub token_counts: Arc<(AtomicU32, AtomicU32)>,
}

#[derive(Debug)]
pub struct Development {
pub log_filter_handle: Handle<EnvFilter, Registry>,
}
impl Development {
pub fn reload_log_filter(&self, level: Level) -> Result<()> {
self.log_filter_handle
.reload(EnvFilter::builder().with_default_directive(level.into()).from_env_lossy())?;

Ok(())
}
}
21 changes: 20 additions & 1 deletion src/ui/panel/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ impl UiT for Setting {
}
});

// TODO: [`crate::component::setting::Chat`].
ui.collapsing("Translation", |ui| {
Grid::new("Translation").num_columns(2).striped(true).show(ui, |ui| {
// TODO: A and B should be mutually exclusive.
Expand All @@ -134,6 +133,26 @@ impl UiT for Setting {
ui.end_row();
});
});

ui.collapsing("Development", |ui| {
Grid::new("Development").num_columns(2).striped(true).show(ui, |ui| {
if ui
.add(widget::combo_box(
"Log Level",
&mut ctx.components.setting.development.log_level,
))
.changed()
{
ctx.state
.development
.reload_log_filter(
ctx.components.setting.development.log_level.clone().into(),
)
.expect("reload must succeed");
}
ui.end_row();
});
});
}
}

Expand Down

0 comments on commit b336d10

Please sign in to comment.