18 个版本

0.4.4 2021 年 8 月 6 日
0.4.3 2021 年 1 月 31 日
0.4.1 2020 年 10 月 20 日
0.4.0 2020 年 7 月 20 日
0.1.3 2018 年 11 月 10 日

调试 中排名 #712

Download history 5/week @ 2024-03-10 18/week @ 2024-03-31

每月下载 65
用于 spirit

Apache-2.0 或 MIT 许可

350KB
4K SLoC

Spirit-log

Travis Build Status

将日志记录集成到 spirit 配置框架的辅助工具和配置片段。

请参阅 文档示例

许可证

许可协议为以下之一

由您选择。

贡献

除非您明确声明,否则根据 Apache-2.0 许可协议定义的,您有意提交以包含在工作中的任何贡献,将按上述方式双许可,不附加任何额外条款或条件。


lib.rs:

spirit 片段和辅助工具,用于配置和控制日志记录。

这里的片段允许从命令行和配置中配置相对复杂的日志(多个记录器、不同格式、不同目的地),并允许在运行时重新加载它们。

内部基于 fern crate,仅增加了配置和运行时重新加载(通过 log-reroute)。

它假设应用程序没有自己设置全局日志记录器。它还通过 log_panics crate 设置 panic hook。还将 with-backtrace cargo 功能传递下去。

特性

  • background:包括异步日志记录的能力 - 日志文件的写入发生在后台线程,允许应用程序的其他部分不阻塞在 I/O 上。
  • cfg-help:支持运行时配置选项帮助。默认开启。
  • with-backtrace:通过 log_panics 记录带有回溯的信息。默认开启。
  • syslog:增加了将日志记录到系统日志的支持。

启动

当使用与管道的自动管理时,启动是这样的

  • 一旦管道被注册,就会向 stderr 发送 WARN 级别的日志。
  • 在解析命令行参数后,将更新 stderr 的日志以反映这一点(或者如果用户没有设置,则保持在 WARN 级别)。
  • 在从文件加载配置后,根据该配置配置完整日志。

与其他日志记录器的集成

如果您需要特定功能(例如 sentry),可以通过管道插入额外的日志记录器 - Dispatch 允许添加任意日志记录器。在 Pipeline::map 中执行此操作是个好地方。

性能警告

这允许用户创建任意数量的日志记录器。此外,默认情况下日志记录是同步的,并且没有缓冲。当写入大量日志或将它们发送到网络上时,这可能会成为瓶颈。

后台日志记录

通过 background 功能标志添加了在后台线程中执行实际日志记录的能力。这允许通过 I/O 或其他昂贵操作不会阻塞实际应用程序。

另一方面,如果应用程序崩溃,一些日志可能会丢失(或者,根据设置,当日志线程跟不上的情况下)。另外,您需要在关闭时使用 FlushGuard 清除日志记录器。

这是通过 Background 转换完成的。

计划中的功能

这些功能计划在未来某个时间点实现,但目前尚未实现(欢迎提交拉取请求)。

  • 如果 TCP 连接丢失,重新连接到远程服务器。
  • 日志文件轮转。
  • stdout/stderr 上使用颜色。

无管道使用

可以手动使用,而不使用 Pipeline,但是需要特别注意初始化所有需要初始化的内容。

可以仅获取 Dispatch 对象并调用 apply,但这是一种单次初始化,日志记录器不能被替换。

辅助函数 initinstall 可以用来多次替换 Dispatch 记录器。

示例

手动单次使用安装

use spirit::AnyError;
use spirit::prelude::*;
use spirit_log::Cfg;

// Well, you'd get it somewhere from configuration, but…
let cfg = Cfg::default();
let logger = cfg.create("logger")?;
logger.apply()?;

手动多次使用安装

use spirit::AnyError;
use spirit::prelude::*;
use spirit_log::Cfg;

spirit_log::init();
// This part can be done multiple times.
let cfg = Cfg::default();
let logger = cfg.create("logger")?;
spirit_log::install(logger);

使用 Pipeline 自动使用,重新加载和命令行选项

use log::info;
use serde::Deserialize;
use spirit::{Pipeline, Spirit};
use spirit::prelude::*;
use spirit_log::{Cfg as LogCfg, CfgAndOpts as LogBoth, Opts as LogOpts};
use structopt::StructOpt;

#[derive(Clone, Debug, StructOpt)]
struct Opts {
    #[structopt(flatten)]
    logging: LogOpts,
}

impl Opts {
    fn logging(&self) -> LogOpts {
        self.logging.clone()
    }
}

#[derive(Clone, Debug, Default, Deserialize)]
struct Cfg {
    #[serde(default, skip_serializing_if = "LogCfg::is_empty")]
    logging: LogCfg,
}

impl Cfg {
    fn logging(&self) -> LogCfg {
        self.logging.clone()
    }
}

fn main() {
    Spirit::<Opts, Cfg>::new()
        .with(
            Pipeline::new("logging").extract(|opts: &Opts, cfg: &Cfg| LogBoth {
                cfg: cfg.logging(),
                opts: opts.logging(),
            }),
        )
        .run(|_spirit| {
            info!("Hello world");
            Ok(())
        });
}

配置可能看起来像这样

[[logging]]
level = "DEBUG"
type = "file"
filename = "/tmp/example.log"
clock = "UTC"

依赖项

~6–8.5MB
~146K SLoC