

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

# 擷取 Lambda 非同步調用的記錄
<a name="invocation-async-retain-records"></a>

Lambda 可以將非同步調用的記錄傳送到下列其中一項 AWS 服務。
+ **Amazon SQS**：標準 SQS 佇列
+ **Amazon SNS**：標準 SNS 主題
+ **Amazon S3**：Amazon S3 儲存貯體 (僅限失敗時)
+ **AWS Lambda**：Lambda 函數
+ **Amazon EventBridge**：EventBridge 事件匯流排

呼叫記錄包含請求和回應 (JSON 格式) 的詳細資訊。您可以為成功處理的事件及所有處理嘗試皆失敗的事件設定個別目標。或者，您可以將標準 Amazon SQS 佇列或標準 Amazon SNS 主題設為捨棄事件的無效字母佇列。針對無效字母佇列，Lambda 只會傳送事件的內容，而不包含回應的詳細資訊。

如果 Lambda 無法將記錄傳送到您設定的目的地，便會將 `DestinationDeliveryFailures` 指標傳送至 Amazon CloudWatch。如果您的組態中包含不受支援的目的地類型 (例如 Amazon SQS FIFO 佇列或 Amazon SNS FIFO 主題)，就可能發生這種情形。傳遞錯誤也可能因許可錯誤和大小限制而發生。如需 Lambda 調用指標的詳細資訊，請參閱：[呼叫指標](monitoring-metrics-types.md#invocation-metrics)

**注意**  
為了防止函數觸發，您可以將函數的預留並行設為零。當您將非同步調用函數的預留並行設定為零時，Lambda 會開始將新事件傳送至設定的[無效字母佇列](#invocation-dlq)或失敗時的[事件目的地](#invocation-async-destinations)，不會進行任何重試。若要處理在預留並行設定為零時傳送的事件，您必須使用來自無效字母佇列或失敗時的事件目的地之事件。

## 新增目的地
<a name="invocation-async-destinations"></a>

若要保留非同步調用的記錄，請將目的地新增至您的函數。您可以選擇將成功或失敗的調用傳送至目的地。每個函數都可以有多個目的地，因此您可以為成功和失敗的事件配置單獨的目的地。傳送至目的地的每筆記錄都是包含調用之詳細資訊的 JSON 文件。與錯誤處理設定相似，您可以設定函數、函數版本或是別名的目標。

**提示**  
您也可以保留下列事件來源映射類型的呼叫失敗記錄：[Amazon Kinesis](kinesis-on-failure-destination.md#kinesis-on-failure-destination-console)、[Amazon DynamoDB](services-dynamodb-errors.md) 和 [Apache Kafka (Amazon MSK 和自我管理 Apache Kafka)](kafka-on-failure.md#kafka-onfailure-destination)。<a name="destinations-permissions"></a>

以下資料表列出針對非同步調用記錄支援的目的地。若要讓 Lambda 成功將記錄傳送至您選擇的目的地，請確定函數的[執行角色](lambda-intro-execution-role.md)也包含相關許可。此資料表也說明每個目的地類型如何接收 JSON 調用記錄。


| 目的地類型 | 所需的許可 | 目的地特定 JSON 格式 | 
| --- | --- | --- | 
|  Amazon SQS 佇列  |  [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)  |  Lambda 會將調用記錄做為 `Message` 傳遞至目的地。  | 
|  Amazon SNS 主題  |  [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)  |  Lambda 會將調用記錄做為 `Message` 傳遞至目的地。  | 
|  Amazon S3 儲存貯體 (僅限失敗時)  |  [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/invocation-async-retain-records.html)  | 
|  Lambda 函式  |  [lambda:InvokeFunction](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  Lambda 傳遞調用記錄會以承載形式傳遞給函數。  | 
|  EventBridge  |  [events:PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/invocation-async-retain-records.html)  | 

**注意**  
對於 Amazon S3 目的地，如果您已使用 KMS 金鑰在相應儲存貯體上啟用加密，則函數也需要 [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 許可。

**重要**  
若以 Amazon SNS 為目的地，注意 Amazon SNS 的訊息大小上限為 256 KB。若非同步調用承載接近 1 MB，則調用記錄 (包含原始承載與額外中繼資料) 可能會超過 Amazon SNS 的上限，導致傳送失敗。建議將 Amazon SQS 或 Amazon S3 用作較大承載的目的地。

以下步驟說明如何使用 Lambda 主控台和 AWS CLI為函式設定目的地。

------
#### [ Console ]

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 在**函數概觀下**，選擇**新增目的地**。

1. 針對**來源**，選擇**非同步調用**。

1. 如為**條件**，請從下列選項中選擇：
   + **On failure** (失敗時) - 當事件的所有處理嘗試都失敗，或超過存留期上限時，傳送記錄。
   + **成功時** - 當函數成功處理非同步調用時傳送記錄。

1. 對於**目的地類型**，請選擇接收調用記錄的資源類型。

1. 對於**目的地**，請選擇一個資源。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

若要使用 設定目的地 AWS CLI，請執行 [update-function-event-invoke-config](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-event-invoke-config.html) 命令。下列範例會將 Lambda 設定為在無法處理事件時，將記錄傳送至名為 `destination` 的標準 SQS 佇列。

```
aws lambda update-function-event-invoke-config \
  --function-name my-function \
  --destination-config '{"OnFailure":{"Destination": "arn:aws:sqs:us-east-1:123456789012:destination"}}'
```

------

### Amazon S3 目的地的安全最佳實務
<a name="s3-destination-security"></a>

刪除已設定為目的地的 S3 儲存貯體而不從函數的組態中移除目的地，可能會產生安全風險。如果其他使用者知道目的地儲存貯體的名稱，他們可以在其 AWS 帳戶中重新建立儲存貯體。失敗調用的記錄會被傳送到其儲存貯體，可能公開來自您函數的資料。

**警告**  
為了確保無法將函數的調用記錄傳送到另一個 中的 S3 儲存貯體 AWS 帳戶，請將條件新增至函數的執行角色，以限制您帳戶中儲存貯體的`s3:PutObject`許可。

下列範例顯示的 IAM 政策，將函數的 `s3:PutObject` 許可限制為帳戶中的儲存貯體。此政策也為 Lambda 提供了使用 S3 儲存貯體做為目的地所需的 `s3:ListBucket` 許可。

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3BucketResourceAccountWrite",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::*/*",
                "arn:aws:s3:::*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:ResourceAccount": "111122223333"
                }
            }
        }
    ]
}
```

若要使用 AWS 管理主控台 或 將許可政策新增至函數的執行角色 AWS CLI，請參閱下列程序中的指示：

------
#### [ Console ]

**若要將許可政策新增至函數的執行角色 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選取您要修改其執行角色的 Lambda 函數。

1. 在**組態**索引標籤中，選擇**許可**。

1. 在**執行角色**索引標籤中，選取函數的**角色名稱**，以開啟角色的 IAM 主控台頁面。

1. 透過下列步驟將許可政策新增至角色：

   1. 在**許可政策**窗格中，選擇**新增許可** ，然後選取**建立內嵌政策**。

   1. 在**政策編輯器**中，選取 **JSON**。

   1. 將您要新增的政策貼入編輯器 (取代現有的 JSON)，然後選擇**下一步**。

   1. 在**政策詳細資訊**下，輸入**政策名稱**。

   1. 選擇**建立政策**。

------
#### [ AWS CLI ]

**若要將許可政策新增至函數的執行角色 (CLI)**

1. 建立具有所需許可的 JSON 政策文件，並將其儲存在本機目錄中。

1. 使用 IAM `put-role-policy` CLI 命令，將許可新增至函數的執行角色。從您儲存 JSON 政策文件的目錄執行下列命令，並將角色名稱、政策名稱和政策文件取代為您自己的值。

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### 調用記錄範例
<a name="destination-example-record"></a>

當調用與條件相符時，Lambda 會將包含調用之詳細資訊的 [JSON 文件](#destinations-permissions)傳送到目的地。下列範例顯示因函式錯誤而導致處理失敗三次事件的呼叫記錄。

**Example**  

```
{
    "version": "1.0",
    "timestamp": "2019-11-14T18:16:05.568Z",
    "requestContext": {
        "requestId": "e4b46cbf-b738-xmpl-8880-a18cdf61200e",
        "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function:$LATEST",
        "condition": "RetriesExhausted",
        "approximateInvokeCount": 3
    },
    "requestPayload": {
        "ORDER_IDS": [
            "9e07af03-ce31-4ff3-xmpl-36dce652cb4f",
            "637de236-e7b2-464e-xmpl-baf57f86bb53",
            "a81ddca6-2c35-45c7-xmpl-c3a03a31ed15"
        ]
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "responsePayload": {
        "errorMessage": "RequestId: e4b46cbf-b738-xmpl-8880-a18cdf61200e Process exited before completing request"
    }
}
```

呼叫記錄包含事件、回應以及記錄傳送原因的詳細資訊。

### 追蹤傳至目的地的請求
<a name="destinations-tracing"></a>

您可以使用 AWS X-Ray 查看每個請求排入佇列、由 Lambda 函數處理並傳遞至目的地服務的連接檢視。為調用函數的函數或服務啟用 X-Ray 追蹤時，Lambda 會將 X-Ray 標頭新增至請求，並將標頭傳送至目的地服務。來自上游服務的追蹤會自動連結至來自下游 Lambda 函數和目的地服務的追蹤，進而建立整個應用程式的端對端檢視。如需追蹤的詳細資訊，請參閱：[使用 視覺化 Lambda 函數叫用 AWS X-Ray](services-xray.md)。

## 新增無效字母佇列
<a name="invocation-dlq"></a>

做為[失敗目標](#invocation-async-destinations)的替代項目，您可以設定您的函數，使其具備一個無效字母佇列來儲存捨棄的事件，以供後續處理。無效字母佇列的運作方式與失敗目標相同，會在事件的所有處理嘗試失敗，或是在沒有處理的情況下過期時使用。不過，您只能在函數層級新增或移除無效字母佇列。函數版本使用與未發布版本 (\$1LATEST) 相同的無效字母佇列設定。失敗目標也支援其他目標，並會在呼叫記錄中包含函數回應的詳細資訊。

若要重新處理無效字母佇列中的事件，請將它設定為 Lambda 函數的[事件來源](invocation-eventsourcemapping.md)。或者，您可以手動擷取事件。

您可以為無效字母佇列選擇 Amazon SQS 標準佇列或 Amazon SNS 標準主題。不支援 SQS FIFO 佇列和 Amazon SNS FIFO 主題。
+ [Amazon SQS 佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html) - 佇列會保留失敗的事件，直到其遭到擷取為止。如果您希望單一實體 (例如 Lambda 函數或 CloudWatch 警示) 處理失敗的事件，請選擇 Amazon SQS 標準佇列。如需詳細資訊，請參閱[搭配 Amazon SQS 使用 Lambda](with-sqs.md)。
+ [Amazon SNS 主題](https://docs.aws.amazon.com/sns/latest/gsg/CreateTopic.html) - 主題會將失敗的事件轉送到一個或多個目的地。如果您希望多個實體對失敗的事件採取動作，請選擇 Amazon SNS 標準主題。例如，您可以設定一個主題，以將事件傳送到電子郵件地址、Lambda 函數及/或 HTTP 端點。如需詳細資訊，請參閱[使用 Amazon SNS 通知調用 Lambda 函數](with-sns.md)。

若要將事件傳送到佇列或主題，您的函式需要額外許可。將具有[所需許可](#destinations-permissions)的政策新增到您函數的[執行角色](lambda-intro-execution-role.md)。如果目標佇列或主題使用客戶受管 AWS KMS 金鑰加密，請確定函數的執行角色和金鑰[的資源型政策](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)都包含相關許可。

在建立目標及更新函式的執行角色之後，將無效字母佇列新增到您的函式。您可以設定多個函式來將事件傳送到相同的目標。

------
#### [ Console ]

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇一個函數。

1. 選擇**組態**，然後選擇**非同步調用**。

1. 在**非同步調用**下方，選擇**編輯**。

1. 將**無效字母佇列服務**設定為 **Amazon SQS** 或 **Amazon SNS**。

1. 選擇目標佇列或主題。

1. 選擇**儲存**。

------
#### [ AWS CLI ]

若要使用 設定無效字母佇列 AWS CLI，請使用 [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) 命令。

```
aws lambda update-function-configuration \
  --function-name my-function \
  --dead-letter-config TargetArn=arn:aws:sns:us-east-1:123456789012:my-topic
```

------

Lambda 會依現狀將事件傳送到無效字母佇列，其屬性中有額外資訊。您可以使用此資訊來識別該函式所傳回的錯誤，或建立事件與日誌或 AWS X-Ray 追蹤的關聯性。

**無效字母佇列訊息屬性**
+ **RequestID** (字串) - 調用請求的 ID。請求 ID 會出現於函式日誌中。您也可以使用 X-Ray SDK 在追蹤的屬性中記錄請求 ID。然後，您可以在 X-Ray 主控台中依請求 ID 搜尋追蹤。
+ **ErrorCode** (數字) - HTTP 狀態碼。
+ **ErrorMessage** (字串) - 第 1 KB 的錯誤訊息。

如果 Lambda 無法將訊息傳送到無效字母佇列，則會刪除事件並發出 [DeadLetterErrors](monitoring-metrics-types.md) 指標。這可能由於缺乏許可，或訊息總大小超過目標佇列或主題的限制，而發生此狀況。例如，假設一則內文大小接近 1 MB 的 Amazon SNS 通知觸發了某個函式，導致函式執行出錯。在這種情況下，Amazon SNS 新增的事件資料與 Lambda 新增的屬性結合後，可能導致訊息超過無效字母佇列中允許的大小上限。

如果您使用 Amazon SQS 作為事件來源，請對 Amazon SQS 佇列本身 (而非 Lambda 函數) 設定無效字母佇列。如需詳細資訊，請參閱[搭配 Amazon SQS 使用 Lambda](with-sqs.md)。