rust【日志库】

可以设置输出级别,颜色,时间戳,输出行数等

rust 复制代码
// logger.rs
use chrono::Local;
use std::fmt;
use std::io::{self, Write};
use std::sync::Mutex;
use std::sync::OnceLock;

/// 日志级别
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum LogLevel {
    Error = 0,
    Warning = 1,
    Notice = 2,
    Info = 3,
    Debug = 4,
}

impl fmt::Display for LogLevel {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = match self {
            LogLevel::Notice => "NOTICE",
            LogLevel::Debug => "DEBUG",
            LogLevel::Info => "INFO",
            LogLevel::Warning => "WARN",
            LogLevel::Error => "ERROR",
        };
        write!(f, "{}", s)
    }
}

/// ANSI 颜色代码
#[allow(dead_code)]
mod ansi_colors {
    pub const RESET: &str = "\x1b[0m";
    pub const BLACK: &str = "\x1b[30m";
    pub const RED: &str = "\x1b[31m";
    pub const GREEN: &str = "\x1b[32m";
    pub const YELLOW: &str = "\x1b[33m";
    pub const BLUE: &str = "\x1b[34m";
    pub const MAGENTA: &str = "\x1b[35m";
    pub const CYAN: &str = "\x1b[36m";
    pub const WHITE: &str = "\x1b[37m";

    // 亮色
    pub const BRIGHT_BLACK: &str = "\x1b[90m";
    pub const BRIGHT_RED: &str = "\x1b[91m";
    pub const BRIGHT_GREEN: &str = "\x1b[92m";
    pub const BRIGHT_YELLOW: &str = "\x1b[93m";
    pub const BRIGHT_BLUE: &str = "\x1b[94m";
    pub const BRIGHT_MAGENTA: &str = "\x1b[95m";
    pub const BRIGHT_CYAN: &str = "\x1b[96m";
    pub const BRIGHT_WHITE: &str = "\x1b[97m";
}

/// 日志级别颜色映射
struct LevelColors {
    notice: &'static str,
    debug: &'static str,
    info: &'static str,
    warning: &'static str,
    error: &'static str,
}

impl Default for LevelColors {
    fn default() -> Self {
        Self {
            notice: ansi_colors::WHITE,
            debug: ansi_colors::CYAN,
            info: ansi_colors::GREEN,
            warning: ansi_colors::YELLOW,
            error: ansi_colors::RED,
        }
    }
}

impl LevelColors {
    fn get(&self, level: LogLevel) -> &'static str {
        match level {
            LogLevel::Notice => self.notice,
            LogLevel::Debug => self.debug,
            LogLevel::Info => self.info,
            LogLevel::Warning => self.warning,
            LogLevel::Error => self.error,
        }
    }
}
/// 日志配置
pub struct LogConfig {
    pub level: LogLevel,
    pub use_colors: bool,
    pub use_timestamps: bool,
}

impl Default for LogConfig {
    fn default() -> Self {
        Self {
            level: LogLevel::Info,
            use_colors: true,
            use_timestamps: false,
        }
    }
}

/// 内部日志器
struct Logger {
    config: Mutex<LogConfig>,
    colors: LevelColors, // 颜色配置
}

impl Logger {
    fn new(level: LogLevel) -> Self {
        Self {
            config: Mutex::new(LogConfig {
                level,
                use_colors: true,
                use_timestamps: false,
            }),
            colors: LevelColors::default(),
        }
    }

    fn set_config(&self, config: LogConfig) {
        let mut cfg = self.config.lock().unwrap();
        *cfg = config;
    }

    fn get_level(&self) -> LogLevel {
        self.config.lock().unwrap().level
    }

    fn color_enabled(&self) -> bool {
        self.config.lock().unwrap().use_colors
    }

    fn timestamps_enabled(&self) -> bool {
        self.config.lock().unwrap().use_timestamps
    }

    fn log(&self, level: LogLevel, message: fmt::Arguments) {
        if level > self.get_level() {
            return;
        }

        let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
        // 需要输出行号,取消下面注释
        // let (file, line) = get_caller_location();

        // let output = format!("{} {:<5} [{}:{}] {}", timestamp, level, file, line, message);
        // 改变输出格式,调整output变量即可
        let output = if self.timestamps_enabled() {
            format!("{} {}", timestamp,   message)
        } else {
            format!("{}",  message)
        };
        if self.color_enabled() {
            let color = self.colors.get(level);
            let colored = format!("{}{}{}", color, output, ansi_colors::RESET);

            let _ = match level {
                LogLevel::Error => writeln!(io::stderr(), "{}", colored),
                _ => writeln!(io::stdout(), "{}", colored),
            };
        } else {
            let _ = match level {
                LogLevel::Error => writeln!(io::stderr(), "{}", output),
                _ => writeln!(io::stdout(), "{}", output),
            };
        }
    }
}

/// 需要输出行号,取消注释,获取调用位置(文件名和行号)
// fn get_caller_location() -> (&'static str, u32) {
//     let location = std::panic::Location::caller();
//     (location.file(), location.line())
// }

// 全局静态日志器
static LOGGER: OnceLock<Logger> = OnceLock::new();

// 设置 v的级别,通过
fn get_logger() -> &'static Logger {
    LOGGER.get_or_init(|| Logger::new(LogLevel::Notice))
}

/// 初始化日志系统
pub fn init_logger(config: LogConfig) {
    get_logger().set_config(config);
}

/// 设置日志级别
pub fn set_log_level(level: u8) {
    let level = match level + 3 {
            0 => LogLevel::Error,
            1 => LogLevel::Warning,
            2 => LogLevel::Notice,
            3 => LogLevel::Info,
            4 => LogLevel::Debug,
            _ => LogLevel::Debug,
        };
    let mut config = get_logger().config.lock().unwrap();
    config.level = level;
}

/// 启用/禁用颜色输出
pub fn set_color_enabled(enabled: bool) {
    let mut config = get_logger().config.lock().unwrap();
    config.use_colors = enabled;
}

// 内部函数,供宏调用
#[doc(hidden)]
pub fn _log(level: LogLevel, args: fmt::Arguments) {
    get_logger().log(level, args);
}

// 宏定义:方便在任何地方调用
#[macro_export]
macro_rules! log_trace {
    ($($arg:tt)*) => {
        $crate::logger::_log($crate::logger::LogLevel::Notice, format_args!($($arg)*))
    };
}

#[macro_export]
macro_rules! log_debug {
    ($($arg:tt)*) => {
        $crate::logger::_log($crate::logger::LogLevel::Debug, format_args!($($arg)*))
    };
}

#[macro_export]
macro_rules! log_info {
    ($($arg:tt)*) => {
        $crate::logger::_log($crate::logger::LogLevel::Info, format_args!($($arg)*))
    };
}

#[macro_export]
macro_rules! log_warn {
    ($($arg:tt)*) => {
        $crate::logger::_log($crate::logger::LogLevel::Warning, format_args!($($arg)*))
    };
}

#[macro_export]
macro_rules! log_error {
    ($($arg:tt)*) => {
        $crate::logger::_log($crate::logger::LogLevel::Error, format_args!($($arg)*))
    };
}

注意: set_log_level函数需要稍微修改下,以适应不同方式的日志级别设置

使用方式

rust 复制代码
mod logger;

use logger::{LogConfig, LogLevel, init_logger, set_color_enabled, set_log_level};
// use logger::{log_trace, log_debug, log_info, log_warn, log_error};

fn main() {
    // 初始化(可选,不调用则使用默认配置:Info级别,彩色输出)
    init_logger(LogConfig {
        level: LogLevel::Debug,
        use_colors: true,
        use_timestamps: false,
    });

    println!("=== 日志示例 ===");
    example_function();

    println!("\n=== 修改为只显示 WARN 及以上级别 ===");
    set_log_level(1); // 0 + 3 = 3 -> LogLevel::Warning
    example_function();

    println!("\n=== 关闭颜色输出 ===");
    set_color_enabled(false);
    example_function();
}

fn example_function() {
    log_trace!("这是追踪信息(TRACE)");
    log_debug!("调试值: x = {}", 42);
    log_info!("服务启动成功");
    log_warn!("磁盘使用率 {}%", 85);
    log_error!("连接失败: {}", "timeout");
}
相关推荐
古城小栈1 小时前
Rust Tauri:构建轻量高性能跨平台桌面应用
开发语言·后端·rust
问心无愧05131 小时前
ctf show web 入门258
android·前端·笔记
qq_2518364571 小时前
基于java Web 耗材购置与维修网络申报审批系统设计与实现
java·开发语言·前端
UXbot1 小时前
企业AI开发工具:界面自动生成与前端代码交付能力详解
前端·人工智能·交互·web app·ui设计
专业技术员!!!!1 小时前
陪玩系统前端核心功能详解|线上线下陪玩平台开发方案
前端·陪玩系统·电竞陪玩
英俊潇洒美少年1 小时前
前端主流状态管理全家桶:Vuex/Pinia/Redux/Zustand/MobX 从入门到原理、实战、面试全解
前端·面试·职场和发展
Maddie_Mo1 小时前
Pi Agent Web 使用教程:把本地 Pi Coding Agent 搬进浏览器
android·java·前端·人工智能·ai
Python私教2 小时前
从主题闪烁到 Markdown 阅读体验:RuyiBlog v0.1.1 的前端实现复盘
前端·状态模式
SuperEugene2 小时前
菜单架构设计:递归渲染、权限过滤、多级菜单与面包屑统一|权限与菜单架构篇
前端·vue.js·架构