記錄和監控 Python Lambda 函數 - AWS Lambda

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

記錄和監控 Python Lambda 函數

AWS Lambda 會自動監控 Lambda 函數,並將日誌項目傳送至 Amazon CloudWatch。您的 Lambda 函數隨附一個 CloudWatch 日誌日誌群組,以及每個函數執行個體的日誌串流。Lambda 執行期環境會將每次調用的詳細資訊和函數程式碼的其他輸出,傳送至日誌串流。如需 CloudWatch 日誌的詳細資訊,請參閱 搭配 Lambda 使用日 CloudWatch 誌記錄

若要從函數程式碼輸出日誌,可以使用內建 logging 模組。如需更詳細的項目,您可以使用任何寫入 stdoutstderr 的記錄程式庫。

列印至日誌

若要將基本輸出傳送至日誌,請使用您函數中的 print 方法。下列範例會記錄 CloudWatch Logs 日誌群組和串流的值,以及事件物件。

請注意,如果您的函數使用 Python print陳述式輸出日誌,Lambda 只能以純文字格式將日誌輸出傳送至 CloudWatch 日誌。若要在結構化 中擷取日誌JSON,您需要使用支援的日誌程式庫。如需更多資訊,請參閱搭配 Python 使用 Lambda 進階日誌控制項

範例 lambda_function.py
import os def lambda_handler(event, context): print('## ENVIRONMENT VARIABLES') print(os.environ['AWS_LAMBDA_LOG_GROUP_NAME']) print(os.environ['AWS_LAMBDA_LOG_STREAM_NAME']) print('## EVENT') print(event)
範例 記錄輸出
START RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95 Version: $LATEST ## ENVIRONMENT VARIABLES /aws/lambda/my-function 2023/08/31/[$LATEST]3893xmpl7fac4485b47bb75b671a283c ## EVENT {'key': 'value'} END RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95 REPORT RequestId: 8f507cfc-xmpl-4697-b07a-ac58fc914c95 Duration: 15.74 ms Billed Duration: 16 ms Memory Size: 128 MB Max Memory Used: 56 MB Init Duration: 130.49 ms XRAY TraceId: 1-5e34a614-10bdxmplf1fb44f07bc535a1 SegmentId: 07f5xmpl2d1f6f85 Sampled: true

Python 執行時間會記錄每次調用的 STARTENDREPORT 行。REPORT 行包含以下資料:

REPORT 行資料欄位
  • RequestId – 調用的唯一請求 ID。

  • 持續時間 - 函數的處理常式方法處理事件所花費的時間量。

  • 計費持續時間 - 調用的計費時間量。

  • 記憶體大小 - 分配給函數的記憶體數量。

  • 使用的記憶體上限 - 函數所使用的記憶體數量。當調用共用執行環境時,Lambda 會報告在所有調用中使用的記憶體上限。此行為可能會導致高於預期的報告值。

  • 初始化持續時間 - 對於第一個提供的請求,這是執行期載入函數並在處理常式方法之外執行程式碼所花費的時間量。

  • XRAY TraceId – 對於追蹤的請求,AWS X-Ray 追蹤 ID

  • SegmentId – 對於追蹤的請求,X-Ray 區段 ID。

  • 已取樣 - 對於追蹤的請求,這是取樣結果。

使用記錄程式庫

如需更詳細的日誌,請使用標準程式庫中的 logging 模組,或任何寫入 stdoutstderr 的第三方記錄程式庫。

對於支援的 Python 執行期,您可以選擇使用標準logging模組建立的日誌是以純文字還是 擷取JSON。如需進一步了解,請參閱 搭配 Python 使用 Lambda 進階日誌控制項

目前,所有 Python 執行期的預設日誌格式都是純文字。下列範例顯示如何在 Logs 中以純文字擷取使用標準logging模組建立的 CloudWatch 日誌輸出。

import os import logging logger = logging.getLogger() logger.setLevel("INFO") def lambda_handler(event, context): logger.info('## ENVIRONMENT VARIABLES') logger.info(os.environ['AWS_LAMBDA_LOG_GROUP_NAME']) logger.info(os.environ['AWS_LAMBDA_LOG_STREAM_NAME']) logger.info('## EVENT') logger.info(event)

來自 logger 的輸出包含記錄等級、時間戳記和請求 ID。

START RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125 Version: $LATEST [INFO] 2023-08-31T22:12:58.534Z 1c8df7d3-xmpl-46da-9778-518e6eca8125 ## ENVIRONMENT VARIABLES [INFO] 2023-08-31T22:12:58.534Z 1c8df7d3-xmpl-46da-9778-518e6eca8125 /aws/lambda/my-function [INFO] 2023-08-31T22:12:58.534Z 1c8df7d3-xmpl-46da-9778-518e6eca8125 2023/01/31/[$LATEST]1bbe51xmplb34a2788dbaa7433b0aa4d [INFO] 2023-08-31T22:12:58.535Z 1c8df7d3-xmpl-46da-9778-518e6eca8125 ## EVENT [INFO] 2023-08-31T22:12:58.535Z 1c8df7d3-xmpl-46da-9778-518e6eca8125 {'key': 'value'} END RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125 REPORT RequestId: 1c8df7d3-xmpl-46da-9778-518e6eca8125 Duration: 2.75 ms Billed Duration: 3 ms Memory Size: 128 MB Max Memory Used: 56 MB Init Duration: 113.51 ms XRAY TraceId: 1-5e34a66a-474xmpl7c2534a87870b4370 SegmentId: 073cxmpl3e442861 Sampled: true
注意

當您函數的日誌格式設定為純文字時,Python 執行時間的預設日誌層級設定為 WARN。這表示 Lambda 只會將層級 WARN和更低的日誌輸出傳送至 CloudWatch Logs。若要變更預設日誌層級,請使用 Python logging setLevel() 方法,如此範例程式碼所示。如果您將函數的日誌格式設定為 JSON,建議您使用 Lambda Advanced Logging Controls 來設定函數的日誌層級,而不是在程式碼中設定日誌層級。如需進一步了解,請參閱 搭配 Python 使用日誌層級篩選

搭配 Python 使用 Lambda 進階日誌控制項

為了讓您更妥善地控制擷取、處理和使用函數日誌的方式,您可以針對支援的 Lambda Python 執行期設定下列記錄選項:

  • 日誌格式 - 在純文字和結構化JSON格式之間選取函數日誌

  • 日誌層級 - 針對JSON格式的日誌,選擇 Lambda 傳送至 Amazon 的日誌詳細資訊層級 CloudWatch,例如 ERROR、 DEBUG或 INFO

  • 日誌群組 - 選擇函數將 CloudWatch 日誌傳送至的日誌群組

如需這些日誌選項的詳細資訊,以及如何設定函數以使用這些選項的說明,請參閱 設定 Lambda 函數的進階記錄控制項

若要進一步瞭解如何將日誌格式和日誌層級選項與 Python Lambda 函數搭配使用,請參閱以下各節中的指引。

搭配 Python 使用結構化JSON日誌

如果您JSON為函數的日誌格式選取 ,Lambda 會將 Python 標準日誌程式庫輸出的日誌以結構化 CloudWatch 方式傳送至 JSON。每個JSON日誌物件包含至少四個具有下列金鑰的金鑰值對:

  • "timestamp" - 產生日誌訊息的時間

  • "level" - 指派給訊息的日誌層級

  • "message" - 日誌訊息的內容

  • "requestId" - 進行調用的唯一請求 ID。

Python logging程式庫也可以將額外的索引鍵值對"logger"新增至此JSON物件。

以下各節的範例顯示當您將函數的日誌格式設定為 時,如何使用 Python logging程式庫產生的日誌輸出擷取在 CloudWatch 日誌中JSON。

請注意,如果您使用 print方法產生基本日誌輸出,如 中所述列印至日誌,Lambda 會將這些輸出擷取為純文字,即使您將函數的日誌格式設定為 JSON。

使用 Python JSON 日誌程式庫的標準日誌輸出

下列程式碼片段和日誌輸出範例顯示當您函數的日誌格式設定為 時,如何在 CloudWatch 日誌中擷取使用 Python logging程式庫產生的標準日誌輸出JSON。

範例 Python 日誌記錄程式碼
import logging logger = logging.getLogger() def lambda_handler(event, context): logger.info("Inside the handler function")
範例 JSON 日誌記錄
{ "timestamp":"2023-10-27T19:17:45.586Z", "level":"INFO", "message":"Inside the handler function", "logger": "root", "requestId":"79b4f56e-95b1-4643-9700-2807f4e68189" }

在 中記錄額外參數 JSON

當您函數的日誌格式設定為 時JSON,您也可以使用 extra關鍵字將 Python 字典傳遞至日誌輸出,以標準 Python logging程式庫來記錄其他參數。

範例 Python 日誌記錄程式碼
import logging def lambda_handler(event, context): logging.info( "extra parameters example", extra={"a":"b", "b": [3]}, )
範例 JSON 日誌記錄
{ "timestamp": "2023-11-02T15:26:28Z", "level": "INFO", "message": "extra parameters example", "logger": "root", "requestId": "3dbd5759-65f6-45f8-8d7d-5bdc79a3bd01", "a": "b", "b": [ 3 ] }

在 中記錄例外狀況 JSON

下列程式碼片段顯示當您將日誌格式設定為 時,如何在函數的日誌輸出中擷取 Python 例外狀況JSON。請注意,使用 產生的日誌輸出logging.exception會指派日誌層級 ERROR。

範例 Python 日誌記錄程式碼
import logging def lambda_handler(event, context): try: raise Exception("exception") except: logging.exception("msg")
範例 JSON 日誌記錄
{ "timestamp": "2023-11-02T16:18:57Z", "level": "ERROR", "message": "msg", "logger": "root", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 15, in lambda_handler\n raise Exception(\"exception\")\n" ], "errorType": "Exception", "errorMessage": "exception", "requestId": "3f9d155c-0f09-46b7-bdf1-e91dab220855", "location": "/var/task/lambda_function.py:lambda_handler:17" }

JSON 使用其他記錄工具的結構化日誌

如果您的程式碼已使用其他記錄程式庫,例如 的 Powertools AWS Lambda,來產生JSON結構化日誌,則您不需要進行任何變更。 AWS Lambda 不會對已JSON編碼的任何日誌進行雙重編碼。即使您將函數設定為使用JSON日誌格式,您的日誌輸出也會出現在您定義的JSON結構 CloudWatch 中。

下列範例顯示如何在日誌中擷取使用 Powertools for AWS Lambda Packages 產生的 CloudWatch 日誌輸出。無論您函數的日誌組態設定為 JSON或 ,此日誌輸出的格式都相同TEXT。如需針對 使用 Powertools 的詳細資訊 AWS Lambda,請參閱 針對 AWS Lambda (Python) 和 使用 Powertools AWS SAM 進行結構化記錄針對 AWS Lambda (Python) 和 使用 Powertools AWS CDK 進行結構化記錄

範例 Python 記錄程式碼程式碼片段 (使用 Powertools for AWS Lambda)
from aws_lambda_powertools import Logger logger = Logger() def lambda_handler(event, context): logger.info("Inside the handler function")
範例 JSON 日誌記錄 (使用 Powertools for AWS Lambda)
{ "level": "INFO", "location": "lambda_handler:7", "message": "Inside the handler function", "timestamp": "2023-10-31 22:38:21,010+0000", "service": "service_undefined", "xray_trace_id": "1-654181dc-65c15d6b0fecbdd1531ecb30" }

搭配 Python 使用日誌層級篩選

透過設定日誌層級篩選,您可以選擇僅將特定日誌層級或更低層級的日誌傳送至 CloudWatch 日誌。若要瞭解如何設定函數的日誌層級篩選,請參閱 日誌層級篩選

若要 AWS Lambda 讓 根據應用程式日誌層級篩選您的應用程式日誌,您的函數必須使用JSON格式化日誌。您可以透過兩種方式達成此操作:

  • 使用標準 Python logging程式庫建立日誌輸出,並將函數設定為使用JSON日誌格式。 AWS Lambda 然後在 中描述的JSON物件中使用「層級」鍵值對來篩選日誌輸出搭配 Python 使用結構化JSON日誌。若要瞭解如何設定函數的日誌格式,請參閱 設定 Lambda 函數的進階記錄控制項

  • 使用另一個日誌程式庫或方法,在您的程式碼中建立JSON結構化日誌,其中包含定義日誌輸出層級的「層級」鍵值對。例如,您可以使用 Powertools for 從程式碼 AWS Lambda 產生JSON結構化日誌輸出。

    您也可以使用列印陳述式輸出包含日誌層級識別符的JSON物件。下列列印陳述式會產生JSON格式化的輸出,其中日誌層級設定為 INFO。如果您函數的日誌層級設定為 INFO、 或 DEBUG, AWS Lambda 會將JSON物件傳送至 CloudWatch LogsTRACE。

    print('{"msg":"My log message", "level":"info"}')

若要讓 Lambda 篩選函數的日誌,您還必須在JSON日誌輸出中包含"timestamp"索引鍵值對。時間必須以有效的 RFC 3339 時間戳記格式指定。如果您沒有提供有效的時間戳記,Lambda 會指派日誌層級,INFO並為您新增時間戳記。

在 Lambda 主控台檢視日誌

您可以在調用 Lambda 函數之後,使用 Lambda 主控台來檢視日誌輸出。

如果可以從內嵌程式碼編輯器測試您的程式碼,您會在執行結果中找到日誌。使用主控台測試功能以調用函數時,您會在詳細資訊區段找到日誌輸出

在 CloudWatch 主控台中檢視日誌

您可以使用 Amazon CloudWatch 主控台來檢視所有 Lambda 函數調用的日誌。

在 CloudWatch 主控台上檢視日誌
  1. 在 CloudWatch 主控台上開啟日誌群組頁面

  2. 選擇函數的日誌群組 (/aws/lambda/your-function-name).

  3. 選擇日誌串流

每個日誌串流都會對應至函式的執行個體。當您更新 Lambda 函數,以及建立額外執行個體以處理多個並行調用時,便會出現日誌串流。若要尋找特定調用的日誌,建議您使用 測試函數 AWS X-Ray。X-Ray 會在追蹤內記錄有關請求和日誌串流的詳細資訊。

使用 檢視日誌 AWS CLI

AWS CLI 是開放原始碼工具,可讓您使用命令列 Shell 中的命令與 AWS 服務互動。若要完成本節中的步驟,您必須執行下列各項:

您可以透過 AWS CLI,使用 --log-type 命令選項來擷取要調用的日誌。其回應將包含 LogResult 欄位,內含該次調用的 base64 編碼日誌 (最大達 4 KB)。

範例 擷取日誌 ID

下列範例顯示如何從名稱為 my-function 的函數的 LogResult 欄位來擷取日誌 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

如果您使用的是 第 2 AWS CLI 版,則需要 cli-binary-format選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》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 Windows 上使用。macOS 使用者可能需要使用 base64 -D

範例 get-logs.sh 指令碼

在相同的命令提示中,使用下列指令碼下載最後五個日誌事件。該指令碼使用 sed 以從輸出檔案移除引述,並休眠 15 秒以使日誌可供使用。輸出包括來自 Lambda 的回應以及來自 get-log-events 命令的輸出。

複製下列程式碼範例的內容,並將您的 Lambda 專案目錄儲存為 get-logs.sh

如果您使用的是 第 2 AWS CLI 版,則需要 cli-binary-format選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》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-name stream1 --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" }

刪除日誌

當您刪除函數時,不會自動刪除日誌群組。若要避免無限期地儲存日誌,請刪除日誌群組,或設定保留期間,系統會在該時間之後自動刪除日誌。

使用其他記錄工具和程式庫

Powertools for AWS Lambda (Python) 是一種開發人員工具組,可實作無伺服器最佳實務並提高開發人員速度。Logger 公用程式提供 Lambda 最佳化的記錄器,其中包含有關輸出結構為 之所有函數的函數內容的其他資訊JSON。使用此公用程式執行下列操作:

  • 從 Lambda 內容、冷啟動和將輸出記錄為 JSON

  • 在收到指示時記錄 Lambda 調用事件 (預設為停用)

  • 透過日誌採樣僅列印調用百分比的所有日誌 (預設為停用)

  • 在任何時間點將其他金鑰附加至結構化日誌

  • 使用自訂日誌格式器 (自帶格式器),在與您組織的日誌相容的結構中輸出日誌 RFC

針對 AWS Lambda (Python) 和 使用 Powertools AWS SAM 進行結構化記錄

請依照以下步驟操作,使用 AWS SAM透過整合式 Powertools for Python 模組,下載、建置和部署範例 Hello World Python 應用程式。此應用程式會實作基本API後端,並使用 Powertools 來發出日誌、指標和追蹤。它由 Amazon API Gateway 端點和 Lambda 函數組成。當您傳送GET請求至API閘道端點時,Lambda 函數會叫用、使用內嵌指標格式將日誌和指標傳送至 CloudWatch,並將追蹤傳送至 AWS X-Ray。該函數會傳回 hello world 訊息。

必要條件

若要完成本節中的步驟,您必須執行下列各項:

部署範例 AWS SAM 應用程式
  1. 使用 Hello World Python 範本來初始化應用程式。

    sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.9 --no-tracing
  2. 建置應用程式。

    cd sam-app && sam build
  3. 部署應用程式。

    sam deploy --guided
  4. 依照螢幕上的提示操作。若要接受互動體驗中提供的預設選項,請按下 Enter

    注意

    對於 HelloWorldFunction 可能未定義授權,這是否正常?,請務必輸入 y

  5. 取得URL已部署應用程式的 :

    aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  6. 叫用API端點:

    curl GET <URL_FROM_PREVIOUS_STEP>

    成功的話,您將會看到以下回應:

    {"message":"hello world"}
  7. 若要獲取該函數的日誌,請執行 sam 日誌。如需詳細資訊,請參閱《AWS Serverless Application Model 開發人員指南》 中的 使用日誌

    sam logs --stack-name sam-app

    日誌輸出如下:

    2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:50.371000 INIT_START Runtime Version: python:3.9.v16 Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:07a48df201798d627f2b950f03bb227aab4a655a1d019c3296406f95937e2525 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.112000 START RequestId: d455cfc4-7704-46df-901b-2a5cce9405be Version: $LATEST 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.114000 { "level": "INFO", "location": "hello:23", "message": "Hello world API - HTTP 200", "timestamp": "2023-02-03 14:59:51,113+0000", "service": "PowertoolsHelloWorld", "cold_start": true, "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j", "function_memory_size": "128", "function_arn": "arn:aws:lambda:us-east-1:111122223333:function:sam-app-HelloWorldFunction-YBg8yfYtOc9j", "function_request_id": "d455cfc4-7704-46df-901b-2a5cce9405be", "correlation_id": "e73f8aef-5e07-436e-a30b-63e4b23f0047", "xray_trace_id": "1-63dd2166-434a12c22e1307ff2114f299" } 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.126000 { "_aws": { "Timestamp": 1675436391126, "CloudWatchMetrics": [ { "Namespace": "Powertools", "Dimensions": [ [ "function_name", "service" ] ], "Metrics": [ { "Name": "ColdStart", "Unit": "Count" } ] } ] }, "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j", "service": "PowertoolsHelloWorld", "ColdStart": [ 1.0 ] } 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.126000 { "_aws": { "Timestamp": 1675436391126, "CloudWatchMetrics": [ { "Namespace": "Powertools", "Dimensions": [ [ "service" ] ], "Metrics": [ { "Name": "HelloWorldInvocations", "Unit": "Count" } ] } ] }, "service": "PowertoolsHelloWorld", "HelloWorldInvocations": [ 1.0 ] } 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.128000 END RequestId: d455cfc4-7704-46df-901b-2a5cce9405be 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.128000 REPORT RequestId: d455cfc4-7704-46df-901b-2a5cce9405be Duration: 16.33 ms Billed Duration: 17 ms Memory Size: 128 MB Max Memory Used: 64 MB Init Duration: 739.46 ms XRAY TraceId: 1-63dd2166-434a12c22e1307ff2114f299 SegmentId: 3c5d18d735a1ced0 Sampled: true
  8. 這是可透過網際網路存取的公有API端點。建議您在測試後刪除端點。

    sam delete

管理日誌保留

當您刪除函數時,不會自動刪除日誌群組。若要避免無限期儲存日誌,請刪除日誌群組,或設定保留期,之後 CloudWatch 會自動刪除日誌。若要設定日誌保留,請將下列項目新增至您的 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

針對 AWS Lambda (Python) 和 使用 Powertools AWS CDK 進行結構化記錄

請依照下列步驟,使用 下載、建置和部署範例 Hello World Python 應用程式,其中包含適用於 AWS Lambda (Python) 模組的整合式 Powertools AWS CDK。此應用程式會實作基本API後端,並使用 Powertools 來發出日誌、指標和追蹤。它由 Amazon API Gateway 端點和 Lambda 函數組成。當您傳送GET請求至API閘道端點時,Lambda 函數會叫用、使用內嵌指標格式將日誌和指標傳送至 CloudWatch,並將追蹤傳送至 AWS X-Ray。函數會傳回 hello world 訊息。

必要條件

若要完成本節中的步驟,您必須執行下列各項:

部署範例 AWS CDK 應用程式
  1. 為您的新應用程式建立專案目錄。

    mkdir hello-world cd hello-world
  2. 初始化應用程式。

    cdk init app --language python
  3. 安裝 Python 相依項。

    pip install -r requirements.txt
  4. 在根資料夾下建立 lambda_function 目錄。

    mkdir lambda_function cd lambda_function
  5. 建立檔案 app.py,並將下列程式碼新增至檔案。這是 Lambda 函數的程式碼。

    from aws_lambda_powertools.event_handler import APIGatewayRestResolver from aws_lambda_powertools.utilities.typing import LambdaContext from aws_lambda_powertools.logging import correlation_paths from aws_lambda_powertools import Logger from aws_lambda_powertools import Tracer from aws_lambda_powertools import Metrics from aws_lambda_powertools.metrics import MetricUnit app = APIGatewayRestResolver() tracer = Tracer() logger = Logger() metrics = Metrics(namespace="PowertoolsSample") @app.get("/hello") @tracer.capture_method def hello(): # adding custom metrics # See: https://docs.powertools.aws.dev/lambda-python/latest/core/metrics/ metrics.add_metric(name="HelloWorldInvocations", unit=MetricUnit.Count, value=1) # structured log # See: https://docs.powertools.aws.dev/lambda-python/latest/core/logger/ logger.info("Hello world API - HTTP 200") return {"message": "hello world"} # Enrich logging with contextual information from Lambda @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST) # Adding tracer # See: https://docs.powertools.aws.dev/lambda-python/latest/core/tracer/ @tracer.capture_lambda_handler # ensures metrics are flushed upon request completion/failure and capturing ColdStart metric @metrics.log_metrics(capture_cold_start_metric=True) def lambda_handler(event: dict, context: LambdaContext) -> dict: return app.resolve(event, context)
  6. 開啟 hello_world 目錄。您應看到名稱為 hello_world_stack.py 的檔案。

    cd .. cd hello_world
  7. 開啟 hello_world_stack.py,並將下列程式碼新增至檔案。這包含 Lambda Constructor ,其會建立 Lambda 函數、設定 Powertools 的環境變數,並將日誌保留設定為一週,以及 ApiGatewayv1 個建構器 ,其會建立 REST API。

    from aws_cdk import ( Stack, aws_apigateway as apigwv1, aws_lambda as lambda_, CfnOutput, Duration ) from constructs import Construct class HelloWorldStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Powertools Lambda Layer powertools_layer = lambda_.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", # At the moment we wrote this example, the aws_lambda_python_alpha CDK constructor is in Alpha, o we use layer to make the example simpler # See https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_lambda_python_alpha/README.html # Check all Powertools layers versions here: https://docs.powertools.aws.dev/lambda-python/latest/#lambda-layer layer_version_arn=f"arn:aws:lambda:{self.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:21" ) function = lambda_.Function(self, 'sample-app-lambda', runtime=lambda_.Runtime.PYTHON_3_9, layers=[powertools_layer], code = lambda_.Code.from_asset("./lambda_function/"), handler="app.lambda_handler", memory_size=128, timeout=Duration.seconds(3), architecture=lambda_.Architecture.X86_64, environment={ "POWERTOOLS_SERVICE_NAME": "PowertoolsHelloWorld", "POWERTOOLS_METRICS_NAMESPACE": "PowertoolsSample", "LOG_LEVEL": "INFO" } ) apigw = apigwv1.RestApi(self, "PowertoolsAPI", deploy_options=apigwv1.StageOptions(stage_name="dev")) hello_api = apigw.root.add_resource("hello") hello_api.add_method("GET", apigwv1.LambdaIntegration(function, proxy=True)) CfnOutput(self, "apiUrl", value=f"{apigw.url}hello")
  8. 部署您的應用程式。

    cd .. cdk deploy
  9. 取得URL部署應用程式的 :

    aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`apiUrl`].OutputValue' --output text
  10. 叫用API端點:

    curl GET <URL_FROM_PREVIOUS_STEP>

    成功的話,您將會看到以下回應:

    {"message":"hello world"}
  11. 若要獲取該函數的日誌,請執行 sam 日誌。如需詳細資訊,請參閱《AWS Serverless Application Model 開發人員指南》 中的 使用日誌

    sam logs --stack-name HelloWorldStack

    日誌輸出如下:

    2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:50.371000 INIT_START Runtime Version: python:3.9.v16 Runtime Version ARN: arn:aws:lambda:us-east-1::runtime:07a48df201798d627f2b950f03bb227aab4a655a1d019c3296406f95937e2525 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.112000 START RequestId: d455cfc4-7704-46df-901b-2a5cce9405be Version: $LATEST 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.114000 { "level": "INFO", "location": "hello:23", "message": "Hello world API - HTTP 200", "timestamp": "2023-02-03 14:59:51,113+0000", "service": "PowertoolsHelloWorld", "cold_start": true, "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j", "function_memory_size": "128", "function_arn": "arn:aws:lambda:us-east-1:111122223333:function:sam-app-HelloWorldFunction-YBg8yfYtOc9j", "function_request_id": "d455cfc4-7704-46df-901b-2a5cce9405be", "correlation_id": "e73f8aef-5e07-436e-a30b-63e4b23f0047", "xray_trace_id": "1-63dd2166-434a12c22e1307ff2114f299" } 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.126000 { "_aws": { "Timestamp": 1675436391126, "CloudWatchMetrics": [ { "Namespace": "Powertools", "Dimensions": [ [ "function_name", "service" ] ], "Metrics": [ { "Name": "ColdStart", "Unit": "Count" } ] } ] }, "function_name": "sam-app-HelloWorldFunction-YBg8yfYtOc9j", "service": "PowertoolsHelloWorld", "ColdStart": [ 1.0 ] } 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.126000 { "_aws": { "Timestamp": 1675436391126, "CloudWatchMetrics": [ { "Namespace": "Powertools", "Dimensions": [ [ "service" ] ], "Metrics": [ { "Name": "HelloWorldInvocations", "Unit": "Count" } ] } ] }, "service": "PowertoolsHelloWorld", "HelloWorldInvocations": [ 1.0 ] } 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.128000 END RequestId: d455cfc4-7704-46df-901b-2a5cce9405be 2023/02/03/[$LATEST]ea9a64ec87294bf6bbc9026c05a01e04 2023-02-03T14:59:51.128000 REPORT RequestId: d455cfc4-7704-46df-901b-2a5cce9405be Duration: 16.33 ms Billed Duration: 17 ms Memory Size: 128 MB Max Memory Used: 64 MB Init Duration: 739.46 ms XRAY TraceId: 1-63dd2166-434a12c22e1307ff2114f299 SegmentId: 3c5d18d735a1ced0 Sampled: true
  12. 這是可透過網際網路存取的公有API端點。建議您在測試後刪除端點。

    cdk destroy