examlab .net 用最有效率的方法,考取最有價值的認證
Vol. I
本篇導覽 約 37 分鐘

CloudWatch Logs、Log Groups 與 Logs Insights

7,250 字 · 約 37 分鐘閱讀 ·

SOA-C02 實戰指南:Amazon CloudWatch Logs 全覽 — log groups、log streams、retention policies、KMS 加密、metric filters、subscription filters 到 Lambda/Kinesis Firehose/OpenSearch、Logs Insights 查詢語言(fields/filter/stats/sort)、CloudWatch agent 日誌收集、S3 匯出、跨帳號日誌彙整,以及 SysOps 疑難排解模式。

立即做 20 題練習 → 免費 · 不用註冊 · SOA-C02

Amazon CloudWatch Logs 是每一個 AWS 工作負載的運維證據庫,在 SOA-C02 中也是 Domain 1 與 metrics 和 alarms 並列的第二支柱。Metrics 告訴你「有東西出問題了」,Logs 則告訴你「到底哪裡出了問題」——stack trace、失敗的查詢、被拒絕的封包、被拒絕的 IAM 呼叫。Domain 1(監控、日誌與補救)佔全卷 20%,Task Statement 1.1 明確要求考生「識別、收集、分析和匯出日誌(例如 Amazon CloudWatch Logs、CloudWatch Logs Insights、AWS CloudTrail logs)」以及「建立 metric filters」。SAA-C03 可能問「哪個 AWS 服務可以收集應用程式日誌?」,SOA-C02 問的是「log group 存在,但新的 EC2 instances 沒有推送日誌——列出每一個診斷步驟」,或者「寫一個 Logs Insights query,回傳過去六小時內出現次數最多的前十個錯誤訊息」。

本指南從 SysOps 角度走過 CloudWatch Logs 全流程:log group / log stream 模型如何運作、為什麼 retention 預設為「Never Expire」(以及這會帶來多少費用)、metric filters 如何將文字模式轉換為可設 alarm 的數值、subscription filters 如何即時串流日誌到 Lambda 或 Firehose 供 SIEM 擷取、完整的 Logs Insights 查詢語言與事故中實際會用到的運維查詢、CloudWatch agent 的日誌收集設定(包含 multiline 處理)、S3 匯出用於長期封存、透過 resource policies 和 destinations 進行跨帳號日誌彙整,以及反覆出現的 SOA-C02 疑難排解場景——agent 未發布、IAM 權限缺口,以及 metric filters 不會回溯掃描歷史資料的陷阱。

為什麼 CloudWatch Logs 是 SOA-C02 Domain 1.1 的核心

官方 SOA-C02 Exam Guide v2.3 在 Task Statement 1.1 第一條技能子項中明確列出 CloudWatch Logs 和 CloudWatch Logs Insights,第四條列出 metric filters,第二條列出 CloudWatch agent 日誌收集。TS 1.1 六條技能中有三條是 CloudWatch Logs 工作。再加上 Task Statement 1.2(根據日誌和 metrics 進行補救),依賴關係就清晰了:Domain 1.2 中每一個 alarm 驅動的補救動作,要麼讀取 log group 上 metric filter 產生的數值,要麼監看 Logs Insights 排程查詢的輸出。Logs 同時也是 CloudTrail(Domain 1.1)和 VPC Flow Logs(Domain 5.3)賴以保存和分析的資料來源。

在 SysOps 層級,問題的框架是運維而非架構設計。SAA-C03 問「架構師應該使用哪個 AWS 服務集中管理應用程式日誌?」SOA-C02 問「50 台 EC2 instances 的日誌沒有出現在預期的 log group 裡——SysOps 工程師按什麼順序執行哪些診斷步驟?」答案幾乎從來不是「換一個服務」,而是 CloudWatch agent IAM role、agent config 檔案路徑、logs:CreateLogStream 權限、logs.region.amazonaws.com 的 VPC endpoint,或者 multiline log group regex。CloudWatch Logs 是所有後續運維故事的插槽:CloudTrail 轉發到 CloudWatch Logs(Domain 1.1)、Lambda function logs 落在 /aws/lambda/<name>(Domain 3)、VPC Flow Logs 寫入 log group(Domain 5.3)、AWS WAF web ACL logs 送到 Firehose 再選擇性地進入 CloudWatch Logs,以及 AWS Config 設定項目傳遞到 log group 作為一個傳遞管道選項。

  • Log event:擷取到 CloudWatch Logs 的單一記錄——一個 timestamp 加上最多 256 KB 的 UTF-8 訊息。一個 log event 就是應用程式呼叫 logger.info(...) 所產生的內容。
  • Log stream:來自單一來源的有序、僅可附加的 log events 序列——通常每台 EC2 instance、每個 Lambda 執行容器、每個 ECS task,或每個用於 Flow Logs 的 VPC ENI 對應一個 log stream。
  • Log group:共享 retention policy、KMS 加密設定、metric filters、subscription filters 和存取控制的 log streams 容器。Log groups 是運維管理的基本單位。
  • Retention policy:log events 保留多久。值從 1 天到 10 年,另有 Never Expire(預設——SOA-C02 上最常考的陷阱)。
  • Metric filter:附加在 log group 上的模式定義,從符合的 log events 中萃取數值或計數,並發布成可設 alarm 的 CloudWatch metric。
  • Subscription filter:將符合的 log events 即時串流到 Kinesis Data Streams、Kinesis Data Firehose、Lambda 或另一個 log group(透過 destination 支援跨帳號)的模式定義。
  • Logs Insights:CloudWatch log groups 的互動式、專用查詢語言,含 fieldsfilterstatsparsesortlimitdedupdisplay 指令。單一查詢最多 50 個 log groups,預設時間範圍 24 小時。
  • Embedded Metric Format (EMF):一種 log events 的 JSON schema,讓 agent / Lambda 可以在單次寫入中同時發出日誌和 metrics。
  • Log group resource policy:直接附加在 log group 上的 IAM 式 policy,允許跨帳號寫入(VPC Flow Logs、Route 53 query logging、CloudFront 等均使用此機制)。
  • 參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatchLogsConcepts.html

白話文解釋 CloudWatch Logs and Logs Insights

CloudWatch Logs 的術語堆疊很快。三個類比能讓概念在看到任何 AWS console 畫面之前就先落地。

類比一:圖書館的運維證據室

CloudWatch Logs 是一座圖書館式運維證據室Log groups 是依主題排列的書架——一個給 web 層(/var/log/nginx/access.log)、一個給應用程式(/aws/lambda/checkout)、一個給 VPC Flow Logs、一個給 CloudTrail。Log streams 是每個書架上的個別書冊,每位「作者」一本——每台 EC2 instance 一本、每個 Lambda 執行環境一本、每個 ECS task 一本。Log events 是每本書裡的個別句子——只可附加、永不修改。Retention policy圖書館的淘汰規則:這個書架保留 30 天、那個書架保留 7 年、珍藏區(Never Expire)永久保存,而儲存費用會持續複利累積。Metric filters館員貼在書架上的劃記表——每次書裡出現「ERROR」這個字,館員就在表上加一筆;這張表本身是一個可以繪圖和設 alarm 的數字。Subscription filters預設好的影印機,會在有符合條件的頁面寫入時立刻影印一份,傳真到 SIEM 或 Lambda 進行即時分析。Logs Insights研究室的查詢終端機,SysOps 偵探在上面輸入 fields @timestamp, @message | filter @message like /ERROR/ | stats count() by bin(5m),幾秒內就拿到一張圖表。

類比二:便利商店的訂單紙條

想像一家全台灣隨處可見的便利商店,每一張收據就是一個 log event。收銀機(Lambda runtime)在店員結帳時印出一張新紙條——這就是 CreateLogStream 呼叫。今晚所有紙條疊在一起構成一個晚間值班紀錄(log stream)。所有「週五 18:00–22:00 值班」紙條的資料夾是一個 log group。店長想計算有多少張紙條含有「加熱」——這是一個 metric filter,模式為 "加熱",metric 名稱為 HeatedFoodCount。老闆想讓每張「VIP 會員」紙條立刻被複印一份送到管理員桌上——這是一個 subscription filter,將符合事件路由到 Lambda function(管理員)。打烊後,紙條被**歸檔到資料夾(S3 匯出)**供稅務記錄使用,收銀機明天繼續印新紙條。圖書館和便利商店兩個類比都強調同一件事:log group 是政策的單位(retention、加密、誰能讀、哪個模式計數),log stream 只是其中的一個到達通道。

類比三:郵局加全文搜尋索引

把 CloudWatch Logs 想成郵局加全文搜尋索引。每封信(log event)在郵局(擷取端點)被蓋上 timestamp,投入信箱(log stream)並標記到你的帳號。信箱被分組到大樓(log groups),共享一個租約期限(retention policy)和保全(KMS key)。郵局的自動轉寄服務(subscription filter)會影印任何提到關鍵字的信,並重新路由到合作地址(Firehose → S3、Lambda、OpenSearch)。Logs Insights 是郵政局長的全文搜尋,能回傳「過去 24 小時內,這 12 棟大樓中所有含有『connection refused』的信,依寄件人分組、依頻率排序」。SOA-C02 考生的結論:問題描述「即時轉發符合的 log events」→ subscription filter;描述「在歷史日誌中跨多個 group 尋找模式」→ Logs Insights;描述「某模式出現 N 次就 alarm」→ metric filter 加 CloudWatch alarm。

對 SOA-C02 的 alarm-from-logs 題型,便利商店劃記表(metric filter)和預設影印機(subscription filter)是你必須分清楚的兩個概念。Metric filter 產生一個數字,讓你事後設 alarm。Subscription filter 產生一個符合事件的串流,讓你即時反應。考題常常把兩者都列為合理選項;目標是「計數並 alarm」→ metric filter;目標是「處理或轉發每一個符合項目」→ subscription filter。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html

CloudWatch Logs 架構:Log Groups、Log Streams、Retention 與 KMS 加密

在任何查詢或 alarm 之前,你需要精確的心智模型,了解一個 log event 如何到達 CloudWatch Logs 以及它存放在哪裡。

三層資料模型

  • Log event — 單一 timestamp + message 記錄。最大 message 大小 256 KB,最大 batch 大小 1 MB,最大 batch event 數量 10,000。時間超過 14 天以前或超過未來 2 小時的 events 會被拒絕。
  • Log stream — 來自單一來源的 log events 序列。Streams 是僅可附加且不可變的。命名是慣例式的:EC2 instance ID、Lambda 執行環境、ECS task ARN、Flow Logs 的 ENI ID。
  • Log group — 政策單位。一個 log group 可以持有幾乎無限數量的 streams(軟配額通常為 100 萬),retention、KMS、metric filters、subscription filters 和 resource policies 都附加在這一層。

Retention policies — 最常被考的預設值

無論透過任何路徑建立 log group,只要沒有明確設定 retention——大多數 CLI 呼叫、大多數 SDK 呼叫、Lambda 自動建立、VPC Flow Logs 自動建立——retention 預設為 Never Expire。CloudWatch Logs 儲存按每 GB 每月計費,無期限累積,一個被遺忘的詳細 log group 可能默默讓帳單膨脹數年。

支援的 retention 值:1、3、5、7、14、30、60、90、120、150、180、365、400、545、731、1827、3653 天,或 Never Expire。SysOps 工程師應在建立時明確設定 retention,或透過 aws logs put-retention-policy --log-group-name <name> --retention-in-days <N> 補救。AWS Config 有受管規則 cw-loggroup-retention-period-check 可標記超過設定最大 retention 的 log groups;搭配 EventBridge → SSM Automation 可進行自動補救。

KMS 靜態加密

Log groups 預設以 AWS 管理金鑰進行靜態加密。若有合規需求,可在建立時(KmsKeyId 參數)或對現有 group 使用 associate-kms-key客戶自管 KMS key 關聯到 log group。KMS key policy 必須授予 CloudWatch Logs 服務主體(logs.<region>.amazonaws.com)標準的 kms:Encryptkms:Decryptkms:ReEncrypt*kms:GenerateDataKey*kms:DescribeKey 動作,並以 kms:EncryptionContext:aws:logs:arn condition 限定 log group ARN。常見的 SOA-C02 陷阱:考生建立了 key 卻忘記加 kms:EncryptionContext condition,導致 agent 靜默地無法發布。

解除 KMS key 關聯

一旦 CMK 與 log group 關聯,後續所有 log events 都會以此 key 加密。現有 log events 仍然以寫入時使用的 key 加密。解除 key 關聯(disassociate-kms-key)會阻止後續以 CMK 加密,並恢復使用 AWS 管理金鑰——但歷史 events 仍綁定 CMK,若 CMK 被停用或刪除則無法讀取。請妥善規劃 key 輪換和生命週期。

  • Log group 預設 retentionNever Expire(SOA-C02 的陷阱預設值)。
  • 最大 log event 大小:每個 message 256 KB
  • 最大 log batch 大小:每次 PutLogEvents 呼叫 1 MB 或 10,000 events。
  • Log event 擷取時間視窗:接受過去 14 天到未來 2 小時內的 events;超出此範圍則被拒絕。
  • Logs Insights 時間範圍:預設 24 小時;查詢可掃描到 retention 期限,但成本和時間隨掃描位元組數線性增加。
  • Logs Insights 每查詢 log groups 數量:單一查詢最多 50 個 log groups
  • Logs Insights 查詢逾時:每次查詢最長執行 15 分鐘
  • Logs Insights 回傳 events 數量:每次查詢結果最多 10,000 列
  • Subscription filter 目標:Kinesis Data Streams、Kinesis Data Firehose、Lambda、透過 destination 連到另一個 log group——每個 log group 最多 兩個 subscription filters
  • Metric filter 上限:每個 log group 100 個 metric filters
  • Retention 值:1、3、5、7、14、30、60、90、120、150、180、365、400、545、731、1827、3653 天,或 Never Expire。
  • 參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch-logs-quotas.html

Metric Filters:從日誌文字模式萃取數值 Metrics

Metric filter 是將非結構化日誌文字橋接到可設 alarm 的結構化 CloudWatch metric 的橋樑。它是 SOA-C02 考試中產值最高的功能之一。

Metric filter 的運作方式

你用三項設定將 metric filter 附加到 log group:

  1. Filter pattern — 要比對什麼。CloudWatch Logs 支援兩種模式語法:傳統詞語和引號片語("ERROR" "timeout"),以及用於結構化 JSON log events 的 JSON pattern matching({$.statusCode = 500})。
  2. Metric transformation — 要發布什麼。Metric 名稱(例如 ApplicationErrorCount)、metric namespace(例如 MyApp/Prod)、值(計數式 filter 通常為 1,或 $.latency 用來萃取數值欄位)、當某個 period 內沒有 event 符合時的選用預設值,以及從 log JSON 萃取的選用 dimensions。
  3. 選用 unit — metric 單位(Count、Bytes、Milliseconds)。

Filter 建立後,每個新到達 log group 的 log event 都會被評估。符合的 events 會向指定 namespace 中的指定 metric 發布資料點。接著你可以在這個 metric 上建立 CloudWatch alarm,就像對待任何其他 metric 一樣。

常見 metric filter 模式

  • 計算錯誤日誌行數:模式 ?ERROR ?Error ?error,值 1,metric ErrorLogCount。設定 alarm 在每 5 分鐘 sum > 100 時觸發。
  • 計算失敗 SSH 嘗試次數:模式 [..., status="Failed", user, ...],值 1,metric FailedSSHAttempts。搭配 composite alarm 進行暴力破解偵測。
  • 從 JSON access log 萃取 HTTP 延遲:模式 {$.method = "GET" && $.latency > 0},值 $.latency,metric GetLatencyMs(Milliseconds unit)。對 p99 設 alarm。
  • 計算 CloudFront 5xx 錯誤:模式 {$.responseStatus >= 500 && $.responseStatus < 600},值 1,metric EdgeServerErrors
  • 萃取 dimensional metric:使用 JSON 模式,可萃取 $.region$.tenantId 作為 dimensions,讓一個 filter 發布每個 region 每個 tenant 的時間序列——對多租戶 SaaS 可觀測性很有用。

模式語法 — 傳統模式 vs JSON 模式

傳統模式針對 log event 的原始文字進行比對。Token 以空格分隔;引號標記字面片語;? 是邏輯 OR;- 是排除;[...] 以位置比對空格分隔的欄位,支援選用名稱和條件。

JSON 模式針對解析為 JSON 的 log event 進行比對。模式是 $.field 路徑的 Boolean 表達式,支援運算子 =!=><>=<=,以及 Boolean &&||。JSON 模式對結構化日誌遠比傳統模式可靠,因為不受相鄰文字或空白字元影響。

SOA-C02 上關於 metric filter 最常被考的陷阱:metric filter 只向前生效。它評估日誌到達 log group 後的新 log events。在 filter 建立之前已寫入的 log events 不會被回溯掃描,metric 也永遠不會得到歷史資料點。若要分析歷史模式,請改對現有 log group 執行 Logs Insights query。若要根據歷史基準設 alarm,需先建立 filter,等待足夠的新資料到來,再建立 alarm——或使用 Logs Insights 進行單次歷史分析。回答「建立 metric filter 並對昨天的資料設 alarm」的考生會失分。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html

Metric filter vs subscription filter vs Logs Insights

這是 SOA-C02 最標準的判斷題,後面的決策矩陣會再次回顧。簡短答案:

  • Metric filter:目標是「計數並 alarm」。
  • Subscription filter:目標是「即時對每個符合項目做出反應」。
  • Logs Insights:目標是「臨時分析或歷史調查」。

CloudWatch Logs Insights:運維疑難排解的查詢語法

CloudWatch Logs Insights 是專為臨時日誌分析設計的查詢語言。Metric filters 和 subscription filters 是向前生效且模式驅動的;Logs Insights 則是互動式、回溯式且分析性的——SysOps 偵探在事故中最愛用的工具。

查詢結構

Logs Insights query 是以 | 分隔的指令 pipeline。完整語法:

  • fields — 選擇要回傳的欄位;支援內建欄位(@timestamp@message@logStream@log)以及任何 JSON 路徑或萃取欄位。
  • filter — 以 Boolean 表達式篩選列;支援 =!=<>like /regex/in [...]andornot
  • parse — 使用 glob 式模式(* request_id=* status=*)或 regex(@message /(?<ip>\\d+\\.\\d+\\.\\d+\\.\\d+)/)將子字串萃取為具名變數。
  • stats — 彙整(count()sum()avg()min()max()pct(latency, 99)count_distinct(userId)),可選用 by 欄位或 by bin(5m) 分組。
  • sort — 依欄位排序,可用 ascdesc
  • limit — 限制結果列數(預設和最大值均為 10,000)。
  • dedup — 依欄位組合去除重複列。
  • display — 最終欄位投影。

內建欄位

Logs Insights 中每個 log event 無需設定即可存取以下隱含欄位:

  • @timestamp — event timestamp。
  • @message — 原始 event message。
  • @logStream — log stream 名稱。
  • @log — log group 識別碼(帳號 ID + log group 名稱)。
  • @ingestionTime — CloudWatch Logs 收到 event 的時間。
  • @type — event 類型(Lambda logs 為 'Lambda',CloudTrail 為 'CloudTrail')。對於 JSON 編碼的 log events,頂層 JSON 欄位會自動萃取為具名欄位,無需使用 parse

多 log group 查詢

單一 Logs Insights query 最多可掃描 50 個 log groups。這是「在過去 24 小時內,找出整個微服務群中所有 API 錯誤」的答案——在 console 中選取所有 50 個微服務 log groups,輸入一個 query,檢視結果。

儲存查詢與 dashboards

Insights queries 可以儲存在資料夾階層下,由任何團隊成員重新執行。查詢結果也可以嵌入 CloudWatch dashboard 作為 Logs widget,自動刷新。儲存的查詢是 SysOps 運維手冊的一部分,應進行版本控管(透過 API 匯出 JSON,存放在 Git 中)。

定價模型

Logs Insights 按每次查詢掃描的 GB 資料計費,與回傳多少列無關。縮短時間範圍、縮小 log groups 範圍,以及使用索引化篩選(@logStream 成員判斷、精確 = 比對)都能減少掃描位元組數和費用。SOA-C02 有時會問「如何降低 Logs Insights 費用」——答案是「縮短時間範圍並縮小 log group 集合」,而不是「換一個服務」。

記住這五個查詢的運維結構——它們的變體會出現在情境題和實際生產工作中:

  1. 前 N 個錯誤訊息依計數排序fields @timestamp, @message | filter @message like /ERROR/ | stats count() as cnt by @message | sort cnt desc | limit 10
  2. 依分鐘計數(時間軸)filter @message like /5xx/ | stats count() by bin(1m) 用於繪製隨時間變化的錯誤率。
  3. 從 JSON access log 計算百分位數filter ispresent(latency) | stats pct(latency, 99) by bin(5m) 用於追蹤 p99 延遲。
  4. 依來源 IP 分組用於資安parse @message /(?<ip>\\d+\\.\\d+\\.\\d+\\.\\d+)/ | filter @message like /Failed password/ | stats count() by ip | sort count() desc
  5. Lambda timeout 調查filter @type = "REPORT" | stats max(@duration), avg(@duration), pct(@duration, 99) by bin(5m)/aws/lambda/<name> log group 執行。 參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-examples.html

常用 Logs Insights 查詢:運維手冊配方

除了語法之外,SysOps 工程師還帶著一本標準查詢手冊。每個查詢都對應 Domain 1.1 的一個真實場景。

前 10 個錯誤訊息

fields @timestamp, @message
| filter @message like /ERROR/ or @message like /Exception/
| stats count() as occurrences by @message
| sort occurrences desc
| limit 10

這是任何事故發生時執行的第一個查詢。對受影響 stack 中的所有微服務 log groups 執行,以找出主要錯誤。

ALB access logs 的 p99 延遲(啟用 ALB access logging 到 log group 後)

filter @logStream like /ALB/
| parse @message /target_processing_time=(?<tpt>\\S+)/
| filter ispresent(tpt) and tpt != "-1"
| stats pct(tpt, 99) as p99_seconds, pct(tpt, 50) as p50_seconds by bin(5m)
| sort @timestamp asc

依來源 IP 統計失敗 SSH 嘗試次數(由 agent 收集的 Linux /var/log/secure

filter @message like /Failed password/
| parse @message /from (?<src_ip>\\S+) port/
| stats count() as attempts by src_ip
| sort attempts desc
| limit 20

Lambda cold-start 頻率

filter @type = "REPORT"
| filter @message like /Init Duration/
| stats count() as cold_starts by bin(5m)

CloudTrail 未授權 API 呼叫(CloudTrail 轉發到 log group 後)

filter errorCode = "AccessDenied" or errorCode = "UnauthorizedOperation"
| stats count() as denied_calls by userIdentity.arn, eventName
| sort denied_calls desc
| limit 20

VPC Flow Logs 被拒絕的流量

filter action = "REJECT"
| stats count() as rejects by srcAddr, dstAddr, dstPort
| sort rejects desc
| limit 50

這六個查詢涵蓋大約 80% 的運維調查。將它們儲存在 Logs Insights console 的「SysOps 手冊」資料夾中並多加練習——考試預設考生熟悉語法結構。

CloudWatch Agent 日誌收集:Config 檔案與 Multiline 處理

統一版 CloudWatch agent 從 Linux 和 Windows 主機收集日誌檔案並傳送到 log groups。SOA-C02 上最常見的「日誌遺失」疑難排解場景往往是 agent 設定問題,因此這些細節非常重要。

Agent config 檔案結構

Agent 從 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json(Linux)或 C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent.json(Windows)讀取 JSON config,也可從 SSM Parameter Store 取得。logs 區段如下:

{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/nginx/access.log",
            "log_group_name": "/myapp/nginx-access",
            "log_stream_name": "{instance_id}",
            "timestamp_format": "%d/%b/%Y:%H:%M:%S %z",
            "multi_line_start_pattern": "{timestamp_format}",
            "retention_in_days": 30
          }
        ]
      }
    }
  }
}

log_stream_name 的 token

log_stream_name 中,agent 支援以下 token:

  • {instance_id} — EC2 instance ID。最常用。
  • {hostname} — OS hostname。
  • {ip_address} — 主要 IP。
  • {local_hostname} — 短 hostname。
  • {date}YYYY-MM-DD

使用 {instance_id} 是 SOA-C02 的慣例,因為它能讓 log streams 直接追溯回來源 EC2 資源。

Multiline 日誌分組

應用程式日誌(Java stack traces、Python tracebacks)天生就是多行的——一個邏輯事件跨越許多行。Agent 使用 multi_line_start_pattern 分組多行 events,這個 regex 比對每個 event 的第一行。不符合的行會附加到前一個 event。簡寫 "multi_line_start_pattern": "{timestamp_format}" 會自動重用 timestamp regex。若沒有這個設定,每一行都會成為獨立的 event,stack traces 就會在 CloudWatch Logs 中碎裂成幾百個無法搜尋的列。

自動建立 log groups 與 retention

Agent 可以自動建立 log group(需要 logs:CreateLogGroup 權限),並透過 retention_in_days 設定 retention。若省略 retention,log group 會繼承 Never Expire 預設值——直接掉入 SOA-C02 最常考的費用陷阱。

Agent 權限

Agent 需要 logs:CreateLogGrouplogs:CreateLogStreamlogs:PutLogEventslogs:DescribeLogStreamslogs:DescribeLogGroups,若同時推送 metrics 則還需要 cloudwatch:PutMetricData。受管 policy CloudWatchAgentServerPolicy 包含所有這些權限。Instance profile 必須包含此 policy 或同等的自訂 policy。

::warning

當 CloudWatch agent config 中省略 retention_in_days 時,agent 自動建立的 log groups 預設為 Never Expire,會無限期累積儲存費用。Lambda(/aws/lambda/<name>)、VPC Flow Logs 以及任何呼叫 CreateLogGroup 而未指定 retention 的服務,都有同樣的問題。定期使用 AWS Config 受管規則 cw-loggroup-retention-period-check 稽核你的帳號,或用一行 CLI 指令:aws logs describe-log-groups --query "logGroups[?retentionInDays==null].logGroupName"。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SettingLogRetention.html ::

Log Subscription Filters:即時串流到 Lambda、Firehose 和 OpenSearch

Metric filter 計算符合次數;subscription filter 則即時將符合項目路由到下游消費者。SOA-C02 同時考兩者——知道各自的適用場景是必備技能。

Subscription filter 機制

Subscription filter 用三項設定附加到 log group:

  1. Filter pattern — 與 metric filter 模式相同的語法(傳統或 JSON)。
  2. Destination ARN — 符合 events 的目標。
  3. IAM role — CloudWatch Logs 假設此 role 來向目標寫入(必須信任 logs.<region>.amazonaws.com)。

每個符合模式的 log event 幾乎即時(通常不到一秒)傳遞到目標。CloudWatch Logs 在傳遞前會對 event 進行 base64 編碼和 gzip 壓縮;消費者必須解壓縮。

支援的目標

  • AWS Lambda — 每批次同步調用。適用於內嵌轉換、告警或簡單的 SIEM 整合。Lambda 並發限制適用;節流會反壓回 subscription。
  • Kinesis Data Streams — 高吞吐量、有序、多消費者。適用於多個下游應用程式需要獨立消費的場景。
  • Kinesis Data Firehose — 緩衝傳遞到 S3、Redshift(超出 SOA 範圍)、OpenSearch Service 或第三方 HTTP 端點。適用於封存、資料湖擷取或 OpenSearch dashboarding。
  • 另一個 CloudWatch Logs log group(透過 destination)——通常用於跨帳號彙整。

兩個 subscription filter 配額

每個 log group 最多同時支援兩個 subscription filters。若架構需要兩個以上的消費者,可透過 Kinesis Data Streams(多消費者)或透過 Lambda 轉發到多個目標來進行扇出。

常見 subscription filter 模式

  • 即時 SIEM 擷取 — subscription filter 在 /aws/cloudtrail/... log group 上,模式 {$.errorCode = "*"} → Firehose → OpenSearch Service → 資安分析師 dashboards。
  • 將應用程式錯誤串流到 Slack — subscription filter 在應用程式 log group 上,模式 ?ERROR ?FATAL → Lambda → Slack webhook。
  • 集中 VPC Flow Logs — subscription filter 在 Flow Log log group 上 → Firehose → S3 → Athena queries;或 → OpenSearch 進行即時網路分析。

費用考量

Subscription filters 按傳遞的 event 數量計費。對於詳細的 log groups(Flow Logs、debug 等級的應用程式日誌),費用可能很快超過 log group 本身的費用。務必在模式層級進行預先過濾——絕不要對一個每天 100 GB 的 log group 使用萬用字元 subscription,除非下游真的有必要。

SOA-C02 常考「SysOps 團隊設了 subscription filter 將所有 log events 轉發到 OpenSearch,帳單暴增——怎麼辦?」答案是收緊 filter 模式使只有相關 events 轉發,以及/或將永久開啟的 subscription 替換為 Firehose 封存路徑(緩衝和批次處理)。對高流量 log group 使用萬用字元 subscription 是反模式。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html

匯出日誌到 S3:一次性匯出任務 vs 透過 Firehose 持續匯出

長期保留(數年)和在 CloudWatch Logs 之外的分析需要匯出到 S3。存在兩種運維路徑;SOA-C02 考核何時使用各自的路徑。

路徑一 — 一次性匯出任務

CreateExportTask API 啟動一次性、同步的匯出作業,將 log group 中指定時間範圍的 log events 匯出到 S3 前綴。此任務是批次、非即時的,依量可能需要數分鐘到數小時。每個帳號每個 region 一次只能執行一個匯出任務。任務建立物件階層 s3://bucket/prefix/<exportTaskId>/... 並寫入 gzip 壓縮的 JSON 檔案。

適用時機:

  • 合規封存,在降低 log group retention 之前——匯出到具有更長 lifecycle 的 S3,再將 log group retention 降至 30 天。
  • 臨時鑑識匯出,用於資安事件——匯出相關時間視窗到 S3,再執行 Athena 查詢。
  • 帳號遷移——從來源帳號匯出日誌到 S3,跨帳號複製,再擷取到目標帳號。

S3 bucket 必須有 bucket policy 允許 CloudWatch Logs(logs.<region>.amazonaws.com)使用適當的 aws:SourceAccountaws:SourceArn condition 寫入物件。

路徑二 — 透過 Subscription Filter → Firehose → S3 持續匯出

對於新 log events 的持續封存,正確的架構是在 log group 上設 subscription filter 路由到以 S3 為目的地的 Kinesis Data Firehose。Firehose 緩衝 events(大小和時間觸發器)、gzip 壓縮、選用轉換為 Parquet/ORC,並即時寫入 S3。此路徑可擴展至高吞吐量 log groups,並自然整合下游分析(Athena、Glue,EMR 超出範圍但 Athena 沒問題)。

適用時機:

  • 持續 SIEM 或資料湖擷取。
  • 成本最佳化——CloudWatch Logs retention 設短(例如 7 天用於熱點除錯),透過 Firehose 將所有內容封存到具有更便宜儲存層的 S3。
  • 格式轉換——Firehose 可將 JSON 轉換為 Parquet,提升 Athena 效能。

何時不需要匯出

若唯一需求是「偶爾搜尋歷史日誌」,對現有 log group 執行 Logs Insights 比匯出到 S3 再用 Athena 更便宜且更快。只有在需要超過 CloudWatch Logs retention 的時間長度、需要欄式格式進行分析查詢,或需要分發給非 AWS 系統時,才需要匯出。

跨帳號日誌彙整:Resource Policies 與跨帳號 Subscription Filters

多帳號組織需要一個單一的資安或運維帳號,彙整所有成員帳號的日誌。CloudWatch Logs 支援兩種跨帳號模式。

模式一 — 透過 log group resource policy 進行跨帳號寫入

Log group resource policy 是直接附加在 log group 上的 IAM 式 policy。它授予其他 AWS 帳號或服務將 log events 寫入該 group 的權限。這就是 VPC Flow Logs、Route 53 query logging 和 CloudFront 即時日誌等 AWS 原生服務如何發布到集中 log group 的機制;同樣的機制也可用於你自己的資源進行跨帳號寫入。

集中 Flow Log 目標的 resource policy 範例:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AWSLogDeliveryWrite",
    "Effect": "Allow",
    "Principal": { "Service": "delivery.logs.amazonaws.com" },
    "Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
    "Resource": "arn:aws:logs:us-east-1:111122223333:log-group:central-flow-logs:*",
    "Condition": {
      "StringEquals": { "aws:SourceAccount": "111122223333" },
      "ArnLike": { "aws:SourceArn": "arn:aws:logs:us-east-1:111122223333:*" }
    }
  }]
}

Resource policies 限制為每個 region 每個帳號 10 KB——當多個來源共享一個集中 group 時,可能需要壓縮或合併 statements。

模式二 — 透過 destination 進行跨帳號 subscription filter

對於即時彙整,來源帳號建立一個指向接收帳號中 destination 的 subscription filter。Destination 是一個包裝 Kinesis Data Stream 和 IAM role 的 CloudWatch Logs 物件;其存取 policy 允許來源帳號放入記錄。

流程:

  1. 接收帳號建立 Kinesis Data Stream、具有寫入 stream 權限的 IAM role,以及引用 stream 和 role 的 CloudWatch Logs destination。Destination 有一個列出來源帳號 ID 的存取 policy。
  2. 來源帳號在其 log group 上建立以 destination ARN 為目標的 subscription filter。
  3. Events 從來源 log group 透過 CloudWatch Logs 串流到接收帳號的 Kinesis stream,消費者(Lambda、Firehose、下游分析)在此處理它們。

這是 SOA-C02 對「即時將 50 個帳號的日誌集中到單一資安帳號」的標準答案。對於批次/非即時彙整,帶有跨帳號 bucket policy 的 S3 加上各來源帳號的匯出任務(或 Firehose)更為簡單。

對於大型組織,AWS Organizations 允許 delegated administrator 模式,讓一個成員帳號獲得跨組織讀取 CloudWatch Logs 的權限。結合跨帳號 subscription filters 或集中式 S3 日誌 bucket,這是最乾淨的運維模型,也與 Control Tower 的日誌帳號模式一致。SOA-C02 偏好 AWS 原生多帳號模式,而非手工建立的跨帳號 IAM。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CrossAccountSubscriptions.html

Log Retention 與封存:從 1 天到 Never Expire

Retention 是最直接影響 CloudWatch Logs 帳單的運維決策。從三個層次來思考。

第一層 — 熱 retention(CloudWatch Logs)

這是 Logs Insights 查詢能回傳資料、metric filters 持續評估新 events 的期間。依除錯節奏選擇:

  • 1–7 天 — 短期除錯日誌、DEBUG 等級的應用程式輸出、暫時性診斷。
  • 14–30 天 — 典型的 web 層和應用程式日誌,兩週的事件調查視窗是常規。
  • 90 天 — 安全敏感日誌(CloudTrail、VPC Flow Logs),調查常常需要回溯整季。
  • 365 天以上 — 合規要求的保留;搭配匯出到 S3 Glacier 進一步降低成本。

第二層 — 溫封存(S3 Standard / S3 IA)

對於超過熱視窗的日誌,匯出到 S3 並設 lifecycle rules,30 天後轉移到 S3-IA,以降低成本。Athena 對 S3 的查詢費用為每 GB 幾分錢,非常適合合規查詢。

第三層 — 冷封存(S3 Glacier / Glacier Deep Archive)

對於法規(HIPAA、SOX、PCI)要求的長期保留,在 180 天後以 lifecycle 將物件轉移到 Glacier Deep Archive。取回需要數小時,但費用遠低於 CloudWatch Logs 一個數量級。標準 SOA 模式:CloudWatch Logs 30 天熱存、S3 IA 1–2 年溫存、之後 Glacier Deep Archive

Never Expire 的費用影響

一個每天累積 10 GB 的 log group,Never Expire 設定下一年後約有 3.6 TB,五年後約有 18 TB,全部以 CloudWatch Logs 每 GB 每月的儲存費率計費。將同一個 group 改為 30 天 retention,儲存量上限為 300 GB。明確設定 retention 的數學和運維理由都十分充分——過了熱視窗後的舊日誌幾乎沒有用處。

場景模式:應用程式日誌在 CloudWatch 中消失

SOA-C02 的標準疑難排解流程。依發生頻率排序的手冊:

  1. 確認 agent 已安裝並正在執行。 透過 SSH 或 Session Manager 連入 EC2 instance:sudo systemctl status amazon-cloudwatch-agent(Linux)或 Get-Service AmazonCloudWatchAgent(Windows)。若不存在,使用 Systems Manager Run Command 的 AWS-ConfigureAWSPackage 安裝 AmazonCloudWatchAgent
  2. 確認 agent 有日誌收集 config。 裸裝的 agent 什麼都不做。檢查 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json 中是否有 logs.logs_collected.files.collect_list 陣列。使用 amazon-cloudwatch-agent-ctl -a status 查看 agent 認為自己在做什麼。
  3. 確認檔案路徑與實際一致。 最常見的 bug:config 寫 /var/log/myapp/app.log 但應用程式寫入 /var/log/myapp/application.log。Agent 靜默地監看一個不存在的檔案。
  4. 確認 IAM 權限。 Instance profile 必須包含 CloudWatchAgentServerPolicy。缺少 logs:CreateLogStream 是 SOA-C02 的教科書式失敗模式——log group 存在、agent 在跑,但 instance 啟動時無法建立新的 stream。
  5. 確認網路路徑。 若 instance 在沒有 NAT gateway 的私有子網路中,agent 需要 logs.<region>.amazonaws.com 的 VPC endpoint(interface endpoint)——否則對 CloudWatch Logs API 的呼叫會失敗。
  6. 確認 agent 本身的日誌。 /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log 顯示發布錯誤。尋找 AccessDenied(IAM 缺口)、connection refused(網路缺口)、no such file(路徑不符)或 InvalidSequenceTokenException(罕見;會自動恢復)。
  7. 確認 log group 存在且在正確的 region。 Region 不符是常見的浪費時間原因。

實際上最常見的根本原因:缺少 logs:CreateLogStream 權限、檔案路徑不符、agent 已安裝但從未執行 start 指令、私有子網路缺少 VPC endpoint。

場景模式:SysOps 必須在 24 小時內找出 50 台 Instance 的所有 API 錯誤

Logs Insights 的教科書場景。凌晨兩點,ops 工程師被傳呼「API 在回傳錯誤」。他們需要找出哪些錯誤、在哪些 instance 上、頻率如何。

查詢:

fields @timestamp, @logStream, @message
| filter @message like /5\\d{2}/ or @message like /ERROR/ or @message like /Exception/
| stats count() as occurrences by @logStream, @message
| sort occurrences desc
| limit 100

對所有 50 個 instance log groups 執行(在 console 中多選,最多 50 個 log groups 的限制)。幾秒內,結果就會顯示哪些訊息佔主導地位,哪些 instance 正在產生這些訊息。加入 | filter @logStream = "i-0abc123" 聚焦在單一主機,或縮短時間範圍到最後一小時進行深入挖掘。

若錯誤量大到掃描費用令人擔憂,可加入早期 filter @timestamp > <epoch_ms>,或使用時間範圍選擇器縮小視窗。查詢是迭代式的——反覆精煉直到主要模式清晰,然後針對該模式建議一個 metric filter,讓未來的發生能自動觸發 alarm 而無需手動重新查詢。

常見陷阱:Metric Filters 不回溯生效

再次強調,因為它幾乎出現在每道 SOA-C02 metric filter 題目的干擾選項中。今天建立的 metric filter 對昨天擷取的 log events 沒有任何作用。Filter 評估到達 log group 的新 events;歷史 events 不會被重新掃描。

實際影響:

  • 無法對剛發生的事故進行回溯 alarm。 使用 Logs Insights 調查過去;建立 metric filter 用於向前 alarm。
  • 無法回填 metric。 若 SysOps 團隊需要過去 90 天的 metric 用於容量規劃,必須找到現有的 CloudWatch metric,或反覆執行 Logs Insights 查詢並手動彙整。
  • Filter pattern 的修改同樣只向前生效。 編輯模式會在 metric 中產生不連續性;在舊模式下評估的舊 events 仍歸屬於舊的 metric 資料點。

清晰的心智規則:metric filter = 向前,Logs Insights = 向後

常見陷阱:Subscription Filter 轉發費用

詳細 log group 上的 subscription filter 可能讓帳單成倍增加。在新增 subscription 之前:

  • 估算 event 量。 aws logs describe-log-groups 回傳 storedBytes;除以 retention 天數估算每日擷取量。
  • 估算符合量。 對擬定的 filter 模式在 24 小時視窗上執行 Logs Insights 查詢——這就是 subscription 將向下游傳遞的速率。
  • 明智選擇目標。 以每次調用計費的 Lambda 對相同資料可能比 Firehose 批次傳遞更貴。
  • 在模式層級進行預先過濾。 絕不要對一個每天 100 GB 的 log group 用萬用字元「轉發所有內容」——這種模式會使 subscription 費用和下游計算費用都爆炸。

CloudWatch Logs vs CloudTrail Logs:不同的擷取路徑

SOA-C02 的概念辨別題。CloudWatch Logs 擷取應用程式輸出、OS 日誌、agent 收集的日誌,以及任何寫入 log group 的服務(Lambda runtime、VPC Flow Logs、AWS WAF web ACL 直接整合)。CloudTrail Logs 記錄 AWS API 呼叫——什麼時候哪個資源 做了 什麼——預設傳遞到 S3,也可選擇傳遞到 CloudWatch log group。

考試的運維區分:

  • 資料來源:CloudWatch Logs 是應用程式/OS;CloudTrail 是 AWS API 平面。
  • 預設目的地:CloudWatch Logs 是 log group;CloudTrail 是 S3(以及選用的 log group)。
  • 查詢:兩者都用 Logs Insights;CloudTrail-in-S3 常用 Athena。
  • 預設 retention:CloudWatch Logs 是 Never Expire;CloudTrail S3 遵循 S3 lifecycle rules。
  • 使用場景:除錯應用程式 bug → CloudWatch Logs;識別誰更改了 IAM policy → CloudTrail。

當 CloudTrail 被轉發到 log group 時,相同的 Logs Insights 語法適用——而運維威力非常強大,因為資安團隊能用互動式查詢語言瀏覽 API 稽核歷史。

SOA-C02 vs SAA-C03:運維視角的差異

問題類型 SAA-C03 視角 SOA-C02 視角
選擇日誌服務 「哪個 AWS 服務集中管理應用程式日誌?」 「日誌沒有出現在預期的 log group 中——依序列出每個診斷步驟。」
Retention 「選擇最具成本效益的封存方式。」 「所有 log groups 都是 Never Expire 且帳單暴增——實作 retention policies 並一次性匯出到 S3。」
Metric filter 「哪個功能將日誌模式轉換為 metric?」 「Metric filter 剛建立,alarm 在 INSUFFICIENT_DATA——為什麼?(沒有歷史掃描)」
Subscription filter 「哪個功能即時轉發日誌?」 「透過 destination + Kinesis Data Stream 設定跨帳號 subscription filter。」
Logs Insights 「哪個服務能互動式查詢 CloudWatch Logs?」 「寫一個 Logs Insights query,回傳過去 24 小時內依 log stream 分組的前 10 個錯誤。」
跨帳號 「跨帳號彙整日誌。」 「接收帳號建立包裝 Kinesis stream 的 destination;來源帳號建立指向 destination ARN 的 subscription filter。」
加密 「靜態加密日誌資料。」 「關聯 CMK;在 key policy 中加入 kms:EncryptionContext:aws:logs:arn condition,否則 agent 會靜默失敗。」
Multiline 日誌 幾乎不考。 「Java stack traces 在 CloudWatch Logs 中每行顯示為獨立列——修正 agent multi_line_start_pattern。」

SAA 考生選擇服務;SOA 考生診斷遺失的日誌、撰寫 Insights query,並正確設定跨帳號 destination 模式。

考試訊號:如何識別 Domain 1.1 日誌題

SOA-C02 上 Domain 1.1 的日誌題目遵循可預期的形式。認識它們,每題的作答時間就會大幅縮短。

  • 「日誌遺失」 — 答案涉及 CloudWatch agent、IAM 權限缺口(logs:CreateLogStream 最常見)、檔案路徑不符,或私有子網路缺少 VPC endpoint。
  • 「在歷史日誌中找出某個模式」 — Logs Insights query。考題展示 query 並期望你辨識正確結構:filter + stats count() by ...
  • 「某模式出現 N 次就 alarm」 — metric filter + CloudWatch alarm。
  • 「即時轉發符合 events」 — subscription filter + Lambda / Firehose / Kinesis。
  • 「彙整多個帳號的日誌」 — 跨帳號 destination + Kinesis Data Stream,或有 resource policy 的集中 log group。
  • 「日誌儲存帳單爆炸」 — retention 預設為 Never Expire;設定明確 retention,選擇性地將舊資料匯出到 S3。
  • 「合規日誌的長期封存」 — Subscription filter → Firehose → S3 + Glacier lifecycle。
  • 「Java stack traces 在 CloudWatch Logs 中碎裂」 — agent multi_line_start_pattern 未設定。
  • 「Metric filter alarm 剛建立,從不對歷史資料觸發」 — metric filters 只向前生效。
  • 「用客戶自管 key 加密日誌資料」 — KMS CMK 關聯 + key policy 含 kms:EncryptionContext:aws:logs:arn condition。

加上 metrics/alarms 主題,Domain 1.1 共約 10–13 題。CloudWatch Logs 和 Logs Insights 通常佔其中 5 到 8 題。精通 metric filter vs subscription filter vs Logs Insights,加上 Never Expire retention 預設值,再加上 agent IAM 陷阱,幾乎能涵蓋所有這些題目。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html

決策矩陣 — Metric Filter vs Subscription Filter vs Logs Insights

SOA-C02 這個主題中最常考的決策。考試時用此表格查詢。

運維目標 正確選項 原因
某字串每分鐘出現 N 次就 alarm Metric filter + CloudWatch alarm 模式產生可 alarm 的計數 metric。
將每個符合 event 串流到 Lambda 處理 Subscription filter → Lambda 即時逐 event 傳遞。
將所有日誌串流到 OpenSearch 作 SIEM Subscription filter → Firehose → OpenSearch 緩衝、可擴展、格式靈活。
調查「過去 6 小時發生了什麼」 Logs Insights 互動式、回溯式、可查詢。
找出前 10 個錯誤訊息依計數排序 Logs Insights with stats count() by @message 內建彙整語言。
合規日誌封存 7 年 Subscription filter → Firehose → S3 + Glacier lifecycle 長期保留比 CloudWatch Logs 便宜。
匯出過去 30 天供鑑識 CreateExportTask to S3 一次性、範圍限定。
將錯誤轉發到 Slack Subscription filter → Lambda 每個 event 即時告警。
從 JSON logs 計算 p99 延遲 Logs Insights stats pct(latency, 99) by bin(5m) 或 metric filter 萃取 $.latency 後對 p99 設 alarm。
即時彙整 50 個帳號的日誌 跨帳號 subscription filter to destination + Kinesis 原生多帳號日誌串流。
跨帳號日誌寫入(集中 log group) Log group resource policy 用於 VPC Flow Logs、CloudFront 等服務。
快速搜尋 14 天以上的日誌 在 retention 內用 Logs Insights;超過後用 Athena over 匯出的 S3 Logs Insights 在 retention 內便宜;超過後用 Athena。
偵測日誌量異常 Metric filter 產生 event 計數 metric + CloudWatch anomaly detection alarm 結合兩個主題。
降低詳細 log group 的 CloudWatch Logs 帳單 設 retention 為天數、匯出舊資料到 S3、將 log level 降至 WARN+ 運維成本紀律。

常見陷阱總結 — CloudWatch Logs 與 Logs Insights

每次 SOA-C02 考試都會遇到其中兩、三個干擾選項。

陷阱一:Metric filters 會掃描歷史日誌

不會。Metric filters 只向前生效;建立 filter 後,對新資料設 alarm。歷史調查請用 Logs Insights。

陷阱二:Log group 預設 retention 是合理的

不是。預設是 Never Expire。務必在建立時明確設定 retention;用 AWS Config 受管規則 cw-loggroup-retention-period-check 稽核現有 log groups。

陷阱三:Subscription filter 不考慮速率

對每天 100 GB 的 log group 使用萬用字元 subscription,會使 CloudWatch Logs 輸出、目標服務和下游計算的費用成倍增加。務必在模式層級進行預先過濾。

陷阱四:安裝 Agent 就等於日誌已發布

Agent 在沒有引用正確日誌檔案和正確 log group/stream 名稱的 config 檔案時什麼都不做。用 amazon-cloudwatch-agent-ctl -a status 確認,並在 /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log 檢查 agent 本身的日誌。

陷阱五:logs:CreateLogStream 隱含在 logs:PutLogEvents

不包含。Agent 必須明確持有 logs:CreateLogStream 才能在首次發布時建立 stream。使用 CloudWatchAgentServerPolicy 而非手動組合——這是 SOA 認可的答案。

陷阱六:Logs Insights 對任意數量 log groups 免費查詢

費用與掃描位元組數線性增加。對 50 個詳細 log groups 查詢 7 天可能產生相當可觀的費用。縮短時間範圍並縮小 log group 集合。

陷阱七:Multiline 應用程式日誌以單一 events 發布

若未設定 multi_line_start_pattern,stack trace 的每一行都成為獨立的 log event,整個 trace 變得無法搜尋。修正方式在 agent config 中,而非 Logs Insights。

陷阱八:KMS 加密「自然運作」

Key policy 必須明確信任 logs.<region>.amazonaws.com 並以 kms:EncryptionContext:aws:logs:arn condition 加以限制。若沒有該 policy,agent 無法發布,log group 顯示為空。

陷阱九:Subscription filter 配額無限

每個 log group 最多同時支援兩個 subscription filters。需要更多消費者時,使用 Kinesis Data Streams 作為多消費者扇出點。

陷阱十:一次性 S3 匯出涵蓋持續封存

CreateExportTask 是一次性的。持續封存請使用 subscription filter → Firehose → S3 pipeline。兩者結合同樣有效:Firehose 用於新 events,加上一次性匯出用於回填視窗。

FAQ — CloudWatch Logs 與 Logs Insights

Q1:為什麼我基於全新 metric filter 的 CloudWatch Logs alarm 一直停在 INSUFFICIENT_DATA?

兩個相互疊加的原因。第一,metric filters 只向前生效——filter 不會回溯掃描 filter 建立前已寫入的 log events,因此 metric 沒有歷史資料點。第二,metric 只在符合的 events 到達時才發出——對於低頻率模式(某特定錯誤類型),在 alarm 的評估視窗內可能確實還沒有資料點。解決方式有兩個:等待新 events 到來,並將 alarm 的 treatMissingData 設為 notBreaching(診斷 alarm)或 breaching(缺少即代表失敗的 alarm)。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/MonitoringLogData.html

Q2:集中多個 AWS 帳號日誌的最乾淨模式是什麼?

對於即時彙整,使用透過 destination 的跨帳號 subscription filter 模式:接收帳號建立 Kinesis Data Stream 和具有存取 policy(列出來源帳號 ID)的 CloudWatch Logs destination;每個來源帳號在其 log groups 上建立指向 destination ARN 的 subscription filter。Events 即時串流到接收帳號的 Kinesis stream,Lambda 或 Firehose 消費者在此處理。對於批次/非即時,替代方案是從每個帳號匯出到帶有跨帳號 bucket policy 的集中 S3 bucket,並用 Athena 查詢。SOA-C02 偏好在問題強調即時或組織治理時使用 subscription-filter-with-destination 模式,在強調長期封存或成本時使用集中 S3 模式。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CrossAccountSubscriptions.html

Q3:Subscription filter 和 metric filter 有什麼差別?

Metric filter 評估每個進來的 log event 是否符合模式;符合時,向指定 CloudWatch metric 發布數值資料點。下游消費者是 CloudWatch metrics 和 alarmsSubscription filter 評估每個進來的 log event 是否符合模式;符合時,將整個 event 串流到即時消費者(Lambda、Kinesis Data Streams、Kinesis Data Firehose)。下游消費者是串流 pipeline。Metric filters 回答「每個 period 發生 X 事件 N 次時 alarm」;subscription filters 回答「即時對每個 X event 做出反應」。兩者使用相同的模式語法;兩者都只向前生效;兩者都有每 log group 配額(100 個 metric filters、2 個 subscription filters)。SOA-C02 上,metric filter 的關鍵字是「alarm when…」,subscription filter 的關鍵字是「forward each…to Lambda/SIEM/OpenSearch」。

Q4:如何寫一個 Logs Insights query 回傳前 N 個錯誤及其 stack traces?

分兩階段建立 query。第一階段依計數找出前 N 個錯誤訊息模式;第二階段為每個模式拉取代表性 event。第一個 query:filter @message like /ERROR/ or @message like /Exception/ | stats count() as cnt by @message | sort cnt desc | limit 10。得到前幾個訊息後,複製其中一個並執行後續 query:fields @timestamp, @logStream, @message | filter @message = "<exact message>" | sort @timestamp desc | limit 5。第二個 query 回傳最近的完整發生記錄,包括 multiline stack trace(前提是 agent 的 multi_line_start_pattern 已正確設定,使 stack trace 被擷取為單一 event)。若 stack traces 在多個 @message 列中碎裂,agent config 是根本原因——修正 multiline 模式後重新擷取。

Q5:如何在整個帳號中避免 Never Expire retention 陷阱?

三種策略組合。第一,在建立每個 log group 時明確設定 retention——在 CloudFormation 設定 RetentionInDays;在 CLI 將 create-log-groupput-retention-policy 配對;在 CloudWatch agent config 使用 retention_in_days。第二,啟用 AWS Config 受管規則 cw-loggroup-retention-period-check,設定最大允許 retention;該規則會標記超過閾值的任何 log group。第三,將 AWS Config 不合規事件串接到 SSM Automation runbook,自動呼叫 put-retention-policy 進行補救。三者組合產生一個自我修復的帳號,不會有任何 log group 無限累積。對現有帳號的一次性清理,用 aws logs describe-log-groups --query "logGroups[?retentionInDays==null].logGroupName" 列出不合規的 groups,並對每個批次設定 retention。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SettingLogRetention.html

Q6:什麼時候應該用 Logs Insights,什麼時候應該匯出到 S3 後用 Athena?

當資料在 CloudWatch Logs retention 範圍內(且該 retention 適合你的調查期限)、查詢是探索性和迭代式的、且結果時效重要時,使用 Logs Insights。Logs Insights 是互動式的,幾秒內回傳,支援完整查詢語言和自動完成。當資料超過 CloudWatch Logs retention、查詢是重複性的(每日合規報告)、資料因欄式格式(透過 Firehose 轉換的 Parquet)能降低分析成本、或消費者是非 AWS BI 工具時,使用 Athena over S3。費用交叉點出現在高資料量和長保留期——每天數百 GB 持續數年,Athena over Glacier 層 S3 的費用遠低於具有 Logs Insights 熱存的 CloudWatch Logs。SOA-C02 通常從調查期限框架問題:熱點除錯視窗 → Logs Insights;長期合規 → Athena。

Q7:為什麼我的 CloudWatch agent 即使在執行中也無法推送日誌?

依可能性排序:(1)IAM instance profile 缺少 logs:CreateLogStreamlogs:PutLogEvents——附加 CloudWatchAgentServerPolicy 解決;(2)agent config 引用的檔案路徑與應用程式寫入的位置不符——對齊路徑並用 amazon-cloudwatch-agent-ctl -a fetch-config 重新載入 config;(3)instance 在沒有網路路徑且沒有 logs.<region>.amazonaws.com VPC interface endpoint 的私有子網路中——新增 interface endpoint 並設定適當的 security group;(4)customer-managed KMS key 與 log group 關聯,但 key policy 缺少 CloudWatch Logs 服務主體授權或 kms:EncryptionContext:aws:logs:arn condition——在 key policy 中修正;(5)agent 本身在 /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log 顯示確切錯誤——疑難排解前務必先查看此檔案,不要猜測。

Q8:單一 Logs Insights query 可以跨多個 AWS 帳號嗎?

可以,但需要設定。CloudWatch cross-account observability 允許監控帳號跨連結的來源帳號查詢 metrics、logs 和 traces。一旦連結(在 CloudWatch console 的「Settings → Monitoring account configuration」一鍵設定),監控帳號中的 Logs Insights 就會在選取器中顯示來源帳號的 log groups;你可以在任意組合的連結來源帳號中選取最多 50 個。這取代了舊有的先將日誌複製到集中帳號再查詢的模式。SOA-C02 有時為「跨組織整合運維查詢」場景指出此功能。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html

Q9:如何設定 CloudTrail 將資料流到 CloudWatch log group 以進行 Logs Insights 查詢?

在 CloudTrail console 中,編輯 trail 的設定並啟用 CloudWatch Logs 傳遞;CloudTrail 會要求 log group 名稱(若不存在則建立)以及可假設的 IAM role 用於寫入 events。Trail 開始轉發後,每個管理 event(若啟用則包含 data events)都以 JSON log event 形式落在該 log group。從此,所有 Logs Insights 慣用語都適用:filter errorCode = "AccessDenied" | stats count() by userIdentity.arn, eventName | sort count() desc 可找出被拒絕最多的 API 呼叫(依 principal 分組)。這將 CloudTrail 的稽核角色與 Logs Insights 的互動式查詢結合,是 SOA-C02 偏好的資安調查模式。

Q10:當 log group 需要超過配額的 subscription filters 時怎麼辦?

CloudWatch Logs 將每個 log group 限制為兩個 subscription filters。當架構確實需要更多下游消費者——例如即時 dashboard 用 OpenSearch、封存用 S3、Slack 告警用 Lambda,以及資安團隊用 Splunk——SOA 模式是透過單一 subscription filter 到 Kinesis Data Stream 進行扇出,再將多個消費者應用程式(Lambda、Firehose、Kinesis Client Library apps)附加到 stream 上。Kinesis Data Streams 支援多個獨立消費者而不互相競爭。Subscription-filter-to-Kinesis-Data-Stream 模式也是消費者之間需要排序、以及某消費者中斷不應阻塞其他消費者時的正確答案。參考:https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html

延伸閱讀與相關運維模式

日誌收集、查詢和路由就緒後,下一個運維層是:CloudWatch Metrics、Alarms 與 Dashboards,負責相同可觀測性架構的 metric 面(建立在 metric filters 上的 alarms 在此運作);CloudTrail 與 AWS Config 提供稽核和設定合規訊號——許多訊號會轉發到相同的 log groups 供 Logs Insights 查詢;EventBridge rules 與 SNS notifications 負責將 alarms 和 events 路由到自動補救 pipelines;以及 EC2 Auto Scaling 與 ELB 高可用性,應用程式日誌就是從這個工作負載層回饋到整個 pipeline 的。

官方資料來源

更多 SOA-C02 主題