

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

# 使用 Lambda Logs API
<a name="runtimes-logs-api"></a>

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

**Lambda 受管執行個體不支援 Logs API**  
Lambda 受管執行個體不支援 Logs API。如果您使用的是受管執行個體函數，請改用[遙測 API](telemetry-api.md)。遙測 API 提供從 Lambda 函數收集和處理遙測資料的增強功能。

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

[Lambda 延伸項目](runtimes-extensions-api.md)可以使用 Lambda Runtime Logs API，直接從 Lambda [執行環境](lambda-runtime-environment.md)中訂閱記錄串流。Lambda 會將日誌串流至延伸項目，延伸項目隨後可處理、篩選日誌並將其傳送至任何偏好目的地。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/logs-api-concept-diagram.png)


Logs API 允許延伸項目訂閱三種不同的日誌串流：
+ Lambda 函數產生並寫入到 `stdout` 或 `stderr` 的函數日誌。
+ 延伸項目程式碼產生的延伸項目日誌。
+ Lambda 平台日誌，它記錄與調用和延伸項目相關的事件和錯誤。

**注意**  
即便延伸項目訂閱一個或多個日誌串流，Lambda 也會將所有日誌傳送至 CloudWatch。

**Topics**
+ [訂閱接收日誌](#runtimes-logs-api-subscribing)
+ [記憶體用量](#runtimes-logs-api-memory)
+ [目的地協定](#runtimes-logs-api-dest)
+ [緩衝組態](#runtimes-logs-api-buffering)
+ [訂閱範例](#runtimes-logs-api-subs-example)
+ [Logs API 的範本程式碼](#runtimes-logs-api-samples)
+ [Logs API 參考](#runtimes-logs-api-ref)
+ [日誌訊息](#runtimes-logs-api-msg)

## 訂閱接收日誌
<a name="runtimes-logs-api-subscribing"></a>

Lambda 延伸項目可透過傳送訂閱請求至 Logs API 來訂閱接收日誌。

若要訂閱接收日誌，您需要延伸項目識別符 (`Lambda-Extension-Identifier`)。首先[註冊延伸項目](runtimes-extensions-api.md#extensions-registration-api-a)以接收延伸項目識別符。然後在[初始化](lambda-runtime-environment.md#runtimes-lifecycle-ib)期間訂閱 Logs API。初始化階段完成後，Lambda 不會處理訂閱請求。

**注意**  
Logs API 訂閱為等冪操作。重複的訂閱請求不會導致重複訂閱。

## 記憶體用量
<a name="runtimes-logs-api-memory"></a>

隨著訂閱者數量的增加，記憶體用量會線性增加。訂閱會耗用記憶體資源，因為每個訂閱都會開啟新的記憶體緩衝區來存放日誌。為了協助最佳化記憶體用量，您可以調整[緩衝組態](#runtimes-logs-api-buffering)。緩衝區記憶體用量會計入執行環境中的整體記憶體耗用量。

## 目的地協定
<a name="runtimes-logs-api-dest"></a>

您可以選擇下列其中一個協定來接收日誌：

1. **HTTP** (建議) - Lambda 會以 JSON 格式的記錄陣列將日誌傳遞至本機 HTTP 端點 (`http://sandbox.localdomain:${PORT}/${PATH}`)。`$PATH` 為選用參數。請注意，僅支援 HTTP，而不是 HTTPS。您可以選擇透過 PUT 或 POST 接收日誌。

1. **TCP** - Lambda 以[換行分隔的 JSON (NDJSON) 格式](https://github.com/ndjson/ndjson-spec)將日誌傳遞至 TCP 連接埠。

建議使用 HTTP，而不是使用 TCP。使用 TCP，Lambda 平台無法確認何時將日誌傳遞至應用程式層。因此，如果您的延伸項目損毀，可能會遺失日誌。HTTP 不會共享此限制。

我們也建議您先設定本機 HTTP 接聽程式或 TCP 連接埠，然後再訂閱接收日誌。在設定期間，請注意下列事項：
+ Lambda 只會將日誌傳送至執行環境內的目的地。
+ 如果沒有接聽程式，或者如果 POST 或 PUT 請求導致錯誤，則 Lambda 會重新嘗試傳送日誌 (使用輪詢)。如果日誌訂閱者當機，則在 Lambda 重新啟動執行環境之後會繼續接收日誌。
+ Lambda 保留連接埠 9001。沒有其他連接埠編號限制或建議。

## 緩衝組態
<a name="runtimes-logs-api-buffering"></a>

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` 日誌。如需詳細資訊，請參閱[Lambda：並非所有函數的日誌都會顯示](troubleshooting-execution.md#troubleshooting-execution-missinglogs)。

## 訂閱範例
<a name="runtimes-logs-api-subs-example"></a>

訂閱平台和函數日誌的請求如下列範例所示。

```
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 的範本程式碼
<a name="runtimes-logs-api-samples"></a>

如需示範如何將日誌傳送至自訂目的地的範例程式碼，請參閱 AWS 運算部落格上的[使用 AWS Lambda 擴充功能將日誌傳送至自訂目的地](https://aws.amazon.com/blogs/compute/using-aws-lambda-extensions-to-send-logs-to-custom-destinations/)。

對於顯示如何開發基本 Lambda 延伸及訂閱 Logs API 的 Python 和 Go 程式碼範例，請參閱 AWS Samples GitHub 儲存庫上的 [AWS Lambda Extensions](https://github.com/aws-samples/aws-lambda-extensions)。如需建置 Lambda 延伸項目的詳細資訊，請參閱 [使用 Lambda 延伸 API 來建立延伸項目](runtimes-extensions-api.md)。

## Logs API 參考
<a name="runtimes-logs-api-ref"></a>

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

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

Logs API 的 OpenAPI 規範 (版本 **2020-08-15**) 可參閱此文件：[logs-api-request.zip](samples/logs-api-request.zip)

### 訂閱
<a name="runtimes-logs-api-ref-a"></a>

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

**路徑** – `/logs`

**方法** – **PUT**

**主體參數**

`destination` – 請參閱[目的地協定](#runtimes-logs-api-dest)。必要：是。類型：字串。

`buffering` – 請參閱[緩衝組態](#runtimes-logs-api-buffering)。必要：否。類型：字串。

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

`schemaVersion` - 必要：否。預設值："2020-08-15"。將延伸項目設定為 "2021-03-18"，可接收 [`platform.runtimeDone`](#runtimes-logs-api-ref-done) 訊息。

****回應參數****

訂閱回應的 OpenAPI 規範 (版本 **2020-08-15**)，適用於 HTTP 和 TCP 通訊協定：
+ HTTP︰[logs-api-http-response.zip](samples/logs-api-http-response.zip)
+ TCP︰[logs-api-tcp-response.zip](samples/logs-api-tcp-response.zip)

****回應代碼****
+ 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"
}
```

## 日誌訊息
<a name="runtimes-logs-api-msg"></a>

Logs API 允許延伸項目訂閱三種不同的日誌串流：
+ 函數 - Lambda 函數產生並寫入到 `stdout` 或 `stderr` 的日誌。
+ 延伸項目 - 延伸項目程式碼產生的日誌。
+ 平台 - 執行時間平台產生的日誌，它們記錄與調用和延伸相關的事件和錯誤。

**Topics**
+ [函數日誌](#runtimes-logs-api-msg-function)
+ [延伸項目日誌](#runtimes-logs-api-msg-extension)
+ [平台日誌](#runtimes-logs-api-msg-platform)

### 函數日誌
<a name="runtimes-logs-api-msg-function"></a>

Lambda 函數和內部延伸項目會產生函數日誌並將它們寫入 `stdout` 或 `stderr`。

下列範例顯示函數日誌訊息的格式。\$1 "time": "2020-08-20T12:31:32.123Z", "type": "function", "record": "ERROR encountered. Stack trace:\$1n\$1my-function (line 10)\$1n" \$1 

### 延伸項目日誌
<a name="runtimes-logs-api-msg-extension"></a>

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

### 平台日誌
<a name="runtimes-logs-api-msg-platform"></a>

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

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

#### 平台日誌訊息範例
<a name="runtimes-logs-api-examples"></a>

下面的範例顯示了平台開始和平台結束日誌。這些日誌指出 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"}   
}
```

**platform.initRuntimeDone** 日誌訊息顯示子階段 `Runtime init` 的狀態，該子階段是[初始化生命週期階段](lambda-runtime-environment.md#runtimes-lifecycle-ib)的一部分。`Runtime init` 成功時，執行階段會傳送 `/next` 執行階段 API 請求 (針對 `on-demand` 和 `provisioned-concurrency` 初始化類型) 或 `restore/next` (針對 `snap-start` 初始化類型)。下列範例顯示 `snap-start` 初始化類型的成功 **platform.initRuntimeDone** 日誌訊息。

```
{
  "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"
}
```

**注意**  
AWS 目前正在對 Lambda 服務實作變更。由於這些變更，您可能會看到系統日誌訊息的結構和內容，與 AWS 帳戶中不同 Lambda 函數發出的追蹤區段之間存在細微差異。  
受此變更影響的日誌輸出之一是平台故障日誌 `"record"` 欄位。下列範例顯示了舊格式和新格式的說明性 `"record"` 欄位。新式故障日誌包含更簡潔的訊息  
這些變化將在未來幾週內實作，除中國和 GovCloud 區域以外，所有 AWS 區域 中的所有函數都會轉換至使用新格式的日誌訊息和追蹤區段。



**Example 平台故障日誌記錄 (舊式)**  

```
"record":"RequestId: ...\tError: Runtime exited with error: exit status 255\nRuntime.ExitError"
```

**Example 平台故障日誌記錄 (新式)**  

```
"record":"RequestId: ... Status: error\tErrorType: Runtime.ExitError"
```

當延伸項目註冊延伸項目 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` 訊息
<a name="runtimes-logs-api-ref-done"></a>

如果您在訂閱請求中將結構描述版本設定為 "2021-03-18"，在函數調用成功完成或發生錯誤之後，Lambda 會傳送 `platform.runtimeDone` 訊息。延伸項目可以使用此訊息停止此函數調用的所有遙測集合。

結構描述版本 **2021-03-18** 中的日誌事件類型的 OpenAPI 規範可參閱此文件：[schema-2021-03-18.zip](samples/schema-2021-03-18.zip)

當執行時間傳送 `Next` 或 `Error` 執行時間 API 請求時，Lambda 會產生 `platform.runtimeDone` 日誌訊息。`platform.runtimeDone` 日誌會通知 Logs API 的使用者，告知他們函數調用完成。延伸項目可以使用此資訊來決定何時傳送該調用期間收集的所有遙測。

##### 範例
<a name="runtimes-logs-api-examples"></a>

當函數調用完成時，在執行時間傳送 NEXT 請求之後，Lambda 會傳送 `platform.runtimeDone` 訊息。下列範例顯示每個狀態值的訊息：成功、失敗和逾時。

**Example 成功訊息範例**  

```
{
    "time": "2021-02-04T20:00:05.123Z",
    "type": "platform.runtimeDone",
    "record": {
       "requestId":"6f7f0961f83442118a7af6fe80b88",
       "status": "success"
    }
}
```

**Example 失敗訊息範例**  

```
{
   "time": "2021-02-04T20:00:05.123Z",
   "type": "platform.runtimeDone",
   "record": {
      "requestId":"6f7f0961f83442118a7af6fe80b88",
      "status": "failure"
   }
}
```

**Example 逾時訊息範例**  

```
{
   "time": "2021-02-04T20:00:05.123Z",
   "type": "platform.runtimeDone",
   "record": {
      "requestId":"6f7f0961f83442118a7af6fe80b88",
      "status": "timeout"
  }
}
```

**Example platform.restoreRuntimeDone 訊息範例 (僅限 `snap-start` 初始化類型)**  
**platform.restoreRuntimeDone** 日誌訊息會顯示 `Restore` 階段是否成功。執行階段傳送 `restore/next` 執行階段 API 請求時，Lambda 會產生此訊息。可能的狀態有三種：成功、失敗和逾時。成功的 **platform.restoreRuntimeDone** 日誌訊息如下列範例所示。  

```
{
  "time":"2022-07-17T18:43:45.936Z",
  "type":"platform.restoreRuntimeDone",
  "record":{
      "status":"success"
  }
}
```