Study Notes - CloudWatch Metrics


整理 CloudWatch Metrics 的相關資料。


CloudWatch Metrics

Metrics 可以說成 監控指標項目, AWS 各個服務預設很多監控指標,可以在 CloudWatch 上看到相關數據,也可以透過 AWS CLI or SDK 取得數據。要取得 CloudWatch 資料,就要先了解 CloudWatch Metrics 的設計與資料結構:

  • Namespaces: Metrics 的容器 (Container), 就是用來分類 AWS 服務的, 用 slash / 區隔. 像是 AWS/EC2, AWS/DynamoDB. 詳細參閱 [AWS Namespaces][12].
  • Metrics: 意思是 度量, 是一個時間軸 (time-base) 的資料集合. 像是 ELB 的 HealthyHostCount, RequestCount, SurgeQueueLength 都叫做 Metrics.
  • Dimensions: 量測的資源對象 (ARN),是 Key/Value 呈現,像是 Name=InstanceId,Value=${INSTANCE_ID}, Name=LoadBalancerName,Value=${ARN_ID}
  • Statistics: 時間範圍之內的統計方式,包含了:Sum, Minimum, Maximum, and SampleCount.

Metric Filter

Metric Filter 是 CloudWatch Log 中重要的功能,透過 Metric Filter 可以定義自己的 Metric,進而變成 Alarm 或者呈現 Dashboard,他有點像是 ELK 的 Logstash 的角色,主要就是把欄位做對應以及過濾。

底下是我透過 AWS CLI 建立 Metric Filter 處理 Nginx Log 的例子:

1
2
3
4
5
6
7
8
9
10
FILTER_NAME="Connection-Request_Filter"

# 過濾 local health check
FILER_PATTERN="[time_iso8601, remote_user, status, body_bytes_sent, http_referer, server_name != 127.0.0.1, upstream_addr, request, request_length, http_user_agent, remote_addr, proxy_protocol_addr, http_x_forwarded_for, proxy_add_x_forwarded_for, request_time, http_host, scheme, msec, connection, connection_requests, connections_active, connections_reading, connections_writing, connections_waiting]"

aws logs put-metric-filter \
--log-group-name "${LOG_GROUP_NAME}" \
--filter-name "${FILTER_NAME}" \
--filter-pattern "${FILER_PATTERN}" \
--metric-transformations metricName=Connection-Active,metricNamespace=Nginx/Connection-Request,metricValue=1,defaultValue=0.0

如果上傳的 Log 是 JSON,Metric Filter 也支援,他的寫法大概長得像這樣:

這是查詢 Cloudtrail Event 的 Metric Filter:有人開了 *.8xlarge or *.4xlarge 的機器

1
{ ($.eventName = RunInstances) && (($.requestParameters.instanceType = *.8xlarge) || ($.requestParameters.instanceType = *.4xlarge)) }

Custom Metrics

有一些資訊 CloudWatch 本身是不提供的,像是 EC2 Instance 的記憶體、磁碟使用空間 (Disk Usage Percent),或者是自己的 Application Servers 像是 Nginx、Tomcat、IIS、Node.js … 需要監控這些 Servers 的相關數據,像是 Nginx 的記憶體使用例、Connection Request、Tomcat 的 JVM HeapSize … 等。那麼就要自行蒐集相關資料、儲存這些資料。

參考:[Monitoring Memory and Disk Metrics for Amazon EC2 Linux Instances][15]

如果是要從自己的 Log 分析出相關資訊,就要透過 CloudWatch Log + Filter 建立自己的 Metric,同樣的這也是 Custom Metrics。像 Nginx or JVM HeapSize 就可以這樣做。

使用 Custom Metrics 要注意怎麼設計 Namespaces, Dimensions,例如依照機器角色分 Namespace,依照角色 Metric 分 Dimension,依照商業邏輯把相關的放一起,日後好整理。

Custom Metrics 不能透過 AWS Console or CLI 刪除,只能等它自己慢慢消失 ..

取得 Metrics 的 DataPoint

有時候需要自行分析 CloudWatch Metric 的數據,或者重新 Aggregation ,例如:

計算一群機器的平均 CPU Utilization,然後平均之後決定是否驅動事件,像是透過 SNS 通知

以下是用 AWS CLI 透過 crontab 固定取得 metric 的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
AWS_PROFILE="<<AWS-PROFILE>>"
INSTANCE_ID="<<EC2-INSTNACE-ID>>"
AWS_REGION="ap-northeast-1"
OUTPUT_TYPE="text"
period=300

# Calculate local time as UTC, there is local time -8 = UTC. my server is local time (UTC+8).
start_time=`date +'%Y-%m-%dT%H:%M:00' --date='-8 hour -10 min'`
end_time=`date +'%Y-%m-%dT%H:%M:00' --date='-8 hour'`

aws cloudwatch get-metric-statistics \
--metric-name CPUUtilization \
--start-time ${start_time} \
--end-time ${end_time} \
--period ${period} \
--namespace AWS/EC2 \
--statistics Average \
--dimensions Name=InstanceId,Value=${INSTANCE_ID} \
--output ${OUTPUT_TYPE} \
--region ${AWS_REGION} \
--profile ${AWS_PROFILE}

Return as text

1
2
3
CPUUtilization
DATAPOINTS 30.24 2016-07-11T06:00:00Z Percent
DATAPOINTS 34.034 2016-07-11T06:05:00Z Percent

Return as json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"Datapoints": [
{
"Timestamp": "2016-07-11T06:00:00Z",
"Average": 30.240000000000002,
"Unit": "Percent"
},
{
"Timestamp": "2016-07-11T06:05:00Z",
"Average": 34.034000000000006,
"Unit": "Percent"
}
],
"Label": "CPUUtilization"
}

這邊要去深入了解每個 Unit, Statistics 以及 Period 等意義是什麼,才能計算出需要的東西。

處理統計資料,通常要過濾很多不必要的資訊,AWS CLI 可以配合 JEMSPath 找到要的欄位,透過 --query 過濾不必要的資訊,詳細參閱 [Ops as Code with AWS CLI][1] 的例子。


延伸閱讀

系列文章


Comments