Rust Lambda 函数日志记录和监控 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Rust Lambda 函数日志记录和监控

注意

Rust 运行时系统客户端是实验性程序包。它随时可能更改,并且仅用于评估目的。

Amazon Lambda 将代表您自动监控 Lambda 函数并将日志记录发送至 Amazon CloudWatch。您的 Lambda 函数带有一个 CloudWatch Logs 日志组以及函数的每个实例的日志流。Lambda 运行时环境会将每个调用的详细信息发送到日志流,然后中继函数代码的日志和其他输出。有关更多信息,请参阅 使用 Amazon CloudWatch Logs 与 Amazon Lambda。本页将介绍如何从 Lambda 函数的代码生成日志输出。

创建写入日志的函数

要从函数代码输出日志,您可以使用写入到 stdoutstderr 的任何日志记录函数,例如 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 实现高级日志记录

跟踪是一个框架,用于分析 Rust 程序以收集基于事件的结构化诊断信息。该框架提供了用于自定义日志记录输出级别和格式的实用程序,例如创建结构化 JSON 日志消息。要使用此框架,您必须在实现函数处理程序之前将其初始化为 subscriber。然后,您可以使用 debuginfoerror 等跟踪宏来指定每个场景所需的日志记录级别。

例 – 使用 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"}]}