CloudWatch Agent (底下簡稱 CWA) 是 awslogs 的後續版本,提供了更強大的功能與整合能力。整理 CWA 的基本概念、如何安裝與配置、以及常見問題。
本文範例為 地端 (On-Premise) Linux (Ubuntu 16.04) 為例。
體驗
簡介
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 cd /tmpwget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb dpkg -i -E ./amazon-cloudwatch-agent.deb passwd cwagent mkhomedir_helper cwagent cd /opt/awschown -R cwagent.cwagent amazon-cloudwatch-agent./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 cd /opt/aws/amazon-cloudwatch-agent/binsudo ./amazon-cloudwatch-agent-ctl \ -a start \ -m onPremise tree ../etc sudo ./amazon-cloudwatch-agent-ctl \ -a status sudo systemctl status amazon-cloudwatch-agent.servicesudo ./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,下述步驟參照著一開始的 執行週期圖 對照看。
1 2 3 4 5 6 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 sudo systemctl start amazon-cloudwatch-agent.service
1 2 3 4 5 6 7 sudo ./amazon-cloudwatch-agent-ctl \ -a stop \ -m onPremise sudo systemctl stop amazon-cloudwatch-agent.service
1 2 3 4 5 6 sudo ./amazon-cloudwatch-agent-ctl \ -a status 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 … 等。
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-ctl、systemctl 啟動、重啟 CWA
調整配置檔,包含了 Metrics、Log
2. Running: 可以正常啟動 CWA
透過 amazon-cloudwatch-agent-ctl、systemctl 暫停 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.servicesudo systemctl disable amazon-cloudwatch-agent.service
Q and A 配置問題
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: 確認這幾個:
指定的 file_path 是否正確
執行的身份是否有權限存取
Q: CW Log Group 需要手動建立?如果砍了會怎樣?
A1: 不用手動建立,CWA 會自行建立。 A2: 砍了 Log Group,只要監控的檔案有異動,CWA 會馬上重新建立。不過舊資料不會存在。
Q: 我已經配置了 Log,但是 Log Group 一直都沒有資料進來?
A: 依照以下檢查:
檢查 /var/log/amazon/amazon-cloudtach-agent 裡的訊息沒有錯誤。
檢查配置檔裡的 Log 路徑是否正確。
A: 有兩個條件:
force_flush_interval 預設每五秒往 CWL 送一次
CWA 會把資料放在記憶體,然後大小到達 1MB 就會往 CWL 送。
延伸閱讀 系列文章
參考資料
相關工具
相關課題