C# Lambda 函数日志记录和监控
AWS Lambda 将自动监控 Lambda 函数并将日志条目发送到 Amazon CloudWatch。您的 Lambda 函数带有一个 CloudWatch Logs 日志组以及函数的每个实例的日志流。Lambda 运行时系统环境会将每次调用的详细信息以及函数代码的其他输出发送到该日志流。有关 CloudWatch Logs 的更多信息,请参阅将 CloudWatch Logs 日志与 Lambda 结合使用。
Sections
创建返回日志的函数
要从函数代码输出日志,您可以使用控制台类stdout
或 stderr
的任何日志记录库。
.NET 运行时记录每次调用的 START
、END
和 REPORT
行。报告行提供了以下详细信息:
REPORT 行数据字段
-
RequestId – 调用的唯一请求 ID。
-
Duration(持续时间)– 函数的处理程序方法处理事件所花费的时间。
-
Billed Duration(计费持续时间)– 针对调用计费的时间量。
-
Memory Size(内存大小)– 分配给函数的内存量。
-
Max Memory Used(最大内存使用量)– 函数使用的内存量。如果调用共享执行环境,Lambda 会报告所有调用使用的最大内存。此行为可能会导致报告值高于预期。
-
Init Duration(初始持续时间)– 对于提供的第一个请求,为运行时在处理程序方法外部加载函数和运行代码所花费的时间。
-
XRAY TraceId – 对于追踪的请求,为 AWS X-Ray 追踪 ID。
-
SegmentId – 对于追踪的请求,为 X-Ray 分段 ID。
-
Sampled(采样)– 对于追踪的请求,为采样结果。
使用日志记录工具和库
Powertools for AWS Lambda(.NET)
从 Lambda 上下文中捕获关键字段,冷启动并将日志记录输出结构化为 JSON
根据指示记录 Lambda 调用事件(默认情况下禁用)
通过日志采样仅针对一定百分比的调用输出所有日志(默认情况下禁用)
在任何时间点将其他键附加到结构化日志
使用自定义日志格式设置程序(自带格式设置程序),从而在与组织的日志记录 RFC 兼容的结构中输出日志
将 Powertools for AWS Lambda(.NET)和 AWS SAM 用于结构化日志记录
请按照以下步骤使用 AWS SAM,通过集成的 Powertools for AWS Lambda(.NET)hello world
消息。
先决条件
要完成本节中的步骤,您必须满足以下条件:
-
.NET 6 或 .NET 8
-
AWS SAM CLI 版本 1.75 或更高版本。如果您使用的是旧版本的 AWS SAM CLI,请参阅升级 AWS SAM CLI。
部署示例 AWS SAM 应用程序
-
使用 Hello World TypeScript 模板初始化该应用程序。
sam init --app-template hello-world-powertools-dotnet --name sam-app --package-type Zip --runtime dotnet6 --no-tracing
-
构建应用程序。
cd sam-app && sam build
-
部署应用程序。
sam deploy --guided
-
按照屏幕上的提示操作。要在交互式体验中接受提供的默认选项,请按
Enter
。注意
对于 HelloWorldFunction 可能没有定义授权,确定执行此操作吗?,确保输入
y
。 -
获取已部署应用程序的 URL:
aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
-
调用 API 端点:
curl -X GET
<URL_FROM_PREVIOUS_STEP>
如果成功,您将会看到如下响应:
{"message":"hello world"}
-
要获取该函数的日志,请运行 sam logs。有关更多信息,请参阅《AWS Serverless Application Model 开发人员指南》中的 使用日志。
sam logs --stack-name sam-app
该日志输出类似于以下示例:
2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:27.988000 INIT_START Runtime Version: dotnet:6.v13 Runtime Version ARN: arn:aws:lambda:ap-southeast-2::runtime:699f346a05dae24c58c45790bc4089f252bf17dae3997e79b17d939a288aa1ec 2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:28.229000 START RequestId: bed25b38-d012-42e7-ba28-f272535fb80e Version: $LATEST 2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:29.259000 2023-02-20T14:15:29.201Z bed25b38-d012-42e7-ba28-f272535fb80e info {"_aws":{"Timestamp":1676902528962,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ColdStart","Unit":"Count"}],"Dimensions":[["FunctionName"],["Service"]]}]},"FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","Service":"PowertoolsHelloWorld","ColdStart":1} 2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:30.479000 2023-02-20T14:15:30.479Z bed25b38-d012-42e7-ba28-f272535fb80e info {"ColdStart":true,"XrayTraceId":"1-63f3807f-5dbcb9910c96f50742707542","CorrelationId":"d3d4de7f-4ccc-411a-a549-4d67b2fdc015","FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","FunctionVersion":"$LATEST","FunctionMemorySize":256,"FunctionArn":"arn:aws:lambda:ap-southeast-2:123456789012:function:sam-app-HelloWorldFunction-haKIoVeose2p","FunctionRequestId":"bed25b38-d012-42e7-ba28-f272535fb80e","Timestamp":"2023-02-20T14:15:30.4602970Z","Level":"Information","Service":"PowertoolsHelloWorld","Name":"AWS.Lambda.Powertools.Logging.Logger","Message":"Hello world API - HTTP 200"} 2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:30.599000 2023-02-20T14:15:30.599Z bed25b38-d012-42e7-ba28-f272535fb80e info {"_aws":{"Timestamp":1676902528922,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ApiRequestCount","Unit":"Count"}],"Dimensions":[["Service"]]}]},"Service":"PowertoolsHelloWorld","ApiRequestCount":1} 2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:30.680000 END RequestId: bed25b38-d012-42e7-ba28-f272535fb80e 2023/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2023-02-20T14:15:30.680000 REPORT RequestId: bed25b38-d012-42e7-ba28-f272535fb80e Duration: 2450.99 ms Billed Duration: 2451 ms Memory Size: 256 MB Max Memory Used: 74 MB Init Duration: 240.05 ms XRAY TraceId: 1-63f3807f-5dbcb9910c96f50742707542 SegmentId: 16b362cd5f52cba0
-
这是一个可以通过互联网访问的公有 API 端点。我们建议您在测试后删除该端点。
sam delete
管理日志保留日期
删除函数时,日志组不会自动删除。要避免无限期存储日志,请删除日志组,或配置一个保留期,在该保留期结束后,日志将自动删除。要设置日志保留日期,请将以下内容添加到您的 AWS SAM 模板中:
Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: # Omitting other properties LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}" RetentionInDays: 7
在 Lambda 控制台中查看日志
调用 Lambda 函数后,您可以使用 Lambda 控制台查看日志输出。
如果可以在嵌入式代码编辑器中测试代码,则可以在执行结果中找到日志。使用控制台测试功能调用函数时,可以在详细信息部分找到日志输出。
在 CloudWatch 控制台中查看日志
您可以使用 Amazon CloudWatch 控制台查看所有 Lambda 函数调用的日志。
使用 CloudWatch 控制台查看日志
-
打开 CloudWatch 控制台的 Log groups
(日志组页面)。 -
选择您的函数 (/aws/lambda/
your-function-name
) 的日志组。 -
创建日志流。
每个日志流对应一个函数实例。日志流会在您更新 Lambda 函数以及创建更多实例来处理多个并发调用时显示。要查找特定调用的日志,建议您使用 AWS X-Ray 检测函数。X-Ray 会在追踪中记录有关请求和日志流的详细信息。
使用 AWS Command Line Interface(AWS CLI)查看日志
AWS CLI 是一种开源工具,让您能够在命令行 Shell 中使用命令与 AWS 服务进行交互。要完成本节中的步骤,您必须拥有 AWS CLI 版本 2。
您可以通过 AWS CLI,使用 --log-type
命令选项检索调用的日志。响应包含一个 LogResult
字段,其中包含多达 4KB 来自调用的 base64 编码日志。
例 检索日志 ID
以下示例说明如何从 LogResult
字段中检索名为 my-function
的函数的日志 ID。
aws lambda invoke --function-name my-function out --log-type Tail
您应看到以下输出:
{ "StatusCode": 200, "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...", "ExecutedVersion": "$LATEST" }
例 解码日志
在同一命令提示符下,使用 base64
实用程序解码日志。以下示例说明如何为 my-function
检索 base64 编码的日志。
aws lambda invoke --function-name my-function out --log-type Tail \ --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
如果使用 cli-binary-format 版本 2,则 AWS CLI 选项是必需的。要将其设为默认设置,请运行 aws configure set cli-binary-format raw-in-base64-out
。有关更多信息,请参阅版本 2 的 AWS Command Line Interface 用户指南中的 AWS CLI 支持的全局命令行选项。
您应看到以下输出:
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Duration: 79.67 ms Billed Duration: 80 ms Memory Size: 128 MB Max Memory Used: 73 MB
base64
实用程序在 Linux、macOS 和 Ubuntu on Windowsbase64 -D
。
例 get-logs.sh 脚本
在同一命令提示符下,使用以下脚本下载最后五个日志事件。此脚本使用 sed
从输出文件中删除引号,并休眠 15 秒以等待日志可用。输出包括来自 Lambda 的响应,以及来自 get-log-events
命令的输出。
复制以下代码示例的内容并将其作为 get-logs.sh
保存在 Lambda 项目目录中。
如果使用 cli-binary-format 版本 2,则 AWS CLI 选项是必需的。要将其设为默认设置,请运行 aws configure set cli-binary-format raw-in-base64-out
。有关更多信息,请参阅版本 2 的 AWS Command Line Interface 用户指南中的 AWS CLI 支持的全局命令行选项。
#!/bin/bash aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out sed -i'' -e 's/"//g' out sleep 15 aws logs get-log-events --log-group-name /aws/lambda/
my-function
--log-stream-namestream1
--limit 5
例 macOS 和 Linux(仅限)
在同一命令提示符下,macOS 和 Linux 用户可能需要运行以下命令以确保脚本可执行。
chmod -R 755 get-logs.sh
例 检索最后五个日志事件
在同一命令提示符下,运行以下脚本以获取最后五个日志事件。
./get-logs.sh
您应看到以下输出:
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
{
"events": [
{
"timestamp": 1559763003171,
"message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
"ingestionTime": 1559763003309
},
{
"timestamp": 1559763003173,
"message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
"ingestionTime": 1559763018353
},
{
"timestamp": 1559763003173,
"message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r \"key\": \"value\"\r}\n",
"ingestionTime": 1559763018353
},
{
"timestamp": 1559763003218,
"message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
"ingestionTime": 1559763018353
},
{
"timestamp": 1559763003218,
"message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
"ingestionTime": 1559763018353
}
],
"nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
"nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
删除日志
删除函数时,日志组不会自动删除。要避免无限期存储日志,请删除日志组,或配置一个保留期,在该保留期之后,日志将自动删除。