Lambda 遙測 API - AWS Lambda

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

Lambda 遙測 API

遙測 API 可讓您的延伸項目直接從 Lambda 接收遙測資料。在函數初始化和調用期間,Lambda 會自動擷取遙測資料,包括日誌、平台指標和平台追蹤。遙測 API 使延伸項目可以近乎即時地從 Lambda 直接存取這些遙測資料。

在 Lambda 執行環境中,您可以讓 Lambda 延伸項目訂閱遙測串流。訂閱後,Lambda 會自動將所有遙測資料傳送至您的延伸項目。然後,您便能靈活處理、篩選和傳送資料到偏好目的地,例如 Amazon Simple Storage Service (Amazon S3) 儲存貯體或第三方可觀測性工具提供者。

下圖顯示延伸 API 和遙測 API 如何從執行環境中將延伸項目連結至 Lambda。另外,執行期 API 也會將執行期和函數連接至 Lambda。

將 Lambda 連接至執行環境中處理序之延伸、遙測和執行階段 API。
重要

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

延伸項目可使用遙測 API 來訂閱三個不同的遙測串流:

  • 平台遙測 – 日誌、指標和追蹤,描述與執行環境執行階段生命週期、延伸項目生命週期和函數調用相關的事件和錯誤。

  • 函數日誌 – Lambda 函數程式碼產生的自訂日誌。

  • 延伸項目日誌 - Lambda 延伸項目程式碼產生的自訂日誌。

注意

Lambda 會將日誌和指標傳送至 X-Ray (如果您已啟動追蹤),即使有擴充功能訂閱遙測串流也一樣。 CloudWatch

使用遙測 API 建立延伸項目

Lambda 延伸項目會在執行環境中做為獨立的程序執行。延伸項目可以在函數調用完成後繼續執行。由於延伸項目為獨立的處理序,因此您可以使用與函數程式碼不同的語言來撰寫。我們建議您使用 Golang 或 Rust 等編譯語言編寫延伸項目。在這種情況下,延伸項目是獨立的二進位檔案,且與任何支援的執行階段相容。

下圖說明建立延伸項目的四步驟程序,讓延伸項目使用遙測 API 接收和處理遙測資料。

註冊您的延伸項目、建立接聽程式、訂閱串流,然後取得遙測資料。

以下是各步驟的詳細說明:

  1. 使用 使用 Lambda 擴充功能 API 建立擴充功能 註冊延伸項目。這會為您提供 Lambda-Extension-Identifier,接著需要在下列步驟中使用。如需有關如何註冊延伸項目的詳細資訊,請參閱:註冊延伸項目

  2. 建立遙測接聽程式。這可以是基本的 HTTP 或 TCP 伺服器。Lambda 使用遙測接聽程式的 URI 來將遙測資料傳送至延伸項目。如需詳細資訊,請參閱 建立遙測接聽程式

  3. 使用遙測 API 中的訂閱 API,為您的延伸項目訂閱需要的遙測串流。在此步驟中,您需要遙測接聽程式的 URI。如需詳細資訊,請參閱 將訂閱請求傳送至遙測 API

  4. 透過遙測接聽程式從 Lambda 取得遙測資料。您可以對這些資料執行任何自訂處理,例如將資料分派到 Amazon S3 或外部可檢視性服務。

注意

Lambda 函數的執行環境可以在其生命週期中多次啟動和停止。一般來說,延伸項目程式碼會在函數調用期間執行,並且在關閉階段執行最多 2 秒。我們建議在遙測傳送到您的接聽程式時進行批次處理。然後,使用 InvokeShutdown 生命週期事件將每個批次傳送到所需的目的地。

註冊延伸項目

您必須先註冊 Lambda 延伸項目,才能訂閱遙測資料。註冊會在延伸功能初始化階段進行。下列範例顯示註冊延伸項目的 HTTP 請求。

POST http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register Lambda-Extension-Name: lambda_extension_name { 'events': [ 'INVOKE', 'SHUTDOWN'] }

如果請求成功,訂閱者會收到 HTTP 200 成功回應。回應標頭包含 Lambda-Extension-Identifier。回應內文包含函數的其他屬性。

HTTP/1.1 200 OK Lambda-Extension-Identifier: a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 { "functionName": "lambda_function", "functionVersion": "$LATEST", "handler": "lambda_handler", "accountId": "123456789012" }

如需更多資訊,請參閱 Extensions API 參考

建立遙測接聽程式

Lambda 延伸項目必須具有可處理遙測 API 所傳入請求的接聽程式。下列程式碼顯示以 Golang 實作的遙測接聽程式實作範例:

// Starts the server in a goroutine where the log events will be sent func (s *TelemetryApiListener) Start() (string, error) { address := listenOnAddress() l.Info("[listener:Start] Starting on address", address) s.httpServer = &http.Server{Addr: address} http.HandleFunc("/", s.http_handler) go func() { err := s.httpServer.ListenAndServe() if err != http.ErrServerClosed { l.Error("[listener:goroutine] Unexpected stop on Http Server:", err) s.Shutdown() } else { l.Info("[listener:goroutine] Http Server closed:", err) } }() return fmt.Sprintf("http://%s/", address), nil } // http_handler handles the requests coming from the Telemetry API. // Everytime Telemetry API sends log events, this function will read them from the response body // and put into a synchronous queue to be dispatched later. // Logging or printing besides the error cases below is not recommended if you have subscribed to // receive extension logs. Otherwise, logging here will cause Telemetry API to send new logs for // the printed lines which may create an infinite loop. func (s *TelemetryApiListener) http_handler(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { l.Error("[listener:http_handler] Error reading body:", err) return } // Parse and put the log messages into the queue var slice []interface{} _ = json.Unmarshal(body, &slice) for _, el := range slice { s.LogEventsQueue.Put(el) } l.Info("[listener:http_handler] logEvents received:", len(slice), " LogEventsQueue length:", s.LogEventsQueue.Len()) slice = nil }

指定目的地通訊協定

使用遙測 API 訂閱以接收遙測資料時,除了目的地 URI 之外,您還可以指定目的地通訊協定:

{ "destination": { "protocol": "HTTP", "URI": "http://sandbox.localdomain:8080" } }

Lambda 接受兩種通訊協定用於接收遙測資料:

  • HTTP (建議) - Lambda 會以 JSON 格式的記錄陣列將遙測資料傳遞至本機 HTTP 端點 (http://sandbox.localdomain:${PORT}/${PATH})。$PATH 為選用參數。Lambda 僅支援 HTTP,不支援 HTTPS。Lambda 會透過 POST 請求傳遞遙測資料。

  • TCP - Lambda 使用以換行分隔的 JSON (NDJSON) 格式將遙測資料傳遞至 TCP 連接埠。

注意

強烈建議使用 HTTP,而不是使用 TCP。若使用 TCP,Lambda 平台無法確認何時將遙測資料傳遞至應用程式層。因此,如果您的延伸項目損毀,遙測資料可能會遺失。HTTP 沒有此限制。

訂閱以接收遙測資料之前,需先建立本機 HTTP 接聽程式或 TCP 連接埠。在設定期間,請注意下列事項:

  • Lambda 只會將遙測資料傳送至執行環境內的目的地。

  • 如果沒有接聽程式,或者如果 POST 請求遇到錯誤,則 Lambda 會重新嘗試傳送遙測資料 (使用回詢)。如果遙測接聽程式損毀,會在 Lambda 重新啟動執行環境之後繼續接收遙測資料。

  • Lambda 保留連接埠 9001。沒有其他連接埠編號限制或建議。

設定記憶體使用量和緩衝

隨著訂閱用戶數量增加,執行環境的記憶體使用量會線性增加。訂閱會耗用記憶體資源,因為每個訂閱都會開啟新的記憶體緩衝區來存放遙測資料。緩衝區記憶體用量會計入執行環境中的整體記憶體耗用量。

透過遙測 API 來訂閱以接收遙測資料時,您可以選擇先緩衝遙測資料再批次傳遞給訂閱用戶。若要最佳化記憶體用量,您可以指定緩衝組態:

{ "buffering": { "maxBytes": 256*1024, "maxItems": 1000, "timeoutMs": 100 } }
緩衝組態設定
參數 描述 預設值和限制

maxBytes

記憶體中要緩衝的遙測資料量上限 (位元組)。

預設:262,144

下限:262,144

上限:1,048,576

maxItems

記憶體中要緩衝的事件數目上限。

預設:10,000

下限:1,000

上限:10,000

timeoutMs

緩衝一個批次的時間上限 (毫秒)。

預設:1,000

下限:25

上限:30,000

當設定緩衝時,請記住以下幾點:

  • 如果有任何輸入串流關閉,則 Lambda 會排清日誌。例如,如果執行期損毀,就可能會發生這種情況。

  • 每個訂閱用戶可以在訂閱請求中自訂其緩衝組態。

  • 決定讀取資料的緩衝區大小時,請預期接收的有效負載大小為 2 * maxBytes + metadataBytes (其中 maxBytes 是緩衝設定的元件)。若要評估要考量的 metadataBytes 數量,請檢閱下列中繼資料。Lambda 會將類似的中繼資料新增至每筆記錄:

    { "time": "2022-08-20T12:31:32.123Z", "type": "function", "record": "Hello World" }
  • 如果訂閱者處理傳入遙測資料的速度不夠快,或是函數程式碼產生了極大量的日誌,Lambda 可能會捨棄記錄,以確保記憶體使用率維持在限制範圍內。發生這種情況時,Lambda 會傳送 platform.logsDropped 事件。

將訂閱請求傳送至遙測 API

Lambda 延伸項目可透過將訂閱請求傳送至遙測 API 來訂閱以接收遙測資料。訂閱請求應包含您希望延伸項目訂閱的事件類型相關資訊。此外,請求可以包含傳遞目的地資訊緩衝組態

傳送訂閱請求之前,您必須有延伸功能 ID (Lambda-Extension-Identifier)。向延伸 API 註冊您的延伸項目時,您可從 API 回應中取得延伸項目 ID。

訂閱會在延伸項目初始化階段進行。下列範例顯示訂閱全部三個遙測串流的 HTTP 請求:平台遙測、函數日誌和延伸項目日誌。

PUT http://${AWS_LAMBDA_RUNTIME_API}/2022-07-01/telemetry HTTP/1.1 { "schemaVersion": "2022-12-13", "types": [ "platform", "function", "extension" ], "buffering": { "maxItems": 1000, "maxBytes": 256*1024, "timeoutMs": 100 }, "destination": { "protocol": "HTTP", "URI": "http://sandbox.localdomain:8080" } }

如果請求成功,訂閱者會收到 HTTP 200 成功回應。

HTTP/1.1 200 OK "OK"

輸入遙測 API 訊息

使用遙測 API 訂閱之後,延伸項目會自動透過 POST 請求開始接收來自 Lambda 的遙測資料。每個 POST 請求主體包含 Event 對象的數組。每個 Event 項目都有以下結構描述:

{ time: String, type: String, record: Object }
  • time 屬性定義了 Lambda 平台產生事件的時間。這與事件實際發生的時間不同。time 的字串值是 ISO 8601 格式的時間戳記。

  • type 屬性定義了事件類型。下表說明所有可能的值。

  • record 屬性定義了包含遙測資料的 JSON 物件。此 JSON 物件的結構描述取決於 type

下表摘要說明 Event 物件的所有類型,以及每個事件類型之遙測 API Event 結構描述參考的連結。

遙測 API 訊息類型
類別 事件類型 描述 事件記錄結構描述

平台事件

platform.initStart

函數初始化已開始。

platform.initStart 結構描述

平台事件

platform.initRuntimeDone

函數初始化已完成。

platform.initRuntimeDone 結構描述

平台事件

platform.initReport

函數初始化報告。

platform.initReport 結構描述

平台事件

platform.start

函數調用已開始。

platform.start 結構描述

平台事件

platform.runtimeDone

執行階段已完成處理的事件,結果為成功或失敗。

platform.runtimeDone 結構描述

平台事件

platform.report

函數調用報告。

platform.report 結構描述

平台事件

platform.restoreStart

執行時間還原已開始。

platform.restoreStart 結構描述

平台事件

platform.restoreRuntimeDone

執行時間還原已完成。

platform.restoreRuntimeDone 結構描述

平台事件

platform.restoreReport

執行時間還原報告。

platform.restoreReport 結構描述

平台事件

platform.telemetrySubscription

延伸項目已訂閱遙測 API。

platform.telemetrySubscription 結構描述

平台事件

platform.logsDropped

Lambda 已捨棄日誌項目。

platform.logsDropped 結構描述

函數日誌

function

函數程式碼的日誌行。

function 結構描述

延伸項目日誌

extension

延伸項目程式碼的日誌行。

extension 結構描述