CloudWatch Logs 概述
Amazon CloudWatch Logs 是 AWS 提供的完全託管日誌管理服務,可讓您集中收集、監控和分析來自 AWS 服務、應用程式和本地伺服器的日誌資料。透過 CloudWatch Logs,您可以即時監控應用程式和系統日誌,設定告警,並使用 Logs Insights 進行進階查詢分析。
主要功能
- 集中式日誌管理:統一收集來自多個來源的日誌
- 即時監控:即時串流和檢視日誌資料
- 進階查詢:使用 Logs Insights 進行複雜的日誌分析
- 指標篩選器:從日誌資料中提取自訂指標
- 訂閱篩選器:將日誌串流到其他 AWS 服務
- 長期保存:可設定日誌保留期限,從 1 天到永久保存
核心概念
Log Group(日誌群組)
Log Group 是日誌串流的容器,用於組織和管理相關的日誌資料。通常會為每個應用程式或服務建立一個獨立的 Log Group。
1
2
3
4
5
| # 列出所有日誌群組
aws logs describe-log-groups
# 列出特定前綴的日誌群組
aws logs describe-log-groups --log-group-name-prefix /aws/lambda
|
Log Stream(日誌串流)
Log Stream 是 Log Group 內的日誌事件序列,通常代表單一來源(如特定的 EC2 執行個體或 Lambda 函數呼叫)。
1
2
3
4
5
6
7
8
9
10
11
| # 列出特定日誌群組內的日誌串流
aws logs describe-log-streams \
--log-group-name my-application-logs \
--order-by LastEventTime \
--descending
# 取得特定日誌串流的日誌事件
aws logs get-log-events \
--log-group-name my-application-logs \
--log-stream-name web-server-01 \
--limit 100
|
建立 Log Group
使用 AWS CLI 建立
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 建立日誌群組
aws logs create-log-group --log-group-name /app/my-application
# 建立帶有標籤的日誌群組
aws logs create-log-group \
--log-group-name /app/production/web-server \
--tags Environment=Production,Application=WebServer
# 建立日誌串流
aws logs create-log-stream \
--log-group-name /app/my-application \
--log-stream-name instance-001
# 手動寫入日誌事件
aws logs put-log-events \
--log-group-name /app/my-application \
--log-stream-name instance-001 \
--log-events timestamp=$(date +%s000),message="Application started successfully"
|
使用 AWS CLI 設定 KMS 加密
1
2
3
4
| # 建立具有 KMS 加密的日誌群組
aws logs create-log-group \
--log-group-name /app/secure-logs \
--kms-key-id arn:aws:kms:ap-northeast-1:123456789012:key/12345678-1234-1234-1234-123456789012
|
安裝 CloudWatch Agent
CloudWatch Agent 可收集系統層級的指標和日誌,並傳送到 CloudWatch。
在 Amazon Linux 2 / RHEL 安裝
1
2
3
4
5
6
7
8
| # 下載並安裝 CloudWatch Agent
sudo yum install amazon-cloudwatch-agent -y
# 或使用 SSM 安裝
aws ssm send-command \
--document-name "AWS-ConfigureAWSPackage" \
--targets "Key=instanceids,Values=i-1234567890abcdef0" \
--parameters "action=Install,name=AmazonCloudWatchAgent"
|
在 Ubuntu / Debian 安裝
1
2
3
4
5
| # 下載 CloudWatch Agent
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
# 安裝
sudo dpkg -i amazon-cloudwatch-agent.deb
|
設定 CloudWatch Agent
建立設定檔 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.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
| {
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "cwagent"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/syslog",
"log_group_name": "/ec2/syslog",
"log_stream_name": "{instance_id}",
"timezone": "UTC"
},
{
"file_path": "/var/log/nginx/access.log",
"log_group_name": "/ec2/nginx/access",
"log_stream_name": "{instance_id}",
"timezone": "UTC"
},
{
"file_path": "/var/log/nginx/error.log",
"log_group_name": "/ec2/nginx/error",
"log_stream_name": "{instance_id}",
"timezone": "UTC"
}
]
}
}
}
}
|
啟動 CloudWatch Agent
1
2
3
4
5
6
7
8
9
| # 使用設定檔啟動 Agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
# 檢查 Agent 狀態
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status
|
Logs Insights 查詢語法
CloudWatch Logs Insights 提供專用的查詢語言,可對日誌資料進行快速互動式分析。
基本查詢語法
1
2
3
4
5
6
7
8
9
| # 使用 AWS CLI 執行 Logs Insights 查詢
aws logs start-query \
--log-group-name /app/my-application \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @message | sort @timestamp desc | limit 20'
# 取得查詢結果
aws logs get-query-results --query-id "12345678-1234-1234-1234-123456789012"
|
常用查詢範例
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
| # 搜尋包含 ERROR 的日誌
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 100
# 統計每小時的錯誤數量
fields @timestamp, @message
| filter @message like /ERROR/
| stats count(*) as error_count by bin(1h)
# 分析 HTTP 狀態碼分布
fields @timestamp, @message
| parse @message /status=(?<status>\d+)/
| stats count(*) by status
# 計算平均回應時間
fields @timestamp, @message
| parse @message /response_time=(?<response_time>\d+)/
| stats avg(response_time) as avg_time, max(response_time) as max_time by bin(5m)
# 找出最慢的請求
fields @timestamp, @message
| parse @message /response_time=(?<response_time>\d+)/
| sort response_time desc
| limit 10
|
指標篩選器
指標篩選器可從日誌資料中提取數值並建立 CloudWatch 指標。
建立指標篩選器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 建立錯誤計數指標篩選器
aws logs put-metric-filter \
--log-group-name /app/my-application \
--filter-name ErrorCount \
--filter-pattern "ERROR" \
--metric-transformations \
metricName=ApplicationErrors,metricNamespace=MyApplication,metricValue=1,defaultValue=0
# 建立回應時間指標篩選器
aws logs put-metric-filter \
--log-group-name /app/my-application \
--filter-name ResponseTime \
--filter-pattern '[timestamp, request_id, level, response_time]' \
--metric-transformations \
metricName=ResponseTime,metricNamespace=MyApplication,metricValue='$response_time'
# 列出現有的指標篩選器
aws logs describe-metric-filters --log-group-name /app/my-application
|
為指標建立告警
1
2
3
4
5
6
7
8
9
10
11
12
| # 建立錯誤數量告警
aws cloudwatch put-metric-alarm \
--alarm-name "HighErrorRate" \
--alarm-description "應用程式錯誤數量過高" \
--metric-name ApplicationErrors \
--namespace MyApplication \
--statistic Sum \
--period 300 \
--threshold 10 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:ap-northeast-1:123456789012:alerts
|
訂閱篩選器
訂閱篩選器可將符合條件的日誌即時串流到其他 AWS 服務。
串流到 Kinesis Data Firehose
1
2
3
4
5
6
7
| # 建立 Kinesis Data Firehose 訂閱
aws logs put-subscription-filter \
--log-group-name /app/my-application \
--filter-name AllLogs \
--filter-pattern "" \
--destination-arn arn:aws:firehose:ap-northeast-1:123456789012:deliverystream/my-stream \
--role-arn arn:aws:iam::123456789012:role/CWLtoKinesisRole
|
串流到 Lambda 函數
1
2
3
4
5
6
7
8
9
10
11
| # 建立 Lambda 訂閱篩選器
aws logs put-subscription-filter \
--log-group-name /app/my-application \
--filter-name ErrorsToLambda \
--filter-pattern "ERROR" \
--destination-arn arn:aws:lambda:ap-northeast-1:123456789012:function:ProcessErrors
# 刪除訂閱篩選器
aws logs delete-subscription-filter \
--log-group-name /app/my-application \
--filter-name ErrorsToLambda
|
跨帳戶日誌共享
1
2
3
4
5
6
7
8
9
10
| # 在目標帳戶建立日誌目的地
aws logs put-destination \
--destination-name SharedLogDestination \
--target-arn arn:aws:kinesis:ap-northeast-1:123456789012:stream/shared-logs \
--role-arn arn:aws:iam::123456789012:role/CWLtoKinesisRole
# 設定目的地存取政策
aws logs put-destination-policy \
--destination-name SharedLogDestination \
--access-policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"111111111111"},"Action":"logs:PutSubscriptionFilter","Resource":"arn:aws:logs:ap-northeast-1:123456789012:destination:SharedLogDestination"}]}'
|
日誌保留設定
適當的日誌保留設定可平衡合規需求和儲存成本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 設定日誌保留期限為 30 天
aws logs put-retention-policy \
--log-group-name /app/my-application \
--retention-in-days 30
# 可用的保留期限選項:
# 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653
# 移除保留限制(永久保存)
aws logs delete-retention-policy --log-group-name /app/my-application
# 批次設定多個日誌群組的保留期限
for log_group in $(aws logs describe-log-groups --query 'logGroups[*].logGroupName' --output text); do
aws logs put-retention-policy --log-group-name "$log_group" --retention-in-days 90
done
|
成本優化
CloudWatch Logs 的費用主要來自資料擷取、儲存和查詢。以下是一些成本優化策略:
1. 設定適當的保留期限
1
2
3
4
5
6
7
8
9
| # 針對不同環境設定不同保留期限
# 開發環境:7 天
aws logs put-retention-policy --log-group-name /app/dev --retention-in-days 7
# 測試環境:14 天
aws logs put-retention-policy --log-group-name /app/staging --retention-in-days 14
# 生產環境:90 天
aws logs put-retention-policy --log-group-name /app/production --retention-in-days 90
|
2. 使用日誌類別降低成本
1
2
3
4
| # 建立使用不常存取日誌類別的日誌群組
aws logs create-log-group \
--log-group-name /app/archive-logs \
--log-group-class INFREQUENT_ACCESS
|
3. 匯出日誌到 S3
1
2
3
4
5
6
7
8
9
10
| # 建立匯出任務到 S3
aws logs create-export-task \
--log-group-name /app/my-application \
--from $(date -d '30 days ago' +%s000) \
--to $(date +%s000) \
--destination my-log-archive-bucket \
--destination-prefix exports/my-application
# 檢查匯出任務狀態
aws logs describe-export-tasks --task-id "task-id-here"
|
4. 過濾不必要的日誌
在 CloudWatch Agent 設定中排除不需要的日誌:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| {
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/app/*.log",
"log_group_name": "/app/logs",
"log_stream_name": "{instance_id}",
"filters": [
{
"type": "exclude",
"expression": "DEBUG"
}
]
}
]
}
}
}
}
|
5. 監控 CloudWatch Logs 使用量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 查看日誌群組的儲存大小
aws logs describe-log-groups \
--query 'logGroups[*].[logGroupName,storedBytes]' \
--output table
# 建立成本告警
aws cloudwatch put-metric-alarm \
--alarm-name "CloudWatchLogsHighIngestion" \
--metric-name IncomingBytes \
--namespace AWS/Logs \
--statistic Sum \
--period 86400 \
--threshold 10737418240 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--alarm-actions arn:aws:sns:ap-northeast-1:123456789012:billing-alerts
|
參考資料