Lambda Logs API - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

Lambda Logs API

重要

Lambda 遙測 API 優先於 Lambda 日誌 API。雖然日誌 API 仍然正常運作,但我們建議您未來只使用遙測 API。您可以使用遙測 API 或日誌 API 訂閱遙測串流的延伸項目。使用其中一個 API 進行訂閱後,若嘗試使用其他 API 進行任何訂閱,都會傳回錯誤。

Lambda 會自動擷取執行階段日誌並將其串流至 Amazon CloudWatch 此日誌串流包含函數程式碼和延伸項目產生的日誌,以及 Lambda 作為函數調用一部分產生的日誌。

Lambda 延伸項目可以使用 Lambda Runtime Logs API,直接從 Lambda 執行環境中訂閱記錄串流。Lambda 會將日誌串流至延伸項目,延伸項目隨後可處理、篩選日誌並將其傳送至任何偏好目的地。


      Extensions API 和 Logs API 會連線 Lambda 及外部延伸項目。

Logs API 允許延伸項目訂閱三種不同的日誌串流:

  • Lambda 函數產生並寫入到 stdoutstderr 的函數日誌。

  • 延伸項目程式碼產生的延伸項目日誌。

  • Lambda 平台日誌,它記錄與調用和延伸項目相關的事件和錯誤。

注意

Lambda 會將所有記錄傳送至 CloudWatch,即使擴充功能訂閱一或多個日誌串流也是如此。

訂閱接收日誌

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 的範本程式碼

如需示範如何將日誌傳送至自訂目的地的範本程式碼,請參閱 AWS 運算部落格上的使用 AWS Lambda 延伸項目將日誌傳送至自訂目的地

如需說明如何開發基本 Lambda 擴充功能及訂閱記錄 API 的 Python 和 Go 程式碼範例,請參閱AWS範例 GitHub 儲存庫上的AWS Lambda擴充功能。如需建置 Lambda 延伸項目的詳細資訊,請參閱 Lambda Extensions API

Logs API 參考

您可以從 AWS_LAMBDA_RUNTIME_API 環境變數中擷取 Logs API 端點。若要傳送 API 請求,請在 API 路徑之前使用前綴 2020-08-15/。例如:

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

應用程式介面版本的 OpenAPI 規格可在此處取得:.zip logs-api-request

訂閱

若要訂閱 Lambda 執行環境中可用的一個或多個日誌串流,延伸項目會傳送 Subscribe API 請求。

路徑/logs

方法PUT

主體參數

destination – 請參閱目的地協定。必要:是。類型:字串。

buffering – 請參閱緩衝組態。必要:否。類型:字串。

types - 要接收的日誌類型陣列。必要:是。類型:字串陣列。有效值:「平台」、「函數」、「延伸項目」。

schemaVersion - 必要:否。預設值:"2020-08-15"。將延伸項目設定為 "2021-03-18",可接收 platform.runtimeDone 訊息。

回應參數

訂閱回應的 OpenAPI 規範 (版本 2020-08-15),適用於 HTTP 和 TCP 通訊協定:

回應代碼
  • 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": "ERROR encountered. Stack trace:\n\my-function (line 10)\n" }

延伸項目日誌

延伸項目可產生延伸日誌。日誌格式與函數日誌的格式相同。

平台日誌

Lambda 會產生平台事件 (例如 platform.startplatform.end 以及 platform.fault) 的日誌訊息。

或者,您可以訂閱包含 platform.runtimeDone 日誌訊息的 2021-03-18 版本的 Logs API 結構描述。

平台日誌訊息範例

下面的範例顯示了平台開始和平台結束日誌。這些日誌指出 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子階段是「初始化」生命周期階段的一部分。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 欄位才會包含在日誌中。如果 AWS 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 的使用者,告知他們函數調用完成。延伸項目可以使用此資訊來決定何時傳送該調用期間收集的所有遙測。

範例

當函數調用完成時,在執行時間傳送 NEXT 請求之後,Lambda 會傳送 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" } }