1 个不稳定版本
0.1.0 | 2022年11月7日 |
---|
#17 in #aptos
110KB
2.5K SLoC
这个crate提供日志记录的API。
使用日志进行监测
使用日志的基本监测
提供一组日志宏(info!
、error!
、warn!
、debug!
和trace!
),用于以不同级别发出日志。所有这些宏都支持添加结构化数据以及格式化文本消息。有关使用哪个级别的指南,请参阅编码指南。
以下示例不进行结构化日志字段的类型检查,而是直接序列化所提供的内容。
use aptos_logger::info;
let world = "world!";
// Formatted message, similar to `printf!`
info!("hello {}", world);
// => '{"level":"info", "message": "hello world!"}'
// Structured data can be logged using the format 'key = value'
// where value implements Serialize. This can be used for indexing and search later.
let value1 = 5;
info!(key1 = value1);
// => '{"level":"info", "data": {"key1": 5}}'
// You can even set multiple key/value pairs and a format message together
let value2 = false;
info!(key1 = value1, key2 = value2, "hello {}", world);
// => '{"level":"info", "data": {"key1": 5, "key2": false}, "message": "hello world!"}'
// Structured data can also use `Display` or `Debug` outputs instead.
// Using the sigil `?` for debug and `%` for display.
let value1 = 5;
info!(debug_key = ?value1, display_key = %value1);
// => '{"level":"info", "data": {"display_key": 5, "debug_key": 5}}'
注意
在格式化消息中使用的参数不会被捕获并作为结构化数据包括在内。例如,在格式字符串字面量之后的全部内容(如"hello {}"
)仅用于格式字符串。
首选的日志监测方式(带类型结构的Schema)
可以使用Schema
trait来实现带类型结构的日志模式。这可以通过手动实现或使用Schema
derive proc-macro实现,为结构实现Schema
trait并提供所有字段的setter。
use aptos_logger::{info, Schema};
#[derive(Schema)]
struct LogSchema<'a> {
// Log using this type's Serialize impl
a: usize,
// Log using this type's Debug impl
#[schema(debug)]
b: Option<Vec<bool>>,
// Log using this type's Display impl
#[schema(display)]
c: Option<&'a str>,
}
let log = LogSchema { a: 5, b: None, c: None };
// Automatic setters are named based on the field names, and handle `Option`
// None fields will be ignored
info!(log.c("radiant"));
// => '{"level":"info", "data": { "a": 5, "c": "radiant"}}'
#[derive(Schema)]
struct OtherSchema<'a> {
val: Option<&'a str>
}
let log = LogSchema { a: 5, b: None, c: None };
let other = OtherSchema { val: None };
// Schemas can be combined
info!(
other.val("awesome"), // First schema
log // Second schema has fields added to it all
);
// => '{"level":"info", "data": { "a": 5, "val":"awesome"}}'
let log = LogSchema { a: 5, b: None, c: None };
let other = OtherSchema { val: None };
// Schemas can be combined with one off fields and messages like above
info!(
other.val("awesome"), // First schema
log, // Second schema has fields added to it all
new_field = "new", // Basic structured fields
"Message: {}", // Format messages
"Some message" // Format message fields (not added to indexed fields)
);
// => {"level":"info", "message": "Message: Some message",
// "data": { "a": 5, "val":"awesome", "new_field": "new"}}'
日志采样
有时记录大量数据是非常昂贵的。为了只记录部分时间的信息,我们添加了一个可配置执行代码频率的sample!
宏。
SampleRate
确定采样语句发生的频率。
use aptos_logger::{info, sample, sample::{SampleRate, Sampling}};
use std::time::Duration;
// Sampled based on frequency of events, log only every 2 logs
sample!(SampleRate::Frequency(2), info!("Long log"));
// Sampled based on time passed, log at most once a minute
sample!(SampleRate::Duration(Duration::from_secs(60)), info!("Long log"));
配置
为了捕获和发出日志,需要实例化Logger。这可以通过使用Logger
类型来实现。
use aptos_logger::{Level, Logger};
Logger::builder().level(Level::Info).build();
依赖项
~10–22MB
~298K SLoC