

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

# CloudWatch Logs 代理程式參考
<a name="AgentReference"></a>

**重要**  
 本節是使用已棄用 CloudWatch Logs 代理程式的參考。如果您使用的是執行個體中繼資料服務第 2 版 (IMDSv2)，則必須使用新的統一 CloudWatch 代理程式。不過，即使您不是使用 IMDSv2，我們強烈建議使用較新的統一 CloudWatch 代理程式，而不是已取代的 CloudWatch Logs 代理程式。如需有關較新的統一 CloudWatch 代理程式的資訊，請參閱[使用 CloudWatch 代理程式從 Amazon EC2 執行個體和內部部署伺服器收集指標和日誌](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html)。如需有關從已棄用 CloudWatch Logs 代理程式遷移至統一代理程式的資訊，[請使用精靈建立 CloudWatch 代理程式組態檔案](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html)。

CloudWatch Logs 代理程式可自動將日誌資料從 Amazon EC2 執行個體傳送至 CloudWatch Logs。代理程式包含下列元件：
+ 將日誌資料 AWS CLI 推送至 CloudWatch Logs 的 外掛程式。
+ 指令碼 (常駐程式)，起始將資料推送至 CloudWatch Logs 的程序。
+ 確保協助程式持續執行的 Cron 工作。

## 代理程式組態檔案
<a name="agent-configuration-file"></a>

CloudWatch Logs 代理程式組態檔案描述 CloudWatch Logs 代理程式所需的資訊。代理程式組態檔案的 [general] 區段定義了通用組態，而這些組態會套用到所有日誌串流。[logstream] 區段定義了將本機檔案傳送到遠端日誌串流時所需的資訊。您可以擁有多個 [logstream] 區段，但每個區段在組態檔案中都必須有唯一的名稱，例如，[logstream1]、[logstream2]，以此類推。[logstream] 值與日誌檔中的第一行資料，用於定義日誌檔的身分。

```
[general]
state_file = value
logging_config_file = value
use_gzip_http_content_encoding = [true | false]

[logstream1]
log_group_name = value
log_stream_name = value
datetime_format = value
time_zone = [LOCAL|UTC]
file = value
file_fingerprint_lines = integer | integer-integer
multi_line_start_pattern = regex | {datetime_format}
initial_position = [start_of_file | end_of_file]
encoding = [ascii|utf_8|..]
buffer_duration = integer
batch_count = integer
batch_size = integer

[logstream2]
...
```

**state\$1file**  
指定狀態檔案的存放位置。

**logging\$1config\$1file**  
(選用) 指定代理程式日誌組態檔案的位置。如果您未在此指定代理程式日誌組態檔案，將使用預設檔案 awslogs.conf。如果您以指令碼安裝代理程式，預設的檔案位置是 `/var/awslogs/etc/awslogs.conf`，如果以 rpm 安裝代理程式，則是 `/etc/awslogs/awslogs.conf`。此檔案為 Python 組態檔案格式 (https://docs.python.org/2/library/logging.config.html\$1logging-config-fileformat)。您可以自訂具有以下名稱的記錄器。  

```
cwlogs.push
cwlogs.push.reader
cwlogs.push.publisher
cwlogs.push.event
cwlogs.push.batch
cwlogs.push.stream
cwlogs.push.watcher
```
以下範例會將讀取者和發佈者的層級變更為 WARNING，而預設值為 INFO。  

```
[loggers]
keys=root,cwlogs,reader,publisher
            
[handlers]
keys=consoleHandler
            
[formatters]
keys=simpleFormatter
           
[logger_root]
level=INFO
handlers=consoleHandler
            
[logger_cwlogs]
level=INFO
handlers=consoleHandler
qualname=cwlogs.push
propagate=0
            
[logger_reader]
level=WARNING
handlers=consoleHandler
qualname=cwlogs.push.reader
propagate=0
            
[logger_publisher]
level=WARNING
handlers=consoleHandler
qualname=cwlogs.push.publisher
propagate=0
            
[handler_consoleHandler]
class=logging.StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stderr,)
            
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(process)d - %(threadName)s - %(message)s
```

**use\$1gzip\$1http\$1content\$1encoding**  
設為 true (預設) 時會啟用 gzip http 內容編碼，將壓縮的酬載傳送至 CloudWatch Logs。這會降低 CPU 使用量、降低 NetworkOut 及減少推送延遲。若要停用此功能，請將 **use\$1gzip\$1http\$1content\$1encoding = false** 新增至 CloudWatch Logs 代理程式組態檔案的 **[general]** 區段，然後重新啟動代理程式。  
此設定僅適用於 awscli-cwlogs 1.3.3 及更新版本。

**log\$1group\$1name**  
指定目的地日誌群組。如果日誌群組尚未存在，將會自動建立。日誌群組的名稱長度可介於 1 到 512 個字元之間。可用的字元為 a-z、A-Z、0-9、「\$1」(底線)、「-」(連字號)、「/」(正斜線) 和「.」(句點)。

**log\$1stream\$1name**  
指定目的地日誌串流。您可以使用常值字串、預先定義的變數 (\$1instance\$1id\$1、\$1hostname\$1、\$1ip\$1address\$1) 或這兩者的組合，以定義日誌串流名稱。如果日誌串流尚未存在，將會自動建立。

**datetime\$1format**  
指定從日誌擷取時間戳記的方式。此時間戳記用於擷取日誌事件及產生指標。若未提供 **datetime\$1format**，目前時間將用於每個日誌事件。如果提供的 **datetime\$1format** 值對於指定的日誌訊息而言是無效的，這時將使用最近一次所含時間戳記成功剖析之日誌事件的時間戳記。如果沒有之前的日誌事件，將使用目前時間。  
以下列出常見的 datetime\$1format 代碼。您也可以使用任何 Python 支援的 datetime\$1format 代碼、datetime.strptime()。亦支援時區位移 (%z)，雖然 Python 3.2 之前版本並不支援，[\$1-] HHMM 無需冒號 (:)。如需詳細資訊，請參閱 [strftime () 和 strptime () 行為](https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior)。  
**%y**：年，不包含以填充零之十進位表示的世紀數字。00、01、…、99  
**%Y**：年，包含以十進位表示的世紀數字。1970、1988、2001、2013  
**%b**：月，當地的縮寫名稱。Jan、Feb、…、Dec (en\$1US)；  
**%B**：月，當地的完整名稱。January、February、…、December (en\$1US)；  
**%m**：月，填充零的十進位數字。01、02、…、12  
**%d**：日，填充零的十進位數字。01、02、…、31  
**%H**：小時 (24 小時制)，填充零的十進位數字。00、01、…、23  
**%I**：小時 (12 小時制)，填充零的十進位數字。01、02、…、12  
**%p**：相當於當地的 AM 或 PM。  
**%M**：分鐘，填充零的十進位數字。00、01、…、59  
**%S**：秒鐘，填充零的十進位數字。00、01、…、59  
**%f**：微秒，十進位數字，左側填充零。000000、…、999999  
**%z**：UTC 位移，格式為 \$1HHMM 或 -HHMM。\$10000、-0400、\$11030  
**範例格式：**  
`Syslog: '%b %d %H:%M:%S', e.g. Jan 23 20:59:29`  
`Log4j: '%d %b %Y %H:%M:%S', e.g. 24 Jan 2014 05:00:00`  
`ISO8601: '%Y-%m-%dT%H:%M:%S%z', e.g. 2014-02-20T05:20:20+0000` 

**time\$1zone**  
指定日誌事件時間戳記的時區。支援的兩個值為 UTC 和 LOCAL。如果無法依據 **datetime\$1format** 推斷時區，預設值為 LOCAL。

**file**  
指定您要推送到 CloudWatch Logs 的日誌檔。檔案可指向特定檔案或多個檔案 (使用萬用字元，例如 /var/log/system.log\$1)。根據檔案的修改時間，只會將最新的檔案推送到 CloudWatch Logs。我們建議您使用萬用字元來指定一系列的相同類型的檔案，例如 access\$1log.2014-06-01-01、access\$1log.2014-06-01-02，以此類推，但不適用於多種種類的檔案，例如 access\$1log\$180 和 access\$1log\$1443。若要指定多種種類的檔案，可將另一個日誌串流新增至組態檔案，讓每個種類的日誌檔進入不同的日誌串流。不支援壓縮檔案。

**file\$1fingerprint\$1lines**  
指定用於識別檔案的行範圍。有效值是一個數字或兩個以破折號分隔的數字，例如「1」、「2-5」。預設值為「1」，因此第一行用於計算指紋。除非所有指定的行皆可用，否則不會將指紋行傳送到 CloudWatch Logs。

**multi\$1line\$1start\$1pattern**  
指定用於識別日誌訊息開始處的模式。日誌訊息是由符合模式的一列及不符合模式的任何幾列所組成。有效值為規則表達式或 \$1datetime\$1format\$1。使用 \$1datetime\$1format\$1 時，應指定 datetime\$1format 選項。預設值為「^ [^\$1s]」，因此開頭使用非空白字元的任何列皆可結束之前的日誌訊息，並開始新的日誌訊息。

**initial\$1position**  
指定開始讀取資料 (start\$1of\$1file 或 end\$1of\$1file) 的位置。預設值為 start\$1of\$1file。只有在日誌串流沒有狀態時才會使用它。

**編碼**  
指定日誌檔的編碼，以便正確讀取檔案。預設值為 utf\$18。這裡可以使用 Python codecs.decode () 支援的編碼。  
指定不正確的編碼可能導致資料遺失，因為無法解碼的字元會被替換為一些其他的字元。
以下是一些常見的編碼：  
 `ascii, big5, big5hkscs, cp037, cp424, cp437, cp500, cp720, cp737, cp775, cp850, cp852, cp855, cp856, cp857, cp858, cp860, cp861, cp862, cp863, cp864, cp865, cp866, cp869, cp874, cp875, cp932, cp949, cp950, cp1006, cp1026, cp1140, cp1250, cp1251, cp1252, cp1253, cp1254, cp1255, cp1256, cp1257, cp1258, euc_jp, euc_jis_2004, euc_jisx0213, euc_kr, gb2312, gbk, gb18030, hz, iso2022_jp, iso2022_jp_1, iso2022_jp_2, iso2022_jp_2004, iso2022_jp_3, iso2022_jp_ext, iso2022_kr, latin_1, iso8859_2, iso8859_3, iso8859_4, iso8859_5, iso8859_6, iso8859_7, iso8859_8, iso8859_9, iso8859_10, iso8859_13, iso8859_14, iso8859_15, iso8859_16, johab, koi8_r, koi8_u, mac_cyrillic, mac_greek, mac_iceland, mac_latin2, mac_roman, mac_turkish, ptcp154, shift_jis, shift_jis_2004, shift_jisx0213, utf_32, utf_32_be, utf_32_le, utf_16, utf_16_be, utf_16_le, utf_7, utf_8, utf_8_sig` 

**buffer\$1duration**  
指定日誌事件的批次處理的持續時間。最小值為 5000ms，預設值為 5000ms。

**batch\$1count**  
指定批次中的日誌事件最大數量，最多可達 10,000。預設值為 10000。

**batch\$1size**  
指定批次中的日誌事件最大大小，以位元組為單位，最多可達 1048576 位元組。預設值為 1048576 位元組。這個大小的計算方式是以所有 UTF-8 事件訊息，加上每個記錄事件 26 個位元組。

## 透過 HTTP 代理使用 CloudWatch Logs 代理程式
<a name="agent-http-proxies"></a>

您可以透過 HTTP 代理來使用 CloudWatch Logs 代理程式。

**注意**  
awslogs-agent-setup.py 1.3.8 或更新版本支援 HTTP 代理。

**透過 HTTP 代理使用 CloudWatch Logs 代理程式**

1. 執行以下任意一項：

   1. 針對新安裝的 CloudWatch Logs 代理程式，請執行下列命令：

      ```
      curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O
      ```

      ```
      sudo python awslogs-agent-setup.py --region us-east-1 --http-proxy http://your/proxy --https-proxy http://your/proxy --no-proxy 169.254.169.254
      ```

      為了維持存取 EC2 執行個體上的 Amazon EC2 中繼資料服務，請使用 **--no-proxy 169.254.169.254** (建議)。如需詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的[執行個體中繼資料和使用者資料](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)。

      在 `http-proxy` 和 `https-proxy` 的數值中，您必須指定整個 URL。

   1. 針對現有已安裝的 CloudWatch Logs 代理程式，請編輯 /var/awslogs/etc/proxy.conf，並新增您的代理：

      ```
      HTTP_PROXY=
      HTTPS_PROXY=
      NO_PROXY=
      ```

1. 重新啟動代理程式，讓變更生效：

   ```
   sudo service awslogs restart
   ```

   如果您使用的是 Amazon Linux 2，請使用下列命令來重新啟動代理程式：

   ```
   sudo service awslogsd restart
   ```

## 分隔 CloudWatch Logs 代理程式組態檔案
<a name="create-additional-configuration-files"></a>

如果您使用的是 awslogs-agent-setup.py 1.3.8 或更新版本及 awscli-cwlogs 1.3.3 或更新版本，您可以在 **/var/awslogs/etc/config/** 目錄中建立額外的組態檔案，為各種元件獨立匯入不同的串流組態。CloudWatch Logs 代理程式啟動時會包含這些額外組態檔案中的任何串流組態。[general] 區段中的組態屬性必須在主要組態檔案 (/var/awslogs/etc/awslogs.conf) 中定義，並且在 /var/awslogs/etc/config/ 中的任何額外的組態檔案中被忽略。

如果您因為使用 rpm 安裝代理程式，因此沒有 **/var/awslogs/etc/config/** 目錄，您可以改為使用 **/etc/awslogs/config/** 目錄。

重新啟動代理程式，讓變更生效：

```
sudo service awslogs restart
```

如果您使用的是 Amazon Linux 2，請使用下列命令來重新啟動代理程式：

```
sudo service awslogsd restart
```

## CloudWatch Logs 代理程式常見問答集
<a name="agent-faq"></a>

**支援哪些種類的檔案輪換？**  
支援以下檔案輪換機制：  
+ 以數值尾碼重新命名現有的日誌檔，然後重新建立原始的空日誌檔。例如，/var/log/syslog.log 重新命名為 /var/log/syslog.log.1. 如果 /var/log/syslog.log.1 從之前的輪換就已存在，它將會重新命名為 /var/log/syslog.log.2。
+ 在建立副本之後，截斷已備妥的原始日誌檔。例如，/var/log/syslog.log 將會複製到 /var/log/syslog.log.1，/var/log/syslog.log 將被截斷。在這種情況下，資料可能會遺失，因此請留意使用此檔案輪換機制。
+ 使用與舊檔案相同的通用模式建立新檔案。例如，保留 /var/log/syslog.log.2014-01-01，並建立 /var/log/syslog.log.2014-01-02。
檔案的指紋 (來源 ID) 的計算方式是雜湊日誌串流金鑰與檔案的第一行內容。若要覆寫此行為，可使用 **file\$1fingerprint\$1lines** 選項。發生檔案輪換時，新的檔案應該會有新的內容，舊的檔案不應該有附加的內容；代理程式會在完成讀取舊檔案之後推送新的檔案。

**我如何判斷我使用的代理程式是哪個版本？**  
如果是使用設定指令碼來安裝 CloudWatch Logs 代理程式，您可以使用 **/var/awslogs/bin/awslogs-version.sh** 來檢查您使用的代理程式是哪個版本。它會列印出代理程式的版本及其主要相依性。如果是使用 yum 來安裝 CloudWatch Logs 代理程式，您可以使用 **"yum info awslogs"** 和 **"yum info aws-cli-plugin-cloudwatch-logs"** 來檢查 CloudWatch Logs 代理程式和外掛程式的版本。

**日誌項目如何轉換為日誌事件？**  
日誌事件包含兩個屬性：事件發生時的時間戳記，以及原始日誌訊息。依據預設，開頭使用非空白字元的任何列皆可結束之前的日誌訊息 (如果有的話)，並開始新的日誌訊息。若要覆寫此行為，可以使用 **multi\$1line\$1start\$1pattern**，符合此模式的任何列都會開始新的日誌訊息。此模式可以是任何 regex 或「\$1datetime\$1format\$1」。例如，如果每個日誌訊息的第一行包含時間戳記，例如 '2014-01-02T13:13:01Z'，則 **multi\$1line\$1start\$1pattern** 可設定為 '\$1d\$14\$1-\$1d\$12\$1-\$1d\$12\$1T\$1d\$12\$1:\$1d\$12\$1:\$1d\$12\$1Z'。為了簡化組態，如果已指定 **datetime\$1format option**，您可以使用「\$1datetime\$1format\$1」變數。以相同的範例而言，如果 **datetime\$1format** 設為 '%Y-%m-%dT%H:%M:%S%z'，則 multi\$1line\$1start\$1pattern 可以只是「\$1datetime\$1format\$1」。  
若未提供 **datetime\$1format**，目前時間將用於每個日誌事件。如果提供的 **datetime\$1format** 對於指定的日誌訊息而言是無效的，將使用最後一個成功剖析時間戳記的日誌事件的時間戳記。如果沒有之前的日誌事件，將使用目前時間。當日誌事件回退至目前時間或之前的日誌事件時間，將會記錄警告訊息。  
時間戳記用於擷取日誌事件並產生指標，因此如果您指定錯誤的格式，可能會導致無法擷取日誌事件，並且會產生錯誤的指標。

**日誌事件會如何進行批次處理？**  
當下列任何一個條件成立時，批次將變滿並予以發佈：  

1. 從新增第一個日誌事件以來，已經過 **buffer\$1duration** 的時間長度。

1. 已累積小於 **batch\$1size** 的日誌事件，但新增超過 **batch\$1size** 的新日誌事件。

1. 達到 **batch\$1count** 的日誌事件數量。

1. 此批次的日誌事件未持續超過 24 小時，但新增新日誌事件過程超過 24 小時限制。

**什麼會導致日誌項目、日誌事件，或批次遭到略過或截斷？**  
若要遵循 `PutLogEvents` 操作的限制，以下問題可能會導致日誌事件或批次進行被略過。  
略過資料時，CloudWatch Logs 代理程式會將警告寫入日誌。

1. 如果日誌事件的大小超過 256 KB，將會完全略過該日誌事件。

1. 如果日誌事件的時間戳記超過未來 2 小時，將會略過該日誌事件。

1. 如果日誌事件的時間戳記超過過去 14 天，將會略過該日誌事件。

1. 如有任何日誌事件超過日誌群組的保留期間，將會略過整個批次。

1. 如果在單一 `PutLogEvents` 請求中的日誌事件批次持續超過 24 小時，則 `PutLogEvents` 操作會失敗。

**停用代理程式是否會造成資料遺失/重複？**  
只要有狀態檔案，而且從上次執行之後未發生檔案輪換，就不會造成資料遺失/重複。CloudWatch Logs 代理程式可以從停止的位置開始，並繼續推送日誌資料。

**我是否可以從相同或不同的主機，將不同的日誌檔指向相同的日誌串流？**  
不支援設定多個日誌來源，將資料傳送到單個日誌串流。

**代理程式發出哪些 API 呼叫 (或我應該將哪些動作新增至 IAM 政策)？**  
CloudWatch Logs 代理程式需要執行 `CreateLogGroup`、`CreateLogStream`、`DescribeLogGrooupd`、 `DescribeLogStreams``PutLogEvents`和 `PutRetentionPolicy`動作的許可。如果您使用的是最新的代理程式，則不需要 `DescribeLogStreams`。請參閱以下 IAM 政策範例。    
****  

```
{
"Version":"2012-10-17",		 	 	 
"Statement": [
  {
    "Effect": "Allow",
    "Action": [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
      "logs:DescribeLogStreams",
      "logs:DescribeLogGroups",
      "logs:PutRetentionPolicy"
    ],
    "Resource": [
      "arn:aws:logs:*:*:*"
    ]
  }
 ]
}
```

**我不希望 CloudWatch Logs 代理程式自動建立日誌群組或日誌串流。我要如何防止代理程式重新建立日誌群組與日誌串流？**  
您可以在 IAM 政策中限制代理程式只能執行以下操作：`DescribeLogStreams`、`PutLogEvents`。  
從代理程式撤銷 `CreateLogGroup` 和 `CreateLogStream` 許可前，請務必建立您要讓代理程式使用的日誌群組和日誌串流。日誌代理程式無法在您已建立的日誌群組中建立日誌串流，除非其擁有 `CreateLogGroup` 和 `CreateLogStream` 許可。

**進行故障排除時，我應該查看哪些日誌？**  
代理程式安裝日誌位於 `/var/log/awslogs-agent-setup.log`，代理程式日誌位於 `/var/log/awslogs.log`。