

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

# 使用 Kinesis Agent 寫入 Amazon Kinesis Data Streams
<a name="writing-with-agents"></a>

Kinesis 代理程式是獨立的 Java 軟體應用程式，可讓您輕鬆收集資料並將資料傳送至 Kinesis Data Streams。此代理程式將持續監控一組檔案，並且傳送新資料到您的串流。代理程式會處理檔案輪換、檢查點，並在故障時重試。它以可靠、及時和簡單的方式提供所有資料。它也會發出 Amazon CloudWatch 指標，協助您更有效地監控串流程序並進行疑難排解。

根據預設，記錄會從各個檔案根據換行符號 (`'\n'`) 字元進行剖析。不過，代理程式也可以設定為剖析多行記錄 (請參閱[指定代理程式組態設定](#agent-config-settings))。

您可以在以 Linux 為基礎的伺服器環境安裝代理程式，例如 Web 伺服器、日誌伺服器，及資料庫伺服器。安裝代理程式後，請透過指定要監控的檔案和資料的串流以進行設定。代理程式設定妥後，其將持續從檔案收集資料並以可靠的方式傳送資料至串流。

**Topics**
+ [完成 Kinesis Agent 的先決條件](#prereqs)
+ [下載並安裝代理程式](#download-install)
+ [設定和啟動代理程式](#config-start)
+ [指定代理程式組態設定](#agent-config-settings)
+ [監控多個檔案目錄並寫入多個串流](#sim-writes)
+ [使用代理程式預先處理資料](#pre-processing)
+ [使用代理程式 CLI 命令](#cli-commands)
+ [常見問答集](#agent-faq)

## 完成 Kinesis Agent 的先決條件
<a name="prereqs"></a>
+ 您的作業系統必須是 Amazon Linux AMI 2015.09 版或更新版本，或 Red Hat Enterprise Linux 版本 7 或更新版本。
+ 如果您使用 Amazon EC2 執行您的代理程式，則請啟動您的 EC2 執行個體。
+ 使用下列其中一種方法管理您的 AWS 登入資料：
  + 當您啟動 EC2 執行個體時，指定 IAM 角色。
  + 設定代理程式時指定 AWS 登入資料 （請參閱 [awsAccessKeyId](#awsAccessKeyId) 和 [awsSecretAccessKey](#awsSecretAccessKey))。
  + 編輯 `/etc/sysconfig/aws-kinesis-agent` 以指定您的區域和 AWS 存取金鑰。
  + 如果您的 EC2 執行個體位於不同的 AWS 帳戶中，請建立 IAM 角色以提供 Kinesis Data Streams 服務的存取權，並在設定代理程式時指定該角色 （請參閱 [assumeRoleARN](#assumeRoleARN) 和 [assumeRoleExternalId](#assumeRoleExternalId))。使用上述其中一種方法來指定其他帳戶中具有擔任此角色許可之使用者的 AWS 登入資料。
+ 您指定的 IAM 角色或 AWS 登入資料必須具有執行 Kinesis Data Streams [PutRecords](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html) 操作的許可，代理程式才能將資料傳送至您的串流。若您啟用 CloudWatch 監控代理程式，則另需具備執行 CloudWatch [PutMetricData](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricData.html) 操作的許可。如需詳細資訊，請參閱 [使用 IAM 控制對 Amazon Kinesis Data Streams 資源的存取](controlling-access.md)、[使用 Amazon CloudWatch 監控 Kinesis Data Streams Agent 運作狀態](agent-health.md) 和 [CloudWatch 存取控制](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/UsingIAM.html)。

## 下載並安裝代理程式
<a name="download-install"></a>

首先，連接至您的執行個體。如需詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的[連線至您的執行個體](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-connect-to-instance-linux.html)。如果您無法連線，請參閱《*Amazon EC2 使用者指南*》中的[連線至執行個體的故障診斷](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html)。

**使用 Amazon Linux AMI 設定代理程式**  
使用以下命令來下載和安裝代理程式：

```
sudo yum install –y aws-kinesis-agent
```

**使用 Red Hat Enterprise Linux 設定代理程式**  
使用以下命令來下載和安裝代理程式：

```
sudo yum install –y https://s3.amazonaws.com/streaming-data-agent/aws-kinesis-agent-latest.amzn2.noarch.rpm
```

**使用 GitHub 設定代理程式**

1. 從 [awlabs/amazon-kinesis-agent](https://github.com/awslabs/amazon-kinesis-agent) 下載代理程式。

1. 瀏覽到下載目錄並執行下列命令以安裝代理程式：

   ```
   sudo ./setup --install
   ```

**若要在 Docker 容器中設定代理程式**  
Kinesis 代理程式也可以透過 [amazonlinux](https://docs.aws.amazon.com/AmazonECR/latest/userguide/amazon_linux_container_image.html) 容器基礎在容器中執行。使用以下 Dockerfile，然後執行 `docker build`。

```
FROM amazonlinux

RUN yum install -y aws-kinesis-agent which findutils
COPY agent.json /etc/aws-kinesis/agent.json

CMD ["start-aws-kinesis-agent"]
```

## 設定和啟動代理程式
<a name="config-start"></a>

**設定和啟動代理程式**

1. 開啟並編輯組態檔案 (如果使用預設檔案存取許可，即以超級使用者身分執行)：`/etc/aws-kinesis/agent.json`

   在此組態檔案中，指定代理程式從中收集資料的檔案 (`"filePattern"`)，以及代理程式將向其傳送資料的串流名稱 (`"kinesisStream"`)。請注意，檔案名稱是一種模式，代理程式可辨識檔案輪換。您可以輪換檔案或建立新的檔案，每秒不超過一次。代理程式利用檔案建立時間戳記以判斷要追蹤哪些檔案，然後傳送至您的串流；如果每秒建立新檔案或輪換檔案超過一次，將導致代理程式無法正確區分這些檔案。

   ```
   { 
      "flows": [
           { 
               "filePattern": "/tmp/app.log*", 
               "kinesisStream": "yourkinesisstream"
           } 
      ] 
   }
   ```

1. 手動啟動代理程式：

   ```
   sudo service aws-kinesis-agent start
   ```

1. (選用) 設定代理程式在系統啟動時開始執行：

   ```
   sudo chkconfig aws-kinesis-agent on
   ```

代理程式現在已做為系統服務在背景執行。其將持續監控指定的檔案，並將資料傳送至指定的串流。代理程式的活動記錄於 `/var/log/aws-kinesis-agent/aws-kinesis-agent.log`。

## 指定代理程式組態設定
<a name="agent-config-settings"></a>

代理程式支援兩種必要的組態設定 `filePattern` 和 `kinesisStream`，以及用於其他功能的選用組態設定。您可以由 `/etc/aws-kinesis/agent.json` 指定必要及選用的組態。

當您變更組態檔案時，必須使用下列命令停止及啟動代理程式：

```
sudo service aws-kinesis-agent stop
sudo service aws-kinesis-agent start
```

或者，您可以使用下列命令：

```
sudo service aws-kinesis-agent restart
```

以下是一般組態設定。


| 組態設定 | Description | 
| --- | --- | 
| <a name="assumeRoleARN"></a>assumeRoleARN |  要由使用者擔任的角色 ARN。如需詳細資訊，請參閱《[IAM 使用者指南》中的使用 IAM 角色跨 AWS 帳戶委派存取權](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html)。 **  | 
| <a name="assumeRoleExternalId"></a>assumeRoleExternalId |  選用的識別符決定誰可以擔任此角色。如需詳細資訊，請參閱《IAM 使用者指南》**中的[如何使用外部 ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)。  | 
| <a name="awsAccessKeyId"></a>awsAccessKeyId |  AWS 會覆寫預設登入資料的存取金鑰 ID。此設定優先於所有其他登入資料供應商。  | 
| <a name="awsSecretAccessKey"></a>awsSecretAccessKey |  AWS 覆寫預設登入資料的私密金鑰。此設定優先於所有其他登入資料供應商。  | 
| cloudwatch.emitMetrics |  如設定為 (true)，將啟用代理程式發出指標至 CloudWatch。 預設：true  | 
| cloudwatch.endpoint |  適用於 CloudWatch 的區域端點。 預設：`monitoring.us-east-1.amazonaws.com`  | 
| kinesis.endpoint |  適用於 Kinesis Data Streams 的區域端點。 預設：`kinesis.us-east-1.amazonaws.com`  | 

以下是流程組態設定。


| 組態設定 | Description | 
| --- | --- | 
| dataProcessingOptions |  將每個剖析的記錄傳送到串流之前會套用於這些記錄的處理選項的清單。此處理選項會在指定的資料夾執行。如需詳細資訊，請參閱[使用代理程式預先處理資料](#pre-processing)。  | 
| kinesisStream |  [必要] 串流的名稱。  | 
| filePattern |  【必要】 必須相符的目錄和檔案模式，才能由代理程式挑選。符合此模式的所有檔案皆需將讀取許可授予 `aws-kinesis-agent-user`。對於包含這些檔案的目錄，必須將讀取和執行許可授予 `aws-kinesis-agent-user`。  | 
| initialPosition |  檔案開始進行剖析的初始位置。有效值為 `START_OF_FILE` 和 `END_OF_FILE`。 預設：`END_OF_FILE`  | 
| maxBufferAgeMillis |  代理程式將資料傳送到串流之前先緩衝資料的時間上限 (毫秒)。 數值範圍：1,000 到 900,000 (1 秒到 15 分鐘) 預設：60,000 (1 分鐘)  | 
| maxBufferSizeBytes |  代理程式將資料傳送到串流之前先緩衝資料的容量上限 (位元組)。 數值範圍：1 到 4,194,304 (4 MB) 預設：4,194,304 (4 MB)  | 
| maxBufferSizeRecords |  代理程式將資料傳送到串流之前先緩衝資料的記錄數上限。 數值範圍：1 到 500 預設：500  | 
| minTimeBetweenFilePollsMillis |  代理程式輪詢和剖析檔案以找出新資料的時間間隔 (以毫秒為單位)。 數值範圍：1 或以上 預設：100  | 
| multiLineStartPattern |  用於識別記錄開始處的模式。記錄是由符合模式的一列及不符合模式的任何幾列所組成。有效值為常規運算式。根據預設，每個新日誌檔中的新列會剖析為一筆記錄。  | 
| partitionKeyOption |  產生分割區索引鍵的方法。有效值為 `RANDOM` (隨機產生的整數) 和 `DETERMINISTIC` (根據資料計算得出的雜湊值)。 預設：`RANDOM`  | 
| skipHeaderLines |  代理程式剖析監控檔案開頭部分時略過的列數。 數值範圍：0 或以上 預設：0 (零)  | 
| truncatedRecordTerminator |  記錄大小超過 Kinesis Data Streams 記錄大小限制時，代理程式將用來截斷剖析之記錄的字串。(1,000 KB) 預設：`'\n'` (換行符號)  | 

## 監控多個檔案目錄並寫入多個串流
<a name="sim-writes"></a>

透過指定多個流程組態設定，您可以設定代理程式來監控多個檔案目錄，然後將資料傳送到多個串流。在下列組態範例中，代理程式會監控兩個檔案目錄，並分別將資料傳送至 Kinesis 串流和 Firehose 交付串流。請注意，您可以為 Kinesis Data Streams 和 Firehose 指定不同的端點，因此 Kinesis 串流和 Firehose 交付串流不需要位於相同的區域。

```
{
    "cloudwatch.emitMetrics": true,
    "kinesis.endpoint": "https://your/kinesis/endpoint", 
    "firehose.endpoint": "https://your/firehose/endpoint", 
    "flows": [
        {
            "filePattern": "/tmp/app1.log*", 
            "kinesisStream": "yourkinesisstream"
        }, 
        {
            "filePattern": "/tmp/app2.log*",
            "deliveryStream": "yourfirehosedeliverystream" 
        }
    ] 
}
```

如需搭配 Firehose 使用代理程式的詳細資訊，請參閱[搭配 Kinesis 代理程式寫入 Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/writing-with-agents.html)。

## 使用代理程式預先處理資料
<a name="pre-processing"></a>

代理程式可預先處理經由受監控檔案所剖析的記錄，然後再將其傳送至您的串流。您可以將 `dataProcessingOptions` 組態設定新增到您的檔案流程以啟用此功能。可新增一或多個處理選項，這些選項將會依照指定的順序執行。

代理程式支援下列處理選項。由於代理程式是開放原始碼，您可以進一步開發和擴展其處理選項。您可以從 [Kinesis 代理程式](https://github.com/awslabs/amazon-kinesis-agent)下載代理程式。處理選項

`SINGLELINE`  
藉由移除換行字元、前方空格及結尾空格，將多列記錄轉換為單列記錄。  

```
{
    "optionName": "SINGLELINE"
}
```

`CSVTOJSON`  
將記錄從分隔符號區隔格式轉換為 JSON 格式。  

```
{
    "optionName": "CSVTOJSON",
    "customFieldNames": [ "field1", "field2", ... ],
    "delimiter": "yourdelimiter"
}
```  
`customFieldNames`  
[必要] 欄位名稱在每個 JSON 鍵值對中做為鍵。例如，若您指定 `["f1", "f2"]`，記錄「v1, v2」將轉換為 `{"f1":"v1","f2":"v2"}`。  
`delimiter`  
在記錄做為分隔符號的字串。預設為逗號 (,)。

`LOGTOJSON`  
將記錄從日誌格式轉換為 JSON 格式。支援的日誌格式為 **Apache Common Log**、**Apache Combined Log**、**Apache Error Log**、以及 **RFC3164 Syslog**。  

```
{
    "optionName": "LOGTOJSON",
    "logFormat": "logformat",
    "matchPattern": "yourregexpattern",
    "customFieldNames": [ "field1", "field2", … ]
}
```  
`logFormat`  
[必要] 日誌項目格式。以下是可能的值：  
+ `COMMONAPACHELOG` – Apache Common Log 格式。根據預設，每個日誌項目皆有以下模式：「`%{host} %{ident} %{authuser} [%{datetime}] \"%{request}\" %{response} %{bytes}`」。
+ `COMBINEDAPACHELOG` – Apache Combined Log 格式。根據預設，每個日誌項目皆有以下模式：「`%{host} %{ident} %{authuser} [%{datetime}] \"%{request}\" %{response} %{bytes} %{referrer} %{agent}`」。
+ `APACHEERRORLOG` – Apache Error Log 格式。根據預設，每個日誌項目皆有以下模式：「`[%{timestamp}] [%{module}:%{severity}] [pid %{processid}:tid %{threadid}] [client: %{client}] %{message}`」。
+ `SYSLOG` – RFC3164 Syslog 格式。根據預設，每個日誌項目皆有以下模式：「`%{timestamp} %{hostname} %{program}[%{processid}]: %{message}`」。  
`matchPattern`  
用於從日誌項目擷取值的正規運算式模式。如果您的日誌項目不屬於任一種預先定義的日誌格式，則將使用此設定。使用此設定時，您還必須指定 `customFieldNames`。  
`customFieldNames`  
自訂欄位名稱在每個 JSON 鍵值對中做為鍵。您可以使用此設定來定義從 `matchPattern` 擷取的值的欄位名稱，或覆寫預先定義的日誌格式的預設欄位名稱。

**Example ：LOGTOJSON 組態**  <a name="example-logtojson"></a>
這裡提供一個 Apache Common Log 項目轉換為 JSON 格式的 `LOGTOJSON` 組態範例：  

```
{
    "optionName": "LOGTOJSON",
    "logFormat": "COMMONAPACHELOG"
}
```
轉換前：  

```
64.242.88.10 - - [07/Mar/2004:16:10:02 -0800] "GET /mailman/listinfo/hsdivision HTTP/1.1" 200 6291
```
轉換後：  

```
{"host":"64.242.88.10","ident":null,"authuser":null,"datetime":"07/Mar/2004:16:10:02 -0800","request":"GET /mailman/listinfo/hsdivision HTTP/1.1","response":"200","bytes":"6291"}
```

**Example ：使用自訂欄位的 LOGTOJSON 組態**  <a name="example-logtojson-custom-fields"></a>
以下是另一個 `LOGTOJSON` 組態範例：  

```
{
    "optionName": "LOGTOJSON",
    "logFormat": "COMMONAPACHELOG",
    "customFieldNames": ["f1", "f2", "f3", "f4", "f5", "f6", "f7"]
}
```
使用此組態設定，前一個範例的相同 Apache Common Log 項目轉換為 JSON 格式如下：  

```
{"f1":"64.242.88.10","f2":null,"f3":null,"f4":"07/Mar/2004:16:10:02 -0800","f5":"GET /mailman/listinfo/hsdivision HTTP/1.1","f6":"200","f7":"6291"}
```

**Example ：轉換 Apache Common Log 項目**  <a name="example-apache-common-log-entry"></a>
以下流程組態將 Apache Common Log 項目轉換為 JSON 格式的單列記錄：  

```
{ 
    "flows": [
        {
            "filePattern": "/tmp/app.log*", 
            "kinesisStream": "my-stream",
            "dataProcessingOptions": [
                {
                    "optionName": "LOGTOJSON",
                    "logFormat": "COMMONAPACHELOG"
                }
            ]
        }
    ] 
}
```

**Example ：轉換多列記錄**  <a name="example-convert-multiline"></a>
以下流程組態剖析第一行從「`[SEQUENCE=`」開始的多列記錄。每筆記錄都會先轉換為單列記錄。然後，根據定位鍵分隔符號從記錄中擷取值。擷取的值會對應到指定的 `customFieldNames` 值以形成 JSON 格式的單列記錄。  

```
{ 
    "flows": [
        {
            "filePattern": "/tmp/app.log*", 
            "kinesisStream": "my-stream",
            "multiLineStartPattern": "\\[SEQUENCE=",
            "dataProcessingOptions": [
                {
                    "optionName": "SINGLELINE"
                },
                {
                    "optionName": "CSVTOJSON",
                    "customFieldNames": [ "field1", "field2", "field3" ],
                    "delimiter": "\\t"
                }
            ]
        }
    ] 
}
```

**Example ：使用匹配模式的 LOGTOJSON 組態**  <a name="example-logtojson-match-pattern"></a>
以下是 Apache Common Log 項目轉換為 JSON 格式的 `LOGTOJSON` 組態範例，省略最後欄位 (位元組)：  

```
{
    "optionName": "LOGTOJSON",
    "logFormat": "COMMONAPACHELOG",
    "matchPattern": "^([\\d.]+) (\\S+) (\\S+) \\[([\\w:/]+\\s[+\\-]\\d{4})\\] \"(.+?)\" (\\d{3})",
    "customFieldNames": ["host", "ident", "authuser", "datetime", "request", "response"]
}
```
轉換前：  

```
123.45.67.89 - - [27/Oct/2000:09:27:09 -0400] "GET /java/javaResources.html HTTP/1.0" 200
```
轉換後：  

```
{"host":"123.45.67.89","ident":null,"authuser":null,"datetime":"27/Oct/2000:09:27:09 -0400","request":"GET /java/javaResources.html HTTP/1.0","response":"200"}
```

## 使用代理程式 CLI 命令
<a name="cli-commands"></a>

在系統啟動時自動開始執行代理程式：

```
sudo chkconfig aws-kinesis-agent on
```

檢查代理程式的狀態：

```
sudo service aws-kinesis-agent status
```

停止代理程式：

```
sudo service aws-kinesis-agent stop
```

從這個位置讀取代理程式的日誌檔案：

```
/var/log/aws-kinesis-agent/aws-kinesis-agent.log
```

解除安裝代理程式：

```
sudo yum remove aws-kinesis-agent
```

## 常見問答集
<a name="agent-faq"></a>

### 是否有適用於 Windows 的 Kinesis 代理程式？
<a name="agent-faq-1"></a>

[適用於 Windows 的 Kinesis 代理程式](https://docs.aws.amazon.com/kinesis-agent-windows/latest/userguide/what-is-kinesis-agent-windows.html)是不同於適用於 Linux 平台的 Kinesis 代理程式的軟體。

### 為什麼 Kinesis 代理程式會減速和/或 `RecordSendErrors` 增加？
<a name="agent-faq-2"></a>

這通常是由於來自 Kinesis 的限流。檢查 Kinesis Data Streams 的 `WriteProvisionedThroughputExceeded` 指標或 Firehose Delivery Streams 的 `ThrottledRecords` 指標。這些指標中從 0 開始的任何增量，均表示需要提升串流限制。如需詳細資訊，請參閱 [Kinesis Data Stream 限制](https://docs.aws.amazon.com/streams/latest/dev/service-sizes-and-limits.html)和 [Amazon Firehose 交付串流](https://docs.aws.amazon.com/firehose/latest/dev/limits.html)。

排除限流之後，請查看 Kinesis 代理程式是否設定為追蹤大量小型檔案。Kinesis 代理程式追蹤新檔案時會有延遲，因此 Kinesis 代理程式應追蹤少量較大的檔案。嘗試將日誌檔案合併至較大的檔案中。

### 為什麼我會遇到 `java.lang.OutOfMemoryError` 例外狀況？
<a name="agent-faq-4"></a>

Kinesis 代理程式沒有足夠的記憶體可以處理其目前的工作負載。嘗試增加 `/usr/bin/start-aws-kinesis-agent` 中的 `JAVA_START_HEAP` 和 `JAVA_MAX_HEAP` 並重新啟動代理程式。

### 為什麼我會遇到 `IllegalStateException : connection pool shut down` 例外狀況？
<a name="agent-faq-5"></a>

Kinesis 代理程式沒有足夠的連線可以處理其目前的工作負載。嘗試在位於 `/etc/aws-kinesis/agent.json` 的一般代理程式組態設定中增加 `maxConnections` 和 `maxSendingThreads`。這些欄位的預設值是可用執行期處理器的 12 倍。如需進階代理程式組態設定的詳細資訊，請參閱 [AgentConfiguration.java](https://github.com/awslabs/amazon-kinesis-agent/blob/master/src/com/amazon/kinesis/streaming/agent/config/AgentConfiguration.java)。

### 如何使用 Kinesis 代理程式對另一個問題進行偵錯？
<a name="agent-faq-6"></a>

可以在 `/etc/aws-kinesis/log4j.xml` 中啟用 `DEBUG` 層級日誌。

### 我應該如何對 Kinesis Agent 進行設定？
<a name="agent-faq-7"></a>

`maxBufferSizeBytes` 越小，Kinesis 代理程式傳送資料的頻率就越高。這可能很好，因為這樣會減少記錄的交付時間，但也增加了 Kinesis 的每秒請求。

### 為什麼 Kinesis 代理程式傳送重複的日誌？
<a name="agent-faq-8"></a>

發生這種情況是由於檔案追蹤組態錯誤。請確保每個 `fileFlow’s filePattern` 僅與一個檔案相符。如果正在 `copytruncate` 模式中使用 `logrotate` 模式下，也可能發生這種情況。嘗試將模式變更為預設模式，或建立模式以避免重複。如需有關處理重複記錄的詳細資訊，請參閱[處理重複記錄](https://docs.aws.amazon.com/streams/latest/dev/kinesis-record-processor-duplicates.html)。