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

Cloud Logging 與 Error Reporting

3,500 字 · 約 18 分鐘閱讀 ·

掌握 Google Cloud Logging 與 Error Reporting,實現日誌的擷取、搜尋與分析,並自動歸類應用程式錯誤。

立即做 20 題練習 → 免費 · 不用註冊 · PCA

Cloud Logging 簡介 (Introduction to Cloud Logging)

在任何分散式系統中,日誌 (Logs) 都是「發生了什麼事」的基本記錄。Cloud Logging 是一項全託管服務,可讓你儲存、搜尋、分析、監控來自 Google Cloud 及其他來源的日誌數據與事件,並針對其設定警報。配合能自動歸類當機與異常狀況的 Error Reporting,它為即時疑難排解與長期稽核提供了強大的工具集。

白話文解釋 Logging and Error Reporting

類比 1 — 飛機黑盒子 (The Black Box Flight Recorder)

Cloud Logging 就像飛機上的黑盒子。它記錄了每一次按鈕的按下、每一次引擎溫度的變化以及每一次通訊。如果飛機平安降落,你可能永遠不會去看它;但如果出了問題,它就是調查人員了解事件順序的首要來源。

類比 2 — 醫療紀錄 (The Medical Record)

日誌記錄就像病人的醫療紀錄,記錄了每一次就診、每一種症狀和每一種藥物。Error Reporting 則像是急診室 (ER) 的檢傷分類系統。它發現有 50 個人帶著相同的症狀(歸類的異常 Grouped Exception)來到醫院,並提醒工作人員這可能是食物中毒爆發(應用程式 Bug),而不是 50 起無關的意外。

類比 3 — 圖書館檔案館 (The Library Archive)

日誌記錄是圖書館檔案館。每天都有成千上萬份報紙(日誌)送達。日誌路由器 (Log Router) 就像是管理員,負責決定哪些報紙留在主閱覽室(日誌值筒 Log Bucket),哪些送到地下室進行長期儲存(Coldline GCS),哪些送到研究室進行分析 (BigQuery)。

日誌接收器 (Log Sink):一種配置,指示 Cloud Logging 將特定日誌匯出到 BigQuery、Cloud Storage 或 Pub/Sub 等目的地。


日誌路由與儲存 (Log Routing and Storage)

Cloud Logging 使用「路由器 (Router)」來處理傳入的日誌:

  1. 擷取 (Ingestion): 日誌來自 GCE、GKE 或透過 API 傳入。
  2. 排除過濾器 (Exclusion Filters): 捨棄「雜訊」日誌(如成功的健康檢查)以節省成本。
  3. 接收器 (Sinks): 將日誌匯出至:
    • Cloud Storage: 用於長期、低成本的合規性儲存(保留期 Retention)。
    • BigQuery: 用於複雜的 SQL 分析和安全性數位鑑識。
    • Pub/Sub: 即時串流至外部 SIEM 或自動化補救腳本。
    • 日誌值筒 (Log Buckets): Logs Explorer 內搜尋功能的預設儲存空間。

Log Router Sinks 深入解析 — BigQuery、GCS、Pub/Sub、Splunk

Log Router 是每一筆日誌的分岔路口:每一行都會被所有啟用的 sink 規則比對一次,零個、一個或多個 sink 都可能命中。理解每種 sink 目的地,是 PCA 合規、分析、SIEM 整合題目的關鍵。

BigQuery Sink

適合需要對日誌做 SQL 分析、JOIN 或 BI 儀表板的場景。

  • 分區資料表 (Partitioned tables)(建議):每個日誌流一張分區表,依 timestamp 分區。建立 sink 時加上 --use-partitioned-tables
  • Schema 演進:jsonPayload 出現新欄位,Cloud Logging 會自動加欄;舊資料列保留原始 schema。
  • 延遲: 端到端通常 60-120 秒。

Cloud Storage Sink

適合封存、WORM 合規、或 7 年稽核保留等最低成本場景。

  • 日誌以每小時 JSON 檔案落在 gs://<bucket>/<log-id>/YYYY/MM/DD/HH/
  • 搭配 Bucket Lock + Retention Policy 來滿足 SEC/HIPAA 不可變寫入要求。
  • 用 lifecycle 規則自動轉換到 Nearline → Coldline → Archive

Pub/Sub Sink

適合即時 fan-out 到 Dataflow、Splunk、Chronicle 或第三方 SIEM。

  • 每一筆日誌變成一個 Pub/Sub 訊息;下游消費者必須處理 at-least-once 投遞。
  • 常見模式:Logs Router → Pub/Sub → Dataflow → BigQuery + Chronicle

Splunk via Pub/Sub + Dataflow Template

GCP 提供 Google 維護的 Pub/Sub-to-Splunk Dataflow 範本 (HEC),把日誌串流進 Splunk HTTP Event Collector。它處理批次、重試、與 dead-letter queue;這是把 GCP 日誌集中到既有地端 Splunk SIEM 的官方零程式碼路徑。

Sink IAM 陷阱: 每個 Log Router sink 都用一個由 Cloud Logging 自動建立的寫入者服務帳戶 (writer service account) 執行。建立 sink 之後,你必須在目的地授予該服務帳戶 roles/bigquery.dataEditorroles/storage.objectCreatorroles/pubsub.publisher;否則日誌會靜默丟失且沒有任何可見錯誤。用 gcloud logging sinks describe SINK_NAME 查出寫入者身分。


Cloud Error Reporting

Error Reporting 會自動分析日誌中的常見異常模式(例如 Java、Python 或 Go 中的堆疊追蹤 Stack Traces)。

  • 自動歸類 (Auto-Grouping): 相似的錯誤會被歸類在一起,因此你會看到「發生 50 次」,而不是 50 條獨立的日誌。
  • 警報 (Alerting): 當生產環境中出現「新類型」的錯誤時,立即獲得通知。
  • 連結至程式碼: 如果你的原始碼位於 Cloud Source Repositories 中,Error Reporting 可以將堆疊追蹤直接連結到對應的程式碼行。

日誌記錄的最佳實踐

  • 結構化日誌 (Structured Logging): 始終使用 JSON 格式記錄。這讓你可以根據特定欄位(如 jsonPayload.user_id)進行過濾,而不是進行緩慢的字串搜尋。
  • 保留策略 (Retention Policies): 為不同的日誌設定不同的保留期。稽核日誌可能需要保留 7 年,而除錯日誌可能只需要 30 天。
  • 數據遮罩 (Data Masking): 在儲存之前,使用日誌路由器脫敏或遮蓋 PII(個人身份資訊)。
::promoted

架構師洞察: 對於 PCA 考試,如果你需要對日誌數據進行「針對安全威脅的即時分析」,正確的架構是 Logs Router -> Pub/Sub -> Dataflow -> BigQuery。 ::


基於日誌的指標 (Log-Based Metrics) — Counter vs Distribution

Log-based metrics 把日誌內容轉成 Cloud Monitoring 可以畫圖、可以警報的 time-series 指標。兩種型態,成本與用途差距很大。

Counter 指標

  • 計算符合條件的日誌筆數。
  • 範例 filter:severity=ERROR AND resource.type="cloud_run_revision" → 產生 1-D 整數指標。
  • 適合 SLO error budget、「5xx 暴衝」警報、或「失敗登入次數」。

Distribution 指標

  • 從每筆日誌擷取一個數值(例如 jsonPayload.latency_ms)並產生 histogram,含 p50/p95/p99 百分位數。
  • 適合從日誌追蹤延遲 (latency) 的場景,特別是當你的應用程式無法直接吐 OpenTelemetry 指標時。

系統 vs 使用者自訂

  • 系統 log-based metrics(例如 logging.googleapis.com/byte_count)免費且預先存在。
  • 使用者自訂 log-based metrics 依照指標擷取量計費;維持 cardinality 低 — 每個 label 組合(特別像 user_id 這類高 cardinality 的 label)都會倍增成本。

Labels 與欄位擷取

你可以用正規表達式或欄位擷取器把 jsonPayload 的欄位升級成指標 label。要小心:像 request_id 這種 label 會讓每個請求都產生一條 time series,把你的帳單炸開。

Distribution 指標陷阱: PCA 題目常問「我的舊系統只會寫純文字 log,怎麼追蹤 p99 延遲?」答案是搭配 regex 擷取器的 distribution log-based metric,不是 counter metric。Counter 只能告訴你發生幾次;Distribution 才能給出數值分佈與百分位數。


保留值筒 (Retention Buckets) — 自訂 vs 預設

Cloud Logging 把日誌存在 log buckets 裡,每個專案或資料夾層級都有。每個專案會自動建立兩個 bucket:

Bucket 預設保留期 用途
_Default 30 天 所有非稽核日誌
_Required 400 天(不可變) Admin Activity + System Event 稽核日誌

自訂 Buckets

當你需要以下任一條件時,建立自己的 log bucket:

  • 自訂保留期 從 1 天到 3650 天(10 年)。
  • CMEK(客戶管理加密金鑰)— 只有使用者自建的 bucket 才能設定。
  • 區域釘選 (Regional pinning) — 為了 GDPR,把歐盟日誌存在 europe-west1

鎖定保留期 (Locked Retention)

對 bucket 套用 retention lock,設定的保留期就會變成不可變 — 任何人(包括 project owner)都不能縮短。這是 GCP 上日誌資料的 WORM 合規對應方案,SOX/PCI 場景必備。

Sink-to-Bucket 模式

用 Log Router sink 路由特定日誌流到自訂 bucket,例如:security 日誌 → 7 年鎖定 bucket;應用 debug 日誌 → 7 天便宜 bucket。這是同時滿足混合保留要求又不必匯出到 GCS 的最省錢方法。


排除過濾器與成本最佳化 (Exclusion Filters and Cost Optimization)

Cloud Logging ingestion 計費是每月每專案前 50 GiB 免費,之後 $0.50 / GiB。對於話多的 workload(GKE、load balancer、Cloud SQL 慢查詢),這項往往主宰了 observability 帳單。Exclusion filter 是主要的成本控制槓桿。

套用位置

排除過濾器掛在 sink 層級(包含隱含的 _Default sink)。被排除的日誌在計費前就被丟棄;它們不會進入任何 bucket,無法復原。

典型 Pattern

  • 丟掉成功的健康檢查:resource.type="http_load_balancer" AND httpRequest.status<400 AND httpRequest.requestUrl=~"/healthz"
  • 丟掉冗長的 GKE 控制平面日誌:resource.type="k8s_container" AND severity<WARNING AND resource.labels.container_name="istio-proxy"
  • 取樣 10% 的 INFO 日誌:severity=INFO AND sample(insertId, 0.10)(用 sample() 函式保持統計可信度)。

取樣 vs 排除

  • 排除 (Exclusion) 丟掉 100% 符合條件的日誌。
  • 取樣 (Sampling)(透過 filter 內的 sample())保留一定百分比 — 適合你還想留樣本作抽查。

成本 vs 可見性的權衡

過於激進的排除會藏住事件。永遠搭配在排除之前計算的 log-based metrics(指標會對所有 ingestion 的日誌計算,與 bucket 路由無關),這樣即使你丟掉原始日誌,仍然看得到計數。

省錢撇步: 打開 Console 的 Logs Storage 頁,依量級排序看誰是大戶。多數 GCP 專案裡,60-80% 的 ingestion 都來自 2-3 條吵雜的日誌流(LB access log、GKE system、VPC Flow)。光排除這三個通常就能砍掉一半帳單。


Error Reporting 歸類與去重 (Grouping and Deduplication)

Error Reporting 的價值在歸類 — 把 50,000 條 stack trace 變成 12 個可行動的錯誤群組。理解歸類演算法可以幫你寫出能正確歸類的可記錄錯誤。

歸類特徵 (Signature)

對每個錯誤,Error Reporting 從以下計算一組特徵:

  1. 例外型別 (例如 NullPointerExceptionValueError)。
  2. Stack trace 的頂端 frames(通常是離 throw 最近的 3-5 個 frame)。
  3. Service + versioncheckout-svcv1.2.3 錯誤與 v1.2.4 的會被分開歸類)。

原生支援的語言

Error Reporting 原生解析 Java、Python、Go、Node.js、Ruby、PHP、.NET、C# 的 stack trace。其他語言則寫一筆結構化日誌帶上 @type: "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent",Error Reporting 就會吃。

透過 API 手動回報

沒有原生支援的語言可以直接呼叫 Error Reporting API,或單純寫一條 log entry,把 ReportedErrorEvent proto 放在 jsonPayload 裡。後者是建議模式,因為它不挑 agent。

解決流程 (Resolution Workflow)

每個群組有狀態:Open → Acknowledged → Resolved → Muted。把錯誤標 Resolved 等於告訴 Error Reporting:若它再次出現,請重新警報(regression detection),所以 Resolved 有意義 — 不要批次清掉。

為什麼有時群組會意外分裂

若重新部署改動了 stack trace 的行號(例如 refactor),同一個邏輯 bug 可能產生新的群組。用 error_message filter 與 resolution timeline 視圖在心理上合併;目前沒有手動 merge 的 UI。


Cloud Logging API 與結構化日誌 jsonPayload

Cloud Logging API 透過 entries.write 接收日誌。生產等級日誌記錄最重要的單一欄位是 jsonPayload vs textPayload

textPayload vs jsonPayload

  • textPayload:單一字串。搜尋是全文掃描 — 又慢又貴。
  • jsonPayload:結構化物件。每個 key 都變成可查詢欄位:jsonPayload.user_id="u123" 已索引、查詢快速。

保留的頂層欄位

jsonPayload 裡,特定 key 會被晉升到 LogEntry 的頂層欄位:

  • severityLogEntry.severity(控制顏色 + 警報)。
  • message → 在 Logs Explorer 中顯示為摘要行。
  • traceLogEntry.trace(把日誌連結到 Cloud Trace 的 span)。
  • spanId → 啟用每個 span 的日誌篩選。
  • httpRequest → 填滿 HTTP request 面板。

Trace 關聯範例

{
  "severity": "ERROR",
  "message": "Payment timeout",
  "logging.googleapis.com/trace": "projects/my-proj/traces/abc123",
  "logging.googleapis.com/spanId": "span-456",
  "jsonPayload": {"order_id": "o-789", "vendor": "stripe", "timeout_ms": 30000}
}

這筆 entry 會在 trace abc123 的 Cloud Trace waterfall 內聯出現 — 對 debug 分散式系統非常寶貴。

Ops Agent 自動解析

GCE 上的 Ops Agent 會自動偵測 stdout/stderr 中的 JSON 並解析到 jsonPayload。在 GKE 上,Logging operator 對 container stdout 做同樣的事。在最常見的情境下,只要把 JSON 寫到 stdout,不需要任何 SDK。

Client Libraries

複雜場景(自訂 monitored resource、大型 payload)使用官方 Logging client libraries(Python 的 google-cloud-logging、Node.js 的 @google-cloud/logging)。它們會批次寫入、自動處理重試。


稽核日誌 — Admin Activity vs Data Access vs System Event

Cloud Audit Logs 是 GCP 環境中不可妥協的鑑識紀錄:誰做了什麼。稽核日誌有四種不同型別,預設與成本影響各異。

1. Admin Activity(管理活動)

  • 內容: 修改 metadata 或設定的 API 呼叫(建立 VM、改 IAM、刪除 bucket)。
  • 預設: 永遠開啟、無法停用、免費
  • 保留期:_Required bucket 保留 400 天。

2. Data Access(資料存取)

  • 內容: 讀取或寫入使用者資料的 API 呼叫(storage.objects.getbigquery.jobs.create 讀取資料表)。
  • 預設: 多數服務停用(BigQuery 例外,預設開啟讀取記錄)。
  • 成本: 按一般 Logging ingestion 計費;可能讓成本爆增 10-100 倍。
  • 粒度: 三種子類型 — ADMIN_READDATA_READDATA_WRITE。可逐服務選擇性啟用。

3. System Event(系統事件)

  • 內容: GCP 主動發起的動作(live migration、host 維護、自動 key rotation)。
  • 預設: 永遠開啟、免費
  • 用途: 把 workload 中斷與平台事件關聯起來。

4. Policy Denied(政策拒絕)

  • 內容: 紀錄請求被 VPC Service ControlsOrg PolicyIAM Conditions 拒絕的情況。
  • 預設: 永遠開啟、免費
  • 用途: Debug「為什麼這個請求被擋?」— VPC-SC perimeter 推行期間特別寶貴。

啟用 Data Access Logs

透過 gcloud organizations set-iam-policy 或 Console 在 IAM Audit Config 中逐服務啟用。PCA 題目常暗示這點:「稽核誰讀取了敏感 BigQuery 資料表」→ 為 BigQuery 啟用 DATA_READ,路由到鎖定的 bucket。

PCA 場景判斷法則: 若題目問為了合規 (SOX/HIPAA/PCI) 提供不可變、防竄改、7 年保留的「誰做了什麼」紀錄,答案是 Admin Activity + Data Access 稽核日誌 → sink 到鎖定的 log bucket(或啟用 Bucket Lock 的 GCS bucket)並設定對應保留期。永遠不要只把稽核日誌存在預設 bucket — 它 400 天的上限低於多數合規要求。


Log Analytics on BigQuery

Log Analytics 讓你直接對 Cloud Logging bucket 跑 BigQuery SQL,不需要先匯出。2023 年 GA,許多分析場景因此不必再開一個 BigQuery sink。

運作方式

  • 把一個 log bucket 升級為 Log Analytics-enabled(單向操作)。
  • 該 bucket 的日誌可透過合成的 BigQuery dataset ({project}.global._Default._AllLogs) 查詢。
  • 也可以把 bucket 連結 為 BigQuery dataset,與你自己的 BigQuery 資料表 JOIN。

能力

  • 標準 SQL,可用完整 BigQuery 函式(window function、regex、geo)。
  • Schema:每筆日誌是一列,含 timestampseverityresourcejson_payloadproto_payload
  • 查詢直接打 bucket 的底層儲存 — 沒有儲存重複,也沒有額外 ingestion 費。

成本模型

  • 分析功能本身免費;只有當你把 bucket 連結為 BigQuery dataset 時,按 BigQuery 查詢掃描量計費。
  • 在 Log Analytics UI 內的查詢,掃描 bucket 是包含的。

何時用 Log Analytics vs BigQuery Sink

需求 選擇
一次性的日誌 SQL 探索 Log Analytics
日誌與帳單 / 資產 / 外部資料表 JOIN BigQuery Sink(或 Log Analytics 加連結 dataset)
長期封存 + 儀表板 含分區的 BigQuery Sink
事故當下不必設定就能寫 SQL Log Analytics

範例查詢

SELECT
  TIMESTAMP_TRUNC(timestamp, MINUTE) AS minute,
  COUNT(*) AS errors
FROM `my-proj.global._Default._AllLogs`
WHERE severity = 'ERROR'
  AND resource.type = 'cloud_run_revision'
  AND timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
GROUP BY minute
ORDER BY minute DESC;

日誌中的敏感資料遮罩 (Sensitive Data Redaction in Logs)

應用程式日誌是 GCP 環境裡 PII 洩漏的第一來源 — 開發者不假思索就把 request body、header、DB row 記下來。三層防禦,由內而外。

1. 擷取前清洗(最佳)

在應用程式碼裡於來源端清洗。用一個 logging interceptor 在呼叫 Logging API 之前剝除 passwordssncredit_card 等欄位。這是唯一能保證敏感資料完全沒進 GCP 的方法。

2. Log Router 搭配 Cloud DLP

對於已經流經 Logs Router 的資料,走 Pub/Sub → 用 DLP Inspect 範本的 Dataflow → BigQuery/GCS。Dataflow 用 Cloud DLP 的 infoType detector(EMAIL_ADDRESS、US_SOCIAL_SECURITY_NUMBER、CREDIT_CARD_NUMBER)處理,可以遮蔽 (redact)(換成 [REDACTED])、遮罩 (mask)***-**-1234)、或代幣化 (tokenize)(格式保留加密)。

3. 對 Log Bucket 做欄位層級存取控制

即便原始 PII 不小心落入 bucket,也可以用 Logging field-level IAM + bucket views 對多數使用者只開放遮罩過的視圖,把完整 bucket 鎖在一個小型安全群組(持有 roles/logging.privateLogViewer)後面。

Data Access Logs 本身也是敏感的

諷刺的是,Data Access logs 包含被存取的資源名稱 — 有時資源名稱本身就敏感(例如 storage.objects.getgs://my-bucket/patient-12345/scan.dcm)。對稽核日誌 bucket 的保留期與存取控制,要用跟它所稽核的資料同等的嚴謹度來規劃。

應該避免的反模式

  • 記錄整個 HTTP request body(生產環境只記 header)。
  • Authorization 日誌行裡帶 JWT 或 session token。
  • 把 SQL query 參數 WHERE ssn='123-45-6789' 整段 dump — 在 log 之前先參數化。

記下四種稽核日誌: Admin Activity(永遠開啟、免費、修改設定)、Data Access(預設停用,BigQuery 例外、計費、讀寫資料)、System Event(永遠開啟、免費、GCP 發起)、Policy Denied(永遠開啟、免費、被政策擋下)。只有 Data Access 會花錢且需要明確啟用。


常見問題 — Cloud Logging (FAQ — Cloud Logging)

Q1. 「管理活動日誌 (Admin Activity)」與「數據存取日誌 (Data Access)」有什麼區別?

管理活動日誌記錄修改資源的 API 呼叫(如建立 VM),且始終免費。數據存取日誌記錄讀取或寫入數據的 API 呼叫(如讀取 GCS 物件),數據量可能非常大且昂貴;它們預設是停用的。

Q2. 我該如何降低日誌記錄成本?

使用排除過濾器捨棄不需要的日誌,並僅針對關鍵資源啟用數據存取日誌。此外,如果日誌僅用於合規性而非主動搜尋,請考慮將其路由至 Cloud Storage

Q3. Cloud Logging 可以處理來自地端伺服器的日誌嗎?

可以,透過 Ops Agent 或 Logging API。你可以將所有日誌集中在 GCP 中,實現「單一介面 (Single Pane of Glass)」視圖。

Q4. 什麼是「基於日誌的警報 (Log-based Alert)」?

這是在日誌中出現特定模式(例如單字 "CRITICAL" 或特定錯誤碼)時觸發的警報。適用於沒有數值指標的事件。

Q5. Error Reporting 如何知道一個新錯誤是「新」的?

它維護著堆疊追蹤 (Stack Trace) 的特徵碼 (Signature)。如果傳入的堆疊追蹤與任何現有特徵碼都不匹配,它就會被標記為新錯誤。

官方資料來源

更多 PCA 主題