Rust에서 Lambda 함수 로깅 - AWS Lambda

Rust에서 Lambda 함수 로깅

참고

Rust 런타임 클라이언트는 실험용 패키지입니다. 변경될 수 있으며 평가 목적으로만 사용됩니다.

AWS Lambda사용자를 대신하여 Lambda 함수를 자동으로 모니터링하고 Amazon에 로그를 전송합니다. CloudWatch Lambda 함수는 로그 로그 그룹과 함수의 각 인스턴스에 대한 로그 스트림과 함께 CloudWatch 제공됩니다. Lambda 런타임 환경은 각 호출에 관한 세부 정보를 로그 스트림에 전송하며, 함수 코드에서 로그 및 그 외 출력을 중계합니다. 자세한 설명은 AWS Lambda과 함께 Amazon CloudWatch Logs 사용 섹션을 참조하세요. 이 페이지에서는 Lambda 함수의 코드에서 로그 출력을 생성하는 방법을 설명합니다.

로그를 작성하는 함수 생성

함수 코드에서 로그를 출력하려면 println! 매크로와 같이 stdout 또는 stderr에 기록하는 모든 로깅 함수를 사용할 수 있습니다. 다음 예제에서는 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 크레이트를 사용한 고급 로깅

Tracing은 구조화된 이벤트 기반 진단 정보를 수집하기 위해 Rust 프로그램을 계측하기 위한 프레임워크입니다. 이 프레임워크는 구조화된 JSON 로그 메시지 생성과 같은 로깅 출력 수준 및 형식을 사용자 지정하는 유틸리티를 제공합니다. 이 프레임워크를 사용하려면 함수 핸들러를 구현하기 전에 subscriber를 초기화해야 합니다. 그런 다음 debug, info, error 등의 추적 매크로를 사용하여 각 시나리오에 대해 원하는 로깅 수준을 지정할 수 있습니다.

예 - Tracing 크레이트 사용

다음을 참고합니다.

  • tracing_subscriber::fmt().json(): 이 옵션을 포함하면 로그 형식이 JSON으로 지정됩니다. 이 옵션을 사용하려면 tracing-subscriber 종속 구성 요소에 json 기능을 포함해야 합니다(예: 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 함수가 호출되면 다음과 유사한 2개의 로그 라인이 인쇄됩니다.

{"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"}]}