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

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

采用 Rust 的 Lambda 函数日志记录

注意

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

Amazon Lambda自动代表您监控 Lambda 函数并将日志发送到亚马逊。 CloudWatch您的 Lambda 函数带有 CloudWatch 日志日志组和每个函数实例的日志流。Lambda 运行时环境会将每个调用的详细信息发送到日志流,然后中继函数代码的日志和其他输出。有关更多信息,请参阅将 Amazon CloudWatch 日志与 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"}]}