• Rust中如何使用Ftail将日志同时输出到终端和文件中
  • 发布于 2个月前
  • 305 热度
    0 评论
日志记录几乎是每个应用程序的重要组成部分,它可以帮助我们有效地调试和跟踪错误。在Rust中,我们可能会使用log crate,它提供了一个日志facade,应用程序及其依赖项可以挂接到它。但是,log crate不提供实际的日志记录实现,这意味着它不会自己将日志写入终端或文件。这就是Ftail的用武之地——它可以为终端和文件提供简单的、可配置的日志记录。设置它很简单,只需几行代码就可以将日志同时输出到终端和文件中。

下面是一个将日志记录输出到终端(最低日志级别为Debug)和每日文件(最低日志级别为Error)的示例:
使用以下命令创建一个Rust新项目:
cargo new ftail-example
在Cargo.toml文件中加入依赖项:
[dependencies]
ftail = "0.1"
log = "0.4.22"
然后,在项目根目录下创建一个名为logs的文件夹。
main.rs文件中的代码如下:
use ftail::Ftail;
use log::LevelFilter;

fn main() {
    Ftail::new()
        .console(LevelFilter::Debug)
        .daily_file("logs", LevelFilter::Error)
        .init()
        .unwrap();
    // 堆代码 duidaima.com
    // 可以在代码中的任何地方记录消息
    log::trace!("This is a trace message");
    log::debug!("This is a debug message");
    log::info!(target: "foo", "bar");
    log::warn!("This is a warning message");
    log::error!("This is an error message");
}
这将初始化一个Ftail实例,添加一个用于将日志记录到终端的驱动程序,以及另一个用于将日志记录到每日文件的驱动程序。init()方法将所有这些联系在一起,确保根据你定义的过滤器捕获和处理日志。

运行结果如下:
DEBUG ftail_example This is a debug message
INFO foo bar
WARN ftail_example This is a warning message
ERROR ftail_example This is an error message
执行完成后会在logs文件下生成一个日志文件,如图:

默认实现
ftail crate提供了几个默认的日志记录器,因此你可以根据需要快速定制日志。

输出到终端
基本的console日志记录器使用标准格式打印日志消息。它简单、有效,非常适合在终端中进行开发或调试。

输出格式化的日志到终端
formatted_console日志记录器为日志添加了一些修饰,包括颜色格式和更清晰的时间戳。这使得日志更容易阅读,特别是在开发期间。有些终端甚至生成了指向日志消息的源文件和行号的可点击链接。

例:
· TRACE
This is a trace message
examples/formatted_console/src/main.rs:9
输出到单独的文件中
single_file日志记录器实现将消息记录到单个.log文件中,需要在设置这个驱动程序时指定文件名和位置。

按日期划分日志文件
daily_file日志记录器实现每天创建一个新的日志文件,日志存储在指定的目录中,每个文件使用YYYY-MM-DD.log格式命名。这对于长时间运行的应用程序来说是完美的,因为它使日志文件保持有序且易于管理。

配置Ftail
ftail提供了各种选项来配置日志记录器。下面是一个如何自定义时区、日期-时间格式和过滤器的示例:
Ftail::new()
    .timezone(ftail::Tz::Europe__Amsterdam)
    .datetime_format("%d-%m-%Y %H:%M:%S%.3f")
    .console(LevelFilter::Off)
    .filter_levels(vec![
        Level::Trace,
        Level::Debug,
        Level::Info,
        Level::Error,
    ])
    .filter_targets(vec!["foo"])
    .init()?;
配置日期时间格式
默认情况下,ftail使用“%Y-%m-%d %H:%M:%S”的格式作为日志消息中的时间戳。但是,我们可以自定义此格式以满足实际项目的需要。在上面的示例中,我们将格式更改为“%d-%m-%Y %H:%M:%S%.3f”,它将毫秒数添加到时间戳(%.3f代表小数点后三位)。

配置时区
ftail允许你为日志设置一个特定的时区,如果你的应用程序在多个地区运行,或者如果需要在不同的服务器上保持一致的时间戳,这是很有帮助的。在上面的示例中,我们将时区设置为Europe/Amsterdam,默认为系统的本地时区。

要使用时区,请确保在Cargo.toml中启用了时区功能:
[dependencies]
ftail = { version = "0.1", features = ["timezone"] }
配置日志文件最大尺寸
日志文件会快速增长,特别是在生产环境中。为了防止单个日志文件变得太大,ftail允许设置最大文件大小(以MB为单位)。一旦达到限制,它就将日志滚动到一个新文件中,将.old1附加到前一个日志文件名,依此类推。
.max_file_size(100)
过滤日志级别
你可以通过显式指定日志级别来过滤写入的日志。在下面的示例中,我们进行筛选,只包括Debug、Info和Error消息,跳过Trace和Warn。
.filter_levels(vec![Level::Debug, Level::Info, Level::Error])
过滤目标
有时,我们只想记录应用程序的特定部分。通过过滤目标,可以控制记录代码库的哪些部分或哪些依赖项。在上面的示例中,我们进行筛选,只记录来自foo目标的消息。

添加自定义日志记录器
如果默认实现不能满足需求,ftail允许我们定义自己的日志记录器。下面是一个例子,我们创建了一个自定义记录器,为它实现了Log特性,并将它hook到ftail中:
struct CustomLogger {
    config: Config,
}

impl log::Log for CustomLogger {
    fn enabled(&self, metadata: &log::Metadata) -> bool {
        metadata.level() <= self.config.level_filter
    }

    fn log(&self, record: &log::Record) {
        if !self.enabled(record.metadata()) {
            return;
        }

        let time = chrono::Local::now()
            .format(&self.config.datetime_format)
            .to_string();

        println!("{} [{}] {}", time.black(), record.level().bold(), record.args());
    }

    fn flush(&self) {}
}

Ftail::new()
    .custom(
        |config: Config| Box::new(CustomLogger { config }) as Box<dyn Log + Send + Sync>,
        LevelFilter::Debug,
    )
    .datetime_format("%H:%M:%S%.3f")
    .init()?;
这为我们使用ftail构建自定义日志解决方案提供了充分的灵活性,包括高级格式化、过滤和输出等选项。

用户评论