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

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

Lambda Logs API

重要

Lambda 遥测 API 取代 Lambda Logs API。尽管 Logs API 仍然功能完备,但我们建议您今后仅使用遥测 API。您可以使用遥测 API 或 Logs API 为扩展订阅遥测流。使用其中一个 API 进行订阅后,任何使用其他 API 进行订阅的尝试都会返回错误。

Lambda 会自动捕获运行时日志并将其流式传输到亚马逊。 CloudWatch此日志流包含函数代码和扩展生成的日志,以及 Lambda 作为函数调用的一部分生成的日志。

Lambda 扩展可以使用 Lambda Runtime Logs API 从 Lambda 执行环境中直接订阅日志流。Lambda 将日志流式传输到扩展,便于扩展处理、筛选日志并将其发送到首选目标。


      Extensions API 与 Logs API 连接 Lambda 和外部扩展。

Logs API 允许扩展订阅三种不同的日志流:

  • Lambda 函数生成并写入 stdoutstderr 的函数日志。

  • 扩展代码生成的扩展日志。

  • Lambda 平台日志,记录与调用和扩展相关的事件和错误。

注意

即使扩展订阅了一个或多个日志 CloudWatch流,Lambda 也会将所有日志发送到。

订阅接收日志

Lambda 扩展可以通过向 Logs API 发送订阅请求来订阅接收日志。

要订阅接收日志,则需要扩展标识符 (Lambda-Extension-Identifier)。首先,注册扩展以接收扩展标识符。然后,在初始化期间订阅 Logs API。初始化阶段完成后,Lambda 不会处理订阅请求。

注意

Logs API 订阅是幂等的。重复的订阅请求不会导致重复订阅。

内存使用量

内存使用量随着订阅者数量的增加而线性增加。订阅会消耗内存资源,因为每个订阅都会打开一个新的内存缓冲区来存储日志。为了帮助优化内存使用量,您可以调整缓冲配置。缓冲区内存使用量计入执行环境中的总内存消耗量。

目标协议

您可以选择以下协议之一来接收日志:

  1. HTTP(推荐)– Lambda 会将日志作为 JSON 格式的记录数组传送到本地 HTTP 端点 (http://sandbox.localdomain:${PORT}/${PATH})。$PATH 参数是可选的。请注意,只支持 HTTP,不支持 HTTPS。您可以选择通过 PUT 或 POST 来接收日志。

  2. TCP – Lambda 会将日志以换行符分隔的 JSON (NDJSON) 格式传送到 TCP 端口。

我们建议使用 HTTP 而不是 TCP。使用 TCP 时,Lambda 平台无法在其将日志传送到应用层时进行确认。因此,如果扩展崩溃,日志可能会丢失。HTTP 则无此限制。

我们还建议在订阅接收日志之前设置本地 HTTP 侦听器或 TCP 端口。在安装期间,请注意以下事项:

  • Lambda 只会将日志发送到执行环境内的目标。

  • 如果没有侦听器,或者 POST 或 PUT 请求导致错误,Lambda 会尝试重试发送日志(退避尝试)。如果日志订阅者崩溃,它会在 Lambda 重新启动执行环境后继续接收日志。

  • Lambda 会预留端口 9001。没有其他端口号限制或建议。

缓冲配置

Lambda 可以缓冲日志并将其发送给订阅者。您可以通过指定以下可选字段在订阅请求中配置此行为。请注意,Lambda 对未指定的字段使用默认值。

  • timeoutMs – 缓冲批的最长时间(以毫秒为单位)。默认值:1,000。最低:25。最大值:30,000。

  • maxBytes – 在内存中缓冲的最大大小(以字节为单位)。默认值:262,144。最小值:262,144。最大值:1,048,576。

  • maxItems – 在内存中缓冲的最大事件数。默认值:10,000。最小值:1,000。最大值:10,000。

在缓冲配置期间,请注意以下几点:

  • 如果任何输入流关闭(例如,运行时崩溃),Lambda 会刷新日志。

  • 在订阅请求中,每个订阅者都可以指定不同的缓冲配置。

  • 考虑读取数据所需的缓冲区大小。预计最多可接收 2*maxBytes+metadata 的有效负载,其中,maxBytes 在订阅请求中配置。例如,Lambda 会将以下元数据字节添加到每条记录:

    { "time": "2020-08-20T12:31:32.123Z", "type": "function", "record": "Hello World" }
  • 如果订阅者处理传入日志的速度不够快,Lambda 可能会删除日志以保持内存利用率限制。为指示丢弃记录数,Lambda 会发送一个 platform.logsDropped 日志。

示例订阅

以下示例显示订阅平台和函数日志的请求。

PUT http://${AWS_LAMBDA_RUNTIME_API}/2020-08-15/logs HTTP/1.1 { "schemaVersion": "2020-08-15", "types": [ "platform", "function" ], "buffering": { "maxItems": 1000, "maxBytes": 262144, "timeoutMs": 100 }, "destination": { "protocol": "HTTP", "URI": "http://sandbox.localdomain:8080/lambda_logs" } }

如果请求成功,订阅者将收到一条 HTTP 200 成功响应。

HTTP/1.1 200 OK "OK"

Logs API 的示例代码

有关显示如何将日志发送到自定义目标的示例代码,请参阅 Amazon Lambda 计算博客上的使用 Amazon 扩展将日志发送到自定义目标

有关展示如何开发基本 Lambda 扩展和订阅日志 API 的 Python 和 Go 代码示例,请参阅Amazon示例 GitHub 存储库中的Amazon Lambda扩展。有关构建 Lambda 扩展的更多信息,请参阅 Lambda 扩展 API

Logs API 参考

您可以从 AWS_LAMBDA_RUNTIME_API 环境变量中检索 Logs API 终端节点。要发送 API 请求,请在 API 路径前使用前缀 2020-08-15/。例如:

http://${AWS_LAMBDA_RUNTIME_API}/2020-08-15/logs

日志 API 版本 2020-08-15 的 OpenAPI 规范可在此处获得:.z ip logs-api-request

订阅

要订阅一个或多个在 Lambda 执行环境中可用的日志流,扩展会发送 Subscribe API 请求。

路径/logs

方法PUT

主体参数

destination请参阅 目标协议。必需:是。类型:字符串。

buffering请参阅 缓冲配置。必需:否 类型:字符串。

types – 要接收的日志类型的数组。必需:是。类型:字符串数组。有效值:"platform"、"function"、"extension"。

schemaVersion – 必需:否。默认值:“2020-08-15”。设置为“2021-03-18”以便扩展接收 platform.runtimeDone 消息。

响应参数

提供适用于 HTTP 和 TCP 协议的订阅响应版本 2020-08-15 的 OpenAPI 规范:

响应代码
  • 200 – 已成功完成请求

  • 202 – 已接受请求。在本地测试期间响应订阅请求。

  • 4XX – 错误请求

  • 500 – 服务错误

如果请求成功,订阅者将收到一条 HTTP 200 成功响应。

HTTP/1.1 200 OK "OK"

如果请求失败,订阅者将收到一条错误响应。例如:

HTTP/1.1 400 OK { "errorType": "Logs.ValidationError", "errorMessage": URI port is not provided; types should not be empty" }

日志消息

Logs API 允许扩展订阅三种不同的日志流:

  • 函数 – Lambda 函数生成并写入 stdoutstderr 的日志。

  • 扩展 – 扩展代码生成的日志。

  • 平台 – 运行时平台生成的平台日志,用于记录与调用和扩展相关的事件和错误。

函数日志

Lambda 函数和内部扩展会生成函数日志并将其写入 stdoutstderr

以下示例显示了函数日志消息的格式。{ "time": "2020-08-20T12:31:32.123Z", "type": "function", "record": Stack trace:\n\my-function (line 10)\n" }

扩展日志

扩展可以生成扩展日志。日志格式与函数日志的格式相同。

平台日志

Lambda 会为平台事件(例如 platform.startplatform.endplatform.fault)生成日志消息。

或者,您可以订阅 2021-03-18 版本的 Logs API 架构,其中包括 platform.runtimeDone 日志消息。

示例平台日志消息

以下示例显示了平台开始日志和平台结束日志。这些日志指定了 requestId 指定的调用的调用开始时间和调用结束时间。

{ "time": "2020-08-20T12:31:32.123Z", "type": "platform.start", "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56"} } { "time": "2020-08-20T12:31:32.123Z", "type": "platform.end", "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56"} }

平台。 initRuntimeDone日志消息显示子阶段的状态,该Runtime init子阶段是 Init 生命周期阶段的一部分。Runtime init 成功后,运行时会发送 /next 运行时 API 请求(针对 on-demandprovisioned-concurrency 初始化类型)或 restore/next(针对 snap-start 初始化类型)。以下示例显示了一个成功的平台。 initRuntimeDonesnap-start初始化类型的日志消息。

{ "time":"2022-07-17T18:41:57.083Z", "type":"platform.initRuntimeDone", "record":{ "initializationType":"snap-start", "status":"success" } }

platform.initReport 日志消息显示该 Init 阶段的持续时间以及该阶段已计费的毫秒数。当初始化类型为 provisioned-concurrency 时,Lambda 会在调用期间发送此消息。当初始化类型为 snap-start 时,Lambda 会在还原快照后发送此消息。以下示例显示适用于 snap-start 初始化类型的 platform.initReport 日志消息。

{ "time":"2022-07-17T18:41:57.083Z", "type":"platform.initReport", "record":{ "initializationType":"snap-start", "metrics":{ "durationMs":731.79, "billedDurationMs":732 } } }

平台报告日志包含有关 requestId 指定的调用的指标。仅当调用包括冷启动时,initDurationMs 字段才会包含在日志中。如果 Amazon X-Ray 跟踪处于活动状态,日志会包含 X-Ray 元数据。以下示例显示了包括冷启动的调用的平台报告日志。

{ "time": "2020-08-20T12:31:32.123Z", "type": "platform.report", "record": {"requestId": "6f7f0961f83442118a7af6fe80b88d56", "metrics": {"durationMs": 101.51, "billedDurationMs": 300, "memorySizeMB": 512, "maxMemoryUsedMB": 33, "initDurationMs": 116.67 } } }

平台故障日志捕获运行时或执行环境错误。以下示例显示了平台故障日志消息。

{ "time": "2020-08-20T12:31:32.123Z", "type": "platform.fault", "record": "RequestId: d783b35e-a91d-4251-af17-035953428a2c Process exited before completing request" }

在扩展利用扩展 API 注册时,Lambda 会生成平台扩展日志。以下示例显示了平台扩展消息。

{ "time": "2020-08-20T12:31:32.123Z", "type": "platform.extension", "record": {"name": "Foo.bar", "state": "Ready", "events": ["INVOKE", "SHUTDOWN"] } }

在扩展订阅日志 API 时,Lambda 会生成平台日志订阅日志。以下示例显示了日志订阅消息。

{ "time": "2020-08-20T12:31:32.123Z", "type": "platform.logsSubscription", "record": {"name": "Foo.bar", "state": "Subscribed", "types": ["function", "platform"], } }

当扩展无法处理其接收的日志数量时,Lambda 会生成平台日志丢弃日志。以下示例显示了 platform.logsDropped 日志消息。

{ "time": "2020-08-20T12:31:32.123Z", "type": "platform.logsDropped", "record": {"reason": "Consumer seems to have fallen behind as it has not acknowledged receipt of logs.", "droppedRecords": 123, "droppedBytes" 12345 } }

platform.restoreStart 日志消息显示 Restore 阶段的开始时间(仅限 snap-start 初始化类型)。例如:

{ "time":"2022-07-17T18:43:44.782Z", "type":"platform.restoreStart", "record":{} }

platform.restoreReport 日志消息显示 Restore 阶段的持续时间以及该阶段已计费的毫秒数(仅限 snap-start 初始化类型)。例如:

{ "time":"2022-07-17T18:43:45.936Z", "type":"platform.restoreReport", "record":{ "metrics":{ "durationMs":70.87, "billedDurationMs":13 } } }

平台 runtimeDone 消息

如果在订阅请求中将架构版本设置为“2021-03-18”,则在函数调用成功完成或出现错误后,Lambda 会发送一条 platform.runtimeDone 消息。扩展可以使用此消息来停止此函数调用的所有遥测收集。

架构版本 2021-03-18 中日志事件类型的 OpenAPI 规范可从此处获得:schema-2021-03-18.zip

在运行时发送 NextError 运行时 API 请求时,Lambda 会生成 platform.runtimeDone 日志消息。platform.runtimeDone 日志会通知 Logs API 的使用者函数调用已完成。扩展可以使用此信息来决定何时发送在调用期间收集的所有遥测数据。

示例

在函数调用完成时,Lambda 会在运行时发送 NEXT 请求后发送 platform.runtimeDone 消息。以下示例显示了每个状态值的消息:成功、失败和超时。

例 成功消息示例
{ "time": "2021-02-04T20:00:05.123Z", "type": "platform.runtimeDone", "record": { "requestId":"6f7f0961f83442118a7af6fe80b88", "status": "success" } }
例 失败消息示例
{ "time": "2021-02-04T20:00:05.123Z", "type": "platform.runtimeDone", "record": { "requestId":"6f7f0961f83442118a7af6fe80b88", "status": "failure" } }
例 超时消息示例
{ "time": "2021-02-04T20:00:05.123Z", "type": "platform.runtimeDone", "record": { "requestId":"6f7f0961f83442118a7af6fe80b88", "status": "timeout" } }
例 示例平台。 restoreRuntimeDone 消息(仅限snap-start初始化类型)

平台。 restoreRuntimeDone日志消息显示该Restore阶段是否成功。当运行时发送 restore/next 运行时 API 请求时,Lambda 会发送此消息。存在三种可能的状态:成功、失败和超时。以下示例显示了一个成功的平台。 restoreRuntimeDone日志消息。

{ "time":"2022-07-17T18:43:45.936Z", "type":"platform.restoreRuntimeDone", "record":{ "status":"success" } }