- Adjusted formatting and indentation in various files for better clarity. - Consolidated multi-line statements into single lines where appropriate. - Enhanced error handling messages for better debugging. - Added a new InboundProcessor struct to handle inbound messages more effectively. - Updated test cases to ensure they align with the new code structure.
101 lines
3.0 KiB
Rust
101 lines
3.0 KiB
Rust
use chrono::Utc;
|
|
use chrono_tz::Tz;
|
|
use std::path::PathBuf;
|
|
use tracing_appender::rolling::{RollingFileAppender, Rotation};
|
|
use tracing_subscriber::{
|
|
EnvFilter, fmt, fmt::time::FormatTime, layer::SubscriberExt, util::SubscriberInitExt,
|
|
};
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
struct ConfiguredTimestamp {
|
|
timezone: Tz,
|
|
}
|
|
|
|
impl FormatTime for ConfiguredTimestamp {
|
|
fn format_time(
|
|
&self,
|
|
writer: &mut tracing_subscriber::fmt::format::Writer<'_>,
|
|
) -> std::fmt::Result {
|
|
write!(
|
|
writer,
|
|
"{}",
|
|
Utc::now()
|
|
.with_timezone(&self.timezone)
|
|
.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Get the default log directory path: ~/.picobot/logs
|
|
pub fn get_default_log_dir() -> PathBuf {
|
|
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
|
|
home.join(".picobot").join("logs")
|
|
}
|
|
|
|
/// Get the default config file path: ~/.picobot/config.json
|
|
pub fn get_default_config_path() -> PathBuf {
|
|
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
|
|
home.join(".picobot").join("config.json")
|
|
}
|
|
|
|
/// Initialize logging with file appender
|
|
/// Logs are written to ~/.picobot/logs/ with daily rotation
|
|
pub fn init_logging(timezone: Tz) {
|
|
let log_dir = get_default_log_dir();
|
|
|
|
// Create log directory if it doesn't exist
|
|
if !log_dir.exists() {
|
|
if let Err(e) = std::fs::create_dir_all(&log_dir) {
|
|
eprintln!(
|
|
"Warning: Failed to create log directory {}: {}",
|
|
log_dir.display(),
|
|
e
|
|
);
|
|
}
|
|
}
|
|
|
|
// Create file appender with daily rotation
|
|
let file_appender = RollingFileAppender::new(Rotation::DAILY, &log_dir, "picobot.log");
|
|
|
|
// Build subscriber with both console and file output
|
|
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
|
|
|
let file_layer = fmt::layer()
|
|
.with_writer(file_appender)
|
|
.with_timer(ConfiguredTimestamp { timezone })
|
|
.with_ansi(false)
|
|
.with_target(true)
|
|
.with_level(true)
|
|
.with_thread_ids(true);
|
|
|
|
let console_layer = fmt::layer()
|
|
.with_timer(ConfiguredTimestamp { timezone })
|
|
.with_target(true)
|
|
.with_level(true);
|
|
|
|
tracing_subscriber::registry()
|
|
.with(env_filter)
|
|
.with(console_layer)
|
|
.with(file_layer)
|
|
.init();
|
|
|
|
tracing::info!("Logging initialized. Log directory: {}", log_dir.display());
|
|
}
|
|
|
|
/// Initialize logging without file output (console only)
|
|
pub fn init_logging_console_only(timezone: Tz) {
|
|
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
|
|
|
let console_layer = fmt::layer()
|
|
.with_timer(ConfiguredTimestamp { timezone })
|
|
.with_target(true)
|
|
.with_level(true);
|
|
|
|
tracing_subscriber::registry()
|
|
.with(env_filter)
|
|
.with(console_layer)
|
|
.init();
|
|
|
|
tracing::info!("Logging initialized (console only)");
|
|
}
|