#fastly #log #log-messages #log-level #compute #endpoints #initialization

log-fastly

Fastly Compute的log外观实现

35个版本

0.10.4 2024年8月21日
0.10.2 2024年7月9日
0.10.0 2024年4月23日
0.9.11 2024年2月21日
0.1.2 2020年7月13日

#106 in 调试

Download history 703/week @ 2024-05-01 718/week @ 2024-05-08 976/week @ 2024-05-15 775/week @ 2024-05-22 547/week @ 2024-05-29 688/week @ 2024-06-05 924/week @ 2024-06-12 851/week @ 2024-06-19 764/week @ 2024-06-26 1538/week @ 2024-07-03 995/week @ 2024-07-10 1040/week @ 2024-07-17 1077/week @ 2024-07-24 744/week @ 2024-07-31 460/week @ 2024-08-07 522/week @ 2024-08-14

每月2,922次下载
用于perimeterx-fastly-enforce…

Apache-2.0 WITH LLVM-exception

37KB
379

Fastly Compute的log日志外观实现。

配置此日志记录器后,log的日志语句将日志消息发送到您选择的实时日志流端点。您应在程序启动时立即初始化日志记录器。在初始化之前,日志语句不会做任何事情。

有关为您的服务配置日志记录端点的更多信息,请参阅Fastly文档

入门指南

要开始使用,您只需要端点名称和您希望发出的日志消息级别。例如,如果您有一个名为my_endpoint的端点,并且您只想在“警告”或“错误”级别发出日志消息,您可以使用 [init_simple()]

log_fastly::init_simple("my_endpoint", log::LevelFilter::Warn);
log::warn!("This will be written to my_endpoint...");
log::info!("...but this won't");

高级配置

要实现更精确的控制,包括多个端点和不同日志级别的默认端点,请使用Builder接口。第一个示例与以下代码等效

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .init();

选项 [Builder::max_level()] 设置要发出的最详细的日志级别。在第一个示例中,像 log::info!() 这样的日志语句将不会执行任何操作。

注意: 默认级别是 LevelFilter::Off,这意味着完全不记录日志。您可能需要更改此设置以适应大多数配置。

在调用日志语句而没有指定 target 字段以指定其端点时,[Builder::default_endpoint()] 会设置端点。默认端点设置为 my_endpoint 时,第一个示例中的日志语句等同于

log::warn!(target: "my_endpoint", "This will be written to my_endpoint...");
log::info!(target: "my_endpoint", "...but this won't");

配合计算日志尾部使用

计算日志尾部 有助于快速从开发中的计算程序中获取调试输出,通过捕获 stdoutstderr 的输出。要将日志配置为输出到 stdoutstderr(除指定的日志端点外),在构建记录器时启用回显

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .echo_stdout(true)
    .init();

多个端点

将端点设置为默认值将自动将其注册为与记录器一起使用,但您可以使用 [Builder::endpoint()] 注册更多端点

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .endpoint("my_other_endpoint")
    .init();
log::warn!(target: "my_endpoint", "This will be written to my_endpoint...");
log::warn!(target: "my_other_endpoint", "...but this will be written to my_other_endpoint");

每个端点的日志级别

您还可以设置每个端点的日志级别,尽管高于 max_level 的级别总是被忽略

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Warn)
    .default_endpoint("my_endpoint")
    .endpoint_level("my_other_endpoint", log::LevelFilter::Trace)
    .endpoint_level("error_only", log::LevelFilter::Error)
    .init();
log::warn!(target: "my_other_endpoint", "This will be written to my_other_endpoint...");
log::trace!(target: "my_other_endpoint", "...but this won't, because max_level wins");
log::error!(target: "error_only", "This will be written to error_only...");
log::warn!(target: "error_only", "...but this won't, because the endpoint's level is lower");

每个级别的默认端点

在前面的示例中,相同的端点被设置为所有日志级别的默认值。您还可以使用 [Builder::default_level_endpoint()] 为单个级别指定默认端点。默认值按顺序组合,因此您可以指定一个总体默认端点,然后指定所需的所有级别特定端点

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .default_level_endpoint("error_only", log::Level::Error)
    .init();
log::info!("This will be written to my_endpoint...");
log::warn!(".. and this will too.");
log::error!("But this will be written to error_only");

模块名称过滤器

除了每个端点的日志级别外,您还可以根据包含日志语句的 Rust 模块的名称设置日志级别。

默认情况下不会根据模块名称进行过滤,但如果指定了任何模块名称模式,则只有与这些模式之一匹配的日志语句将被发出。例如,如果您的应用程序是一个名为 my_app 的包,您可以过滤掉除 my_app 的以外的任何消息

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .filter_module("my_app", log::LevelFilter::Warn)
    .init();
log::warn!("This will be written to my_endpoint");
// This won't emit any log messages, because no patterns match `some_dependency`
some_dependency::function_that_logs();

过滤器表达式支持 regex 包的完整语法。如果您希望将重叠的模式区分对待,这尤其有用。例如,假设您想将模块 my_app::my_module 的日志级别设置得更严格,而不是顶级 my_app 模块。您可以使用 $ 确保不那么严格的模式匹配到模块名称的末尾,而不是匹配包含 my_app 的任何模块名称

mod my_module {
    pub fn do_a_thing() {
        log::warn!("This won't be written, because this module's max level is Error");
    }
}
log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .filter_module("my_app$", log::LevelFilter::Warn)
    .filter_module("my_app::my_module", log::LevelFilter::Error)
    .init();
log::warn!("This will be written to my_endpoint");
// This won't emit any log messages, because "my_app$" doesn't match, and "my_app::my_module"
// is limited to Error
my_module::do_a_thing();

注册端点

在创建记录器时,必须注册您的日志语句所使用的所有端点。以下函数在端点尚未注册的情况下自动注册端点。

  • [init_simple()]
  • [Builder::endpoint()]
  • [Builder::endpoint_level()]
  • [[代码Builder::default_endpoint()]]
  • [[代码Builder::default_level_endpoint()]]

您可以传递端点名称作为字符串,或者一个显式的 fastly::log::Endpoint 值。以下示例是等价的

log_fastly::init_simple("my_endpoint", log::LevelFilter::Info);
log_fastly::init_simple(
    fastly::log::Endpoint::from_name("my_endpoint"),
    log::LevelFilter::Info,
);

如果一条日志语句使用了 target: "my_endpoint"my_endpoint 未注册,则消息将记录到该级别的默认端点(如果存在)。

端点和模块名称冲突

由于 log 的限制,从一个与您的端点名称相同的模块中记录日志会导致日志被发送到该端点,即使没有指定 target,并且端点不是默认端点。例如,如果您有一个名为 my_app 的端点,并且您的应用程序也是一个名为 my_app 的crate

log_fastly::Logger::builder()
    .max_level(log::LevelFilter::Info)
    .default_endpoint("my_endpoint")
    .endpoint("my_app")
    .init();
log::info!("This will be written to my_app, even though my_endpoint is the default");
log::info!(
    target: "my_endpoint",
    "This will be written to my_endpoint, because the target is explicit",
);

我们希望在未来的版本中解决这个问题,但目前的解决方案是确保您的端点名称和crate名称不同,或者在从顶层模块记录日志时始终使用显式的目标语法。

依赖关系

~6.5–9MB
~194K SLoC