本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Lambda 遙測 API
遙測 API 可讓您的延伸項目直接從 Lambda 接收遙測資料。在函數初始化和調用期間,Lambda 會自動擷取遙測資料,包括日誌、平台指標和平台追蹤。遙測 API 使延伸項目可以近乎即時地從 Lambda 直接存取這些遙測資料。
在 Lambda 執行環境中,您可以讓 Lambda 延伸項目訂閱遙測串流。訂閱後,Lambda 會自動將所有遙測資料傳送至您的延伸項目。然後,您便能靈活處理、篩選和傳送資料到偏好目的地,例如 Amazon Simple Storage Service (Amazon S3) 儲存貯體或第三方可觀測性工具提供者。
下圖顯示延伸 API 和遙測 API 如何從執行環境中將延伸項目連結至 Lambda。另外,執行期 API 也會將執行期和函數連接至 Lambda。
![將 Lambda 連接至執行環境中處理序之延伸、遙測和執行階段 API。](images/telemetry-api-concept-diagram.png)
重要
Lambda 遙測 API 優先於 Lambda 日誌 API。雖然日誌 API 仍然正常運作,但我們建議您未來只使用遙測 API。您可以使用遙測 API 或日誌 API 訂閱遙測串流的延伸項目。使用其中一個 API 進行訂閱後,若嘗試使用其他 API 進行任何訂閱,都會傳回錯誤。
延伸項目可使用遙測 API 來訂閱三個不同的遙測串流:
-
平台遙測 – 日誌、指標和追蹤,描述與執行環境執行階段生命週期、延伸項目生命週期和函數調用相關的事件和錯誤。
-
函數日誌 – Lambda 函數程式碼產生的自訂日誌。
-
延伸項目日誌 - Lambda 延伸項目程式碼產生的自訂日誌。
注意
Lambda 會將日誌和指標傳送至 X-Ray (如果您已啟動追蹤),即使有擴充功能訂閱遙測串流也一樣。 CloudWatch
章節
使用遙測 API 建立延伸項目
Lambda 延伸項目會在執行環境中做為獨立的程序執行。延伸項目可以在函數調用完成後繼續執行。由於延伸項目為獨立的處理序,因此您可以使用與函數程式碼不同的語言來撰寫。我們建議您使用 Golang 或 Rust 等編譯語言編寫延伸項目。在這種情況下,延伸項目是獨立的二進位檔案,且與任何支援的執行階段相容。
下圖說明建立延伸項目的四步驟程序,讓延伸項目使用遙測 API 接收和處理遙測資料。
![註冊您的延伸項目、建立接聽程式、訂閱串流,然後取得遙測資料。](images/telemetry-api-creation-steps.png)
以下是各步驟的詳細說明:
-
使用 使用 Lambda 擴充功能 API 建立擴充功能 註冊延伸項目。這會為您提供
Lambda-Extension-Identifier
,接著需要在下列步驟中使用。如需有關如何註冊延伸項目的詳細資訊,請參閱:註冊延伸項目。 -
建立遙測接聽程式。這可以是基本的 HTTP 或 TCP 伺服器。Lambda 使用遙測接聽程式的 URI 來將遙測資料傳送至延伸項目。如需詳細資訊,請參閱 建立遙測接聽程式。
-
使用遙測 API 中的訂閱 API,為您的延伸項目訂閱需要的遙測串流。在此步驟中,您需要遙測接聽程式的 URI。如需詳細資訊,請參閱 將訂閱請求傳送至遙測 API。
-
透過遙測接聽程式從 Lambda 取得遙測資料。您可以對這些資料執行任何自訂處理,例如將資料分派到 Amazon S3 或外部可檢視性服務。
注意
Lambda 函數的執行環境可以在其生命週期中多次啟動和停止。一般來說,延伸項目程式碼會在函數調用期間執行,並且在關閉階段執行最多 2 秒。我們建議在遙測傳送到您的接聽程式時進行批次處理。然後,使用 Invoke
和 Shutdown
生命週期事件將每個批次傳送到所需的目的地。
註冊延伸項目
您必須先註冊 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 } }
緩衝組態設定 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
參數 | 描述 | 預設值和限制 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
記憶體中要緩衝的遙測資料量上限 (位元組)。 |
預設:262,144 下限:262,144 上限:1,048,576 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
記憶體中要緩衝的事件數目上限。 |
預設:10,000 下限:1,000 上限:10,000 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
緩衝一個批次的時間上限 (毫秒)。 |
預設: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.initReport 結構描述 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
函數調用已開始。 |
platform.start 結構描述 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
執行階段已完成處理的事件,結果為成功或失敗。 |
platform.runtimeDone 結構描述 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
函數調用報告。 |
platform.report 結構描述 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
執行時間還原已開始。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
執行時間還原已完成。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
執行時間還原報告。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
延伸項目已訂閱遙測 API。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
平台事件 |
|
Lambda 已捨棄日誌項目。 |
platform.logsDropped 結構描述 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
函數日誌 |
|
函數程式碼的日誌行。 |
function 結構描述 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
延伸項目日誌 |
|
延伸項目程式碼的日誌行。 |
extension 結構描述 |