Rust Lambda 函数日志记录和监控
注意
Rust 运行时系统客户端
Amazon Lambda 将代表您自动监控 Lambda 函数并将日志记录发送至 Amazon CloudWatch。您的 Lambda 函数带有一个 CloudWatch Logs 日志组以及函数的每个实例的日志流。Lambda 运行时环境会将每个调用的详细信息发送到日志流,然后中继函数代码的日志和其他输出。有关更多信息,请参阅 将 CloudWatch Logs 与 Lambda 结合使用。本页将介绍如何从 Lambda 函数的代码生成日志输出。
创建写入日志的函数
要从函数代码输出日志,您可以使用写入到 stdout
或 stderr
的任何日志记录函数,例如 println!
宏。以下示例使用 println!
在函数处理程序启动时和完成之前输出消息。
use lambda_runtime::{service_fn, LambdaEvent, Error}; use serde_json::{json, Value}; async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> { println!("Rust function invoked"); let payload = event.payload; let first_name = payload["firstName"].as_str().unwrap_or("world"); println!("Rust function responds to {}", &first_name); Ok(json!({ "message": format!("Hello, {first_name}!") })) } #[tokio::main] async fn main() -> Result<(), Error> { lambda_runtime::run(service_fn(handler)).await }
使用 Tracing crate 实现高级日志记录
跟踪subscriber
。然后,您可以使用 debug
、info
和 error
等跟踪宏来指定每个场景所需的日志记录级别。
例 – 使用 Tracing crate
请注意以下几点:
-
tracing_subscriber::fmt().json()
:如果包含此选项,则日志将采用 JSON 格式。要使用此选项,您必须将json
功能包含在tracing-subscriber
依赖项中(例如tracing-subscriber = { version = "0.3.11", features = ["json"] }
)。 -
#[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))]
:每次调用处理程序时,此注释都会生成一个跨度。该跨度会将请求 ID 添加到每个日志行。 -
{ %first_name }
:此构造会将first_name
字段添加到使用该字段的日志行。此字段的值与同名变量对应。
use lambda_runtime::{service_fn, Error, LambdaEvent}; use serde_json::{json, Value}; #[tracing::instrument(skip(event), fields(req_id = %event.context.request_id))] async fn handler(event: LambdaEvent<Value>) -> Result<Value, Error> { tracing::info!("Rust function invoked"); let payload = event.payload; let first_name = payload["firstName"].as_str().unwrap_or("world"); tracing::info!({ %first_name }, "Rust function responds to event"); Ok(json!({ "message": format!("Hello, {first_name}!") })) } #[tokio::main] async fn main() -> Result<(), Error> { tracing_subscriber::fmt().json() .with_max_level(tracing::Level::INFO) // this needs to be set to remove duplicated information in the log. .with_current_span(false) // this needs to be set to false, otherwise ANSI color codes will // show up in a confusing manner in CloudWatch logs. .with_ansi(false) // disabling time is handy because CloudWatch will add the ingestion time. .without_time() // remove the name of the function from every log entry .with_target(false) .init(); lambda_runtime::run(service_fn(handler)).await }
调用此 Rust 函数时,它会输出类似于以下内容的两个日志行:
{"level":"INFO","fields":{"message":"Rust function invoked"},"spans":[{"req_id":"45daaaa7-1a72-470c-9a62-e79860044bb5","name":"handler"}]} {"level":"INFO","fields":{"message":"Rust function responds to event","first_name":"David"},"spans":[{"req_id":"45daaaa7-1a72-470c-9a62-e79860044bb5","name":"handler"}]}