添加日志模块,初始化日志记录功能,设置日志目录为 ~/.picobot/logs,支持每日轮换

This commit is contained in:
xiaoxixi 2026-04-06 22:51:50 +08:00
parent 34ab439067
commit 09899ddb91
4 changed files with 88 additions and 2 deletions

View File

@ -122,7 +122,7 @@ pub struct LLMProviderConfig {
fn get_default_config_path() -> PathBuf { fn get_default_config_path() -> PathBuf {
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from(".")); let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
home.join(".config").join("picobot").join("config.json") home.join(".picobot").join("config.json")
} }
impl Config { impl Config {
@ -192,7 +192,7 @@ pub enum ConfigError {
impl std::fmt::Display for ConfigError { impl std::fmt::Display for ConfigError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
ConfigError::ConfigNotFound(path) => write!(f, "Config file not found: {}. Use CONFIG_PATH env var or place config in ~/.config/picobot/config.json", path), ConfigError::ConfigNotFound(path) => write!(f, "Config file not found: {}. Use CONFIG_PATH env var or place config in ~/.picobot/config.json", path),
ConfigError::AgentNotFound(name) => write!(f, "Agent not found: {}", name), ConfigError::AgentNotFound(name) => write!(f, "Agent not found: {}", name),
ConfigError::ProviderNotFound(name) => write!(f, "Provider not found: {}", name), ConfigError::ProviderNotFound(name) => write!(f, "Provider not found: {}", name),
ConfigError::ModelNotFound(name) => write!(f, "Model not found: {}", name), ConfigError::ModelNotFound(name) => write!(f, "Model not found: {}", name),

View File

@ -8,6 +8,7 @@ use tokio::net::TcpListener;
use crate::channels::{ChannelManager, manager::GatewayMessageHandler}; use crate::channels::{ChannelManager, manager::GatewayMessageHandler};
use crate::config::Config; use crate::config::Config;
use crate::logging;
use session::SessionManager; use session::SessionManager;
pub struct GatewayState { pub struct GatewayState {
@ -39,6 +40,10 @@ impl GatewayState {
} }
pub async fn run(host: Option<String>, port: Option<u16>) -> Result<(), Box<dyn std::error::Error>> { pub async fn run(host: Option<String>, port: Option<u16>) -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
logging::init_logging();
tracing::info!("Starting PicoBot Gateway");
let state = Arc::new(GatewayState::new()?); let state = Arc::new(GatewayState::new()?);
// Get provider config for channels // Get provider config for channels

View File

@ -7,3 +7,4 @@ pub mod gateway;
pub mod client; pub mod client;
pub mod protocol; pub mod protocol;
pub mod channels; pub mod channels;
pub mod logging;

80
src/logging.rs Normal file
View File

@ -0,0 +1,80 @@
use std::path::PathBuf;
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::{
fmt,
layer::SubscriberExt,
util::SubscriberInitExt,
EnvFilter,
};
/// 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() {
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_ansi(false)
.with_target(true)
.with_level(true)
.with_thread_ids(true);
let console_layer = fmt::layer()
.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() {
let env_filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info"));
let console_layer = fmt::layer()
.with_target(true)
.with_level(true);
tracing_subscriber::registry()
.with(env_filter)
.with(console_layer)
.init();
tracing::info!("Logging initialized (console only)");
}