Study Notes - CloudWatch Agent for Linux


CloudWatch Agent (底下簡稱 CWA)awslogs 的後續版本,提供了更強大的功能與整合能力。整理 CWA 的基本概念、如何安裝與配置、以及常見問題。

本文範例為 地端 (On-Premise) Linux (Ubuntu 16.04) 為例。

  1. 體驗
  2. 簡介
  3. Q and A

體驗

先動手體驗看看,這邊在本機的 VMWare 上安裝 Ubuntu 16.04 為例,然後把 Log 往 AWS us-west-2 送。

準備工作

先安裝好一台乾淨的 Ubuntu 16.04,然後開始以下流程。

安裝 CWA

底下的指令 run as root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 0. 檢查是否已經安裝
# 0-1. 檢查 systemctl status amazon-cloudwatch-agent
# 0-2. 移除舊版: apt-get remove amazon-cloudwatch-agent

# 1-0. 下載並安裝 amazon-cloudwatch-agent
## Ubuntu 16.04
cd /tmp
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
dpkg -i -E ./amazon-cloudwatch-agent.deb

## AWS Linux2 / CentoOS
#wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
#sudo rpm -U ./amazon-cloudwatch-agent.rpm

## 完成安裝之後,檢查以下:
## 1-1. CWA 安裝在 /opt/aws/amazon-cloudwatch-agent
## 1-2. 會建立新使用者身份:user: cwagent, group: cwagent, 把這個使用者加入 sudo gorup


## 2-0. 為了方便工作,設定 cwagent 的密碼
passwd cwagent

## 2-1. 初始化使用者 cwagent home
mkhomedir_helper cwagent

## 3. 設定 /opt/aws/amazon-cloudwatch-agent 的權限
cd /opt/aws
chown -R cwagent.cwagent amazon-cloudwatch-agent

## 4. 檢查 cwa 版本
./amazon-cloudwatch-agent version
2019/09/15 16:35:55 I! AmazonCloudWatchAgent Version 1.227496.0.
AmazonCloudWatchAgent v1.227496.0

設定 cwagent 的 IAM Credential

  • 準備 IAM User / Policy:
    • 到 AWS Console 建立 一個 IAM Programmatic User: cwagent
    • 給予 IAM Policy: CloudWatchAgentServerPolicy
  • 使用 cwagent 登入機器,配置 aws configure,設定 profile.

註:安裝 AWS CLI

1
2
apt-get update && apt-get install python-pip
pip install awscli

配置 common-config.toml

重新以 cwagent 登入機器,然後修改配置檔,設定 credentials 段落如下:

/opt/aws/amazon-cloudwatch-agent/etc/common-config.toml
1
2
3
[credentials]
shared_credential_profile = "default"
shared_credential_file = "/home/cwagent/.aws/credentials"

這樣的設定是告訴 cwa 使用 cwagent 的 credential.

體驗 CWA - 預設配置

如果準備工作順利的話,就直接開始 CWA 了,執行底下步驟:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Run as cwagent
## Start CWA using onPremise mode without any config.
cd /opt/aws/amazon-cloudwatch-agent/bin
sudo ./amazon-cloudwatch-agent-ctl \
-a start \
-m onPremise

## Confrim the config is empty.
tree ../etc

## Get CWA status
sudo ./amazon-cloudwatch-agent-ctl \
-a status

## Get CWA status using systemd
sudo systemctl status amazon-cloudwatch-agent.service

## Check Logs
### See screen on button

## Stop CWA
sudo ./amazon-cloudwatch-agent-ctl \
-a stop \
-m onPremise

sudo systemctl status amazon-cloudwatch-agent.service

上述動作的錄影如下:

這個範例沒有提供任何的配置檔,所以 CWA 自動產生了一個範例配置,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"agent": {
"run_as_user": "cwagent"
},
"metrics": {
"metrics_collected": {
"mem": {
"measurement": ["mem_used_percent"]
},
"disk": {
"measurement": ["used_percent"],
"resources": ["*"]
}
}
}
}

描述了配置記憶體 (mem) 與磁碟 (disk) 的 Metrics。

如果順利的話,過一下子,到 CloudWatch Metrics 會發現多一個 Custom Namespace,裡面有一個叫做 CWAgent,點進去會看到類似底下的圖:



執行週期指令

底下整理 CWA 執行週期執行的方法,執行身份都是 cwagent,下述步驟參照著一開始的 執行週期圖 對照看。

  • 第一次啟動、或者 Config 有異動
1
2
3
4
5
6
# 指定 Config 位置
sudo ./amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m onPremise \
-c file:${CWA_CONFIG} \
-s
  • 啟動 CWA,不指定 Config,或者 Config 已經配置
1
2
3
4
5
6
7
sudo ./amazon-cloudwatch-agent-ctl \
-a start \
-m onPremise

# OR

sudo systemctl start amazon-cloudwatch-agent.service
  • 停止 CWA
1
2
3
4
5
6
7
sudo ./amazon-cloudwatch-agent-ctl \
-a stop \
-m onPremise

# OR

sudo systemctl stop amazon-cloudwatch-agent.service
  • 取得 CWA 狀態
1
2
3
4
5
6
sudo ./amazon-cloudwatch-agent-ctl \
-a status

# OR

sudo systemctl status amazon-cloudwatch-agent.service

簡介

CloudWatch Agent 支援以下組合:

  • Where: 可以在哪跑
    • On EC2 / On Premise: 雲端 (AWS) 或者地端、或者說非 AWS
    • On Linux / Windows: 支援兩個主流作業系統
    • On Container: 支援 K8s / EKS / ECS,參閱 Using Container Insights
  • Config Source: 配置檔的來源
    • local files: 儲存在本地端
    • SSM Parameter Store
    • CloudFormation
  • 支援功能:
    • System Metrics: 常見的系統指標,像是 CPU、Memory、Disk I/O … 等。
      • 支援 Linux 與 Windows
    • Application Log Files: 應用程式 Log 送到 CloudWatch Log
    • Plugins: 除了 CWA 自己,另外支援第三方工具的整合,包含了 procstat, StatsD, collectd

縮寫名詞

  • CWA: CloudWatch Agent
  • CWL: CloudWatch Logs
  • SSM: AWS Systems Manager

執行週期

CloudWatch Agent (CWA) 的使用有點小複雜,所以整理以下執行狀態圖的全貌,比較容易了解:

使用上分成幾個狀態:

  • 0. Initial: 第一次使用,需要準備以下事項
    • 安裝 CWA、準備好執行身份
    • 準備權限設定檔: common-config.toml
    • 準備 CWA 配置檔: json 格式,可以透過檔案或者 AWS SSM Parameter Store 取得。
      • 注意: Parameter Store 最大 8KiB.
  • 1. Ready: 配置準備好了
    • 透過 amazon-cloudwatch-agent-ctlsystemctl 啟動、重啟 CWA
    • 調整配置檔,包含了 Metrics、Log
  • 2. Running: 可以正常啟動 CWA
    • 透過 amazon-cloudwatch-agent-ctlsystemctl 暫停 CWA
  • 3. Stopped: 停止 CWA

目錄結構

安裝 CWA 之後,會在系統出現類似以下目錄結構,整理其中主要的用途以及資訊:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.
`-- amazon-cloudwatch-agent
|-- bin
| |-- amazon-cloudwatch-agent // [bin] CWA 主程式
| |-- amazon-cloudwatch-agent-config-wizard // [bin] Config 產生器
| |-- amazon-cloudwatch-agent-ctl // [sh] CWA Controller
| |-- config-downloader // [bin] Config 下載器
| |-- config-translator // [bin] Config 轉換器
| |-- CWAGENT_VERSION
| `-- start-amazon-cloudwatch-agent // [bin] CWA 啟動器
|-- doc
| `-- amazon-cloudwatch-agent-schema.json // CWA Config JSON Schema
|-- etc
| |-- amazon-cloudwatch-agent.d // CWA Config Folder (MUST exist!)
| | `-- file_cwa-config.json // CWA Config in runtime
| |-- amazon-cloudwatch-agent.toml // generated by config-translator
| `-- common-config.toml // Config Profile, Proxy
|-- LICENSE
|-- logs // CWA logs
| |-- amazon-cloudwatch-agent.log
| |-- configuration-validation.log
| `-- state // State of log shipper
| |-- _var_log_amazon_amazon-cloudwatch-agent_amazon-cloudwatch-agent.log
| |-- _var_log_amazon_amazon-cloudwatch-agent_configuration-validation.log
| |-- _var_log_syslog
| `-- _var_log_tomcat_catalina.out
|-- manager
|-- NOTICE
|-- RELEASE_NOTES
|-- THIRD-PARTY-LICENSES
`-- var
`-- amazon-cloudwatch-agent.pid

另外會在 systemd 註冊 amazon-cloudwatch-agent service,然後開啟自動啟動。

配置檔

CWA 配置檔是 JSON 資料結構,檔案可以是一個或者多個, 官方文件 有很詳述的描述。第一次使用可以使用內建的工具 amazon-cloudwatch-agent-config-wizard 產生一份。CWA 配置檔是整個服務的核心,包含三大部分,整理如下圖:

CWA 的配置檔是最重要的部分,分成三大部分,這三大部分沒有依賴關係,但每次的配置都至少要有 Metric or Logs 其中之一。

  • Agent Section: 是啟動 CWA 一些必要資訊,但是裡面的欄位都是 optional 的。
  • Metrics Section: 是配置要蒐集哪一些系統資訊、這些資訊要往哪裡送、儲存在哪裡 … 等
  • Logs Section: 配置要蒐集哪一些應用程式的 Log、時間格式、往哪裡送

拆分配置檔

CWA 的 Config 可以拆分成不同的部分,便於管理,使用方式主要是透過 controller 的 append-config 方式附加上去。底下的範例是把 config 拆成若干檔案:

  • 00-1_config_system-logs.json
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    {
    "agent": {
    "metrics_collection_interval": 60,
    "run_as_user": "cwagent"
    },
    "logs": {
    "logs_collected": {
    "files": {
    "collect_list": [
    {
    "file_path": "/var/log/syslog",
    "log_group_name": "/sys/log/system",
    "log_stream_name": "{hostname}-syslog"
    },
    {
    "file_path": "/var/log/dpkg.log",
    "log_group_name": "/sys/log/system",
    "log_stream_name": "{hostname}-dpkg.log"
    },
    {
    "file_path": "/var/log/auth.log",
    "log_group_name": "/sys/log/system",
    "log_stream_name": "{hostname}-auth.log"
    },
    {
    "file_path": "/var/log/lastlog",
    "log_group_name": "/sys/log/system",
    "log_stream_name": "{hostname}-lastlog"
    }
    ]
    }
    }
    }
    }
  • 00-2_config_system-metrics.json
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    {
    "metrics": {
    "namespace": "GTLab",
    "metrics_collected": {
    "cpu": {
    "measurement": [
    "cpu_usage_idle",
    "cpu_usage_iowait",
    "cpu_usage_steal",
    "cpu_usage_guest",
    "cpu_usage_user",
    "cpu_usage_system",
    { "name": "cpu_usage_nice", "unit": "Percent" }
    ],
    "metrics_collection_interval": 10,
    "resources": ["*"],
    "totalcpu": true
    },
    "disk": {
    "measurement": ["used_percent", "disk_free", "disk_total", "disk_used"],
    "metrics_collection_interval": 60,
    "resources": ["/", "/tmp"],
    "ignore_file_system_types": ["sysfs", "devtmpfs"]
    },
    "diskio": {
    "measurement": [
    "io_time",
    "write_bytes",
    "read_bytes",
    "writes",
    "reads"
    ],
    "metrics_collection_interval": 60,
    "resources": ["*"]
    },
    "mem": {
    "measurement": [
    "mem_used_percent",
    "mem_total",
    "mem_used",
    "mem_free",
    "mem_buffered",
    "mem_cached"
    ],
    "metrics_collection_interval": 60
    },
    "net": {
    "measurement": [
    "bytes_sent",
    "bytes_recv",
    "packets_sent",
    "packets_recv"
    ],
    "metrics_collection_interval": 60,
    "resources": ["*"]
    },
    "netstat": {
    "measurement": ["tcp_established", "tcp_time_wait"],
    "metrics_collection_interval": 60
    },
    "swap": {
    "measurement": ["swap_used_percent"],
    "metrics_collection_interval": 60
    }
    }
    }
    }
  • 10-1_config_tomcat-log.json
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    {
    "logs": {
    "logs_collected": {
    "files": {
    "collect_list": [
    {
    "file_path": "/var/log/tomcat/catalina.out",
    "log_group_name": "/sys/log/tomcat",
    "log_stream_name": "{hostname}-catalina.out",
    "timestamp_format": "%d-%b-%Y %H:%M:%S",
    "timezone": "Local"
    },
    {
    "file_path": "/var/log/tomcat/probe.log",
    "log_group_name": "/sys/log/tomcat",
    "log_stream_name": "{hostname}-probe",
    "timestamp_format": "%H:%M:%S",
    "timezone": "Local"
    },
    {
    "file_path": "/var/log/tomcat/localhost_access_log.*",
    "log_group_name": "/sys/log/tomcat",
    "log_stream_name": "{hostname}-localhost",
    "timestamp_format": "%d-%b-%Y %H:%M:%S",
    "timezone": "Local"
    }
    ]
    }
    }
    }
    }

啟動這些配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## 主要的
sudo ./amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/home/cwagent/conf/00-1_config_system-logs.json \
-s

sudo ./amazon-cloudwatch-agent-ctl \
-a append-config \
-m ec2 \
-c file:/home/cwagent/conf/00-2_config_system-metrics.json \
-s

sudo ./amazon-cloudwatch-agent-ctl \
-a append-config \
-m ec2 \
-c file:/home/cwagent/conf/10-1_config_tomcat-log.json \
-s

過程會看到底下的 Log:

1
2
3
4
5
2019/09/15 08:55:27 I! Config has been translated into TOML /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
2019/09/15 08:55:27 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json ...
2019/09/15 08:55:27 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_00-1_config_cwa-agent.json ...
2019/09/15 08:55:27 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_00-2_config_system-metrics.json ...
2019/09/15 08:55:27 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_00-3_config_cwa-logs.json ...

增加 AP 的 Config,以 Tomcat Log 為例:

1
2
3
4
5
sudo ./amazon-cloudwatch-agent-ctl \
-a append-config \
-m ec2 \
-c file:/home/cwagent/conf/10-1_config_tomcat-log.json \
-s

Log 時間格式

搬移 Log 到 CWL 之後,通常要對齊時間,以便於搜尋,如果 Log 的時間與 CWL 的時間沒對齊,那麼之後搜尋或者統計報表時將會是災難。

要注意:CWL 的時間是以 UTC 為主。

底下的配置是常見的範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"agent": {
"run_as_user": "cwagent",
"debug": true
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/tmp/cwa-test.log",
"log_group_name": "/sys/log/test",
"log_stream_name": "{hostname}",
"timezone": "Local",
"timestamp_format": "%Y-%m-%dT%H:%M:%S"
}
]
}
}
}
}

關鍵設定:

  • timezone: Local
  • timestamp_format: %Y-%m-%dT%H:%M:%S

把這個設定套用之後,用以下測試:

1
2
3
4
5
for item in {1..100};
do
echo "$(date +%Y-%m-%dT%H:%M:%S), Test" >> /tmp/cwa-test.log
sleep 1
done

每秒寫入一筆 Log,然後到 CWL 確認時間是否正確,如下圖左邊欄位是 CWL 收到 Log 的時間,資料是我們送上去的資料:

後續

因為 CloudWatch 的費用是算 API Call / Storage ,所以做完 Lab 之後,為了避免不知名的成本,建議把 CWA 停掉,透過以下方式:

1
2
sudo systemctl stop amazon-cloudwatch-agent.service
sudo systemctl disable amazon-cloudwatch-agent.service

Q and A

配置問題

  • Q: CWA 有 Debug Mode?

A: 有的,在 Config 的 Agent Section,把 debug 設定成 true 即可。

  • Q: 無法正常啟動 CWA,出現以下錯誤訊息,怎麼處理?
    1
    2
    3
    4
    5
    6
    7
    8
    amazon-cloudwatch-agent is not configured. Applying default configuration before starting it.
    /opt/aws/amazon-cloudwatch-agent/bin/config-downloader --output-dir /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d --download-source default --mode onPrem --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml --multi-config default
    Got Home directory: /root
    I! Set home dir Linux: /root
    I! SDKRegionWithCredsMap region: us-west-2
    Cannot access /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d: lstat /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d: no such file or directoryFailed to write the json file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/default.tmp: open /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/default.tmp: no such file or directory

    Fail to fetch the config!

A: 確認目錄 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ 是否存在,如果不存在,手動建立即可。注意權限。

Metric 問題

  • Q: ClouWatch Metric 的名稱,像是 cpu_usage_idle 可以改?

A: 可以,範例如下,measurement 可以使用 dict 個別指定 rename metric,並指定 unit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"metrics": {
"metrics_collected": {
"cpu": {
"measurement": [
{"name": "cpu_usage_idle", "rename": "CPU_USAGE_IDLE", "unit": "Percent"},
"cpu_usage_iowait",
"cpu_usage_steal",
"cpu_usage_guest",
"cpu_usage_user",
"cpu_usage_system",
{"name": "cpu_usage_nice", "unit": "Percent"}
],
"metrics_collection_interval": 10,
"resources": ["*"],
"totalcpu": true
}
}
}
}
  • Q: ClouWatch Metric 的 Custom Namespace 可以刪除?

A: 不行,兩週之後會自動刪除。

  • Q: ClouWatch Metric 的 Custom Namespace 名稱預設是 CWAgent,可以指定?

A: 可以,在 Metrics Section 使用 “namespace” 指定即可。

Log 問題

  • Q: Log 沒有上傳到 CloudWatch Logs?

A: 確認這幾個:

  1. 指定的 file_path 是否正確
  2. 執行的身份是否有權限存取
  • Q: CW Log Group 需要手動建立?如果砍了會怎樣?

A1: 不用手動建立,CWA 會自行建立。
A2: 砍了 Log Group,只要監控的檔案有異動,CWA 會馬上重新建立。不過舊資料不會存在。

  • Q: 我已經配置了 Log,但是 Log Group 一直都沒有資料進來?

A: 依照以下檢查:

  1. 檢查 /var/log/amazon/amazon-cloudtach-agent 裡的訊息沒有錯誤。
  2. 檢查配置檔裡的 Log 路徑是否正確。
  • Q: CWA 的 Log Ship 有多即時?

A: 有兩個條件:

  1. force_flush_interval 預設每五秒往 CWL 送一次
  2. CWA 會把資料放在記憶體,然後大小到達 1MB 就會往 CWL 送。

延伸閱讀

系列文章

參考資料

相關工具

相關課題



Comments

  • 全站索引
  • 關於這裏
  • 關於作者
  • 學習法則
  • 思考本質
  • 一些領悟
  • 分類哲學
  • ▲ TOP ▲