log-full 0.0.1

A simple, asynchronous log library
Documentation
//! 日志构建器模块
//! 
//! 提供灵活的日志配置构建功能

use crate::error::{LogError, LogResult};
use crate::init::init_log_inner_with_config;
use crate::quickwit::QuickwitConfig;
use std::path::Path;

/// 日志构建器
pub struct Builder {
    pub(crate) level: log::LevelFilter,
    pub(crate) log_file: String,
    pub(crate) log_file_max: u32,
    pub(crate) use_console: bool,
    pub(crate) use_async: bool,
    pub(crate) plugin: Option<Box<dyn std::io::Write + Send + Sync + 'static>>,
    pub(crate) filter: Option<Box<dyn crate::CustomFilter>>,
    pub(crate) show_process_id: bool,
    pub(crate) show_thread_info: bool,
    pub(crate) show_module_path: bool,
    pub(crate) highlight_keywords: Vec<String>,
    pub(crate) quickwit_config: Option<QuickwitConfig>,
}

impl Builder {
    #[inline]
    pub fn new() -> Self {
        Self {
            level: log::LevelFilter::Info,
            log_file: String::new(),
            log_file_max: 10 * 1024 * 1024,
            use_console: true,
            use_async: true,
            plugin: None,
            filter: None,
            show_process_id: true,
            show_thread_info: true,
            show_module_path: true,
            highlight_keywords: Vec::new(),
            quickwit_config: None,
        }
    }

    /// 验证配置的有效性
    pub fn validate(&self) -> LogResult<()> {
        if self.log_file_max == 0 {
            return Err(LogError::config("Max file size cannot be zero"));
        }
        
        if !self.log_file.is_empty() {
            if let Some(parent) = Path::new(&self.log_file).parent() {
                if !parent.exists() {
                    return Err(LogError::file_operation(
                        self.log_file.clone(),
                        "Parent directory does not exist"
                    ));
                }
            }
        }
        
        Ok(())
    }

    #[inline]
    pub fn builder(self) -> LogResult<()> {
        self.validate()?;
        init_log_inner_with_config(self.level, self.log_file, self.log_file_max,
            self.use_console, self.use_async, self.plugin, self.filter,
            self.show_process_id, self.show_thread_info, self.show_module_path,
            self.highlight_keywords, self.quickwit_config)
    }

    #[inline]
    pub fn level(mut self, level: log::LevelFilter) -> Self {
        self.level = level;
        self
    }

    #[inline]
    pub fn log_file(mut self, log_file: String) -> Self {
        self.log_file = log_file;
        self
    }

    #[inline]
    pub fn log_file_max(mut self, log_file_max: u32) -> Self {
        self.log_file_max = log_file_max;
        self
    }

    #[inline]
    pub fn use_console(mut self, use_console: bool) -> Self {
        self.use_console = use_console;
        self
    }

    #[inline]
    pub fn use_async(mut self, use_async: bool) -> Self {
        self.use_async = use_async;
        self
    }

    #[inline]
    pub fn level_str(mut self, level: &str) -> LogResult<Self> {
        self.level = crate::utils::parse_level(level)?;
        Ok(self)
    }

    #[inline]
    pub fn log_file_max_str(mut self, log_file_max: &str) -> LogResult<Self> {
        self.log_file_max = crate::utils::parse_size(log_file_max)?;
        Ok(self)
    }

    pub fn plugin<T: std::io::Write + Send + Sync + 'static>(mut self, plugin: T) -> Self {
        self.plugin = Some(Box::new(plugin));
        self
    }

    pub fn filter(mut self, filter: impl crate::CustomFilter) -> Self {
        self.filter = Some(Box::new(filter));
        self
    }

    /// 设置是否显示进程ID
    #[inline]
    pub fn show_process_id(mut self, show: bool) -> Self {
        self.show_process_id = show;
        self
    }

    /// 设置是否显示线程信息
    #[inline]
    pub fn show_thread_info(mut self, show: bool) -> Self {
        self.show_thread_info = show;
        self
    }

    /// 设置是否显示模块路径
    #[inline]
    pub fn show_module_path(mut self, show: bool) -> Self {
        self.show_module_path = show;
        self
    }

    /// 设置需要高亮显示的关键词
    #[inline]
    pub fn highlight_keywords(mut self, keywords: Vec<String>) -> Self {
        self.highlight_keywords = keywords;
        self
    }

    /// 添加单个关键词到高亮列表
    #[inline]
    pub fn add_highlight_keyword(mut self, keyword: String) -> Self {
        self.highlight_keywords.push(keyword);
        self
    }

    /// 设置 Quickwit 配置
    #[inline]
    pub fn quickwit(mut self, config: QuickwitConfig) -> Self {
        self.quickwit_config = Some(config);
        self
    }

    /// 设置 Quickwit URL 和索引 ID
    #[inline]
    pub fn quickwit_simple(mut self, url: String, index_id: String) -> Self {
        self.quickwit_config = Some(QuickwitConfig::new(url, index_id));
        self
    }

    /// 禁用 Quickwit
    #[inline]
    pub fn disable_quickwit(mut self) -> Self {
        self.quickwit_config = None;
        self
    }
}

impl Default for Builder {
    fn default() -> Self {
        Self::new()
    }
}