<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cost-Governance on Tarragon</title><link>https://tarrragon.github.io/blog/tags/cost-governance/</link><description>Recent content in Cost-Governance on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 22 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/cost-governance/index.xml" rel="self" type="application/rss+xml"/><item><title>CloudWatch Logs Insights 查詢與日誌治理</title><link>https://tarrragon.github.io/blog/backend/04-observability/vendors/aws-cloudwatch/logs-insights-governance/</link><pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/04-observability/vendors/aws-cloudwatch/logs-insights-governance/</guid><description>&lt;blockquote>
&lt;p>本文是 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/aws-cloudwatch/" data-link-title="AWS CloudWatch" data-link-desc="AWS 原生觀測性服務、Logs / Metrics / Traces (X-Ray)">AWS CloudWatch&lt;/a> 的 vendor deep article，深化 overview「Logs Insights query」跟「Logs lifecycle」段。初次接觸 CloudWatch 的讀者建議先讀 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/aws-cloudwatch/" data-link-title="AWS CloudWatch" data-link-desc="AWS 原生觀測性服務、Logs / Metrics / Traces (X-Ray)">CloudWatch 服務頁&lt;/a>。&lt;/p>&lt;/blockquote>
&lt;h2 id="問題情境">問題情境&lt;/h2>
&lt;p>CloudWatch Logs 的成本模型跟 self-hosted log stack 不同 — ingestion、storage 跟 query 分開計費，每一層都有明確的 cost lever。理解 log group 設計、retention 設定與 subscription filter 的組合，才能在 AWS-native 環境下控制日誌成本而不犧牲事故判讀能力。&lt;/p>
&lt;h2 id="log-group-設計">Log group 設計&lt;/h2>
&lt;h3 id="拆分粒度">拆分粒度&lt;/h3>
&lt;p>Log group 是 CloudWatch Logs 的計費與 retention 邊界。同一個 log group 內的所有 log stream 共用 retention policy 和 access control（IAM resource policy）。&lt;/p>
&lt;p>合理的拆分粒度是 &lt;strong>一個服務一個 log group&lt;/strong>，而非一個帳號一個或一個 container 一個。服務級拆分讓 retention、查詢範圍與 IAM 權限自然對齊服務 ownership。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>拆分策略&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;th>風險&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>一個服務一個 log group&lt;/td>
 &lt;td>多數 production 服務&lt;/td>
 &lt;td>log group 數量增長需要 naming convention&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>一個環境一個 log group&lt;/td>
 &lt;td>非常小的團隊、staging/dev 環境&lt;/td>
 &lt;td>混合多個服務的日誌，查詢時需要額外 filter&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>一個 Lambda function 一個 log group&lt;/td>
 &lt;td>Lambda 預設行為&lt;/td>
 &lt;td>Lambda 數量多時 log group 爆量，管理成本高&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Lambda 的預設行為是每個 function 自動建一個 log group（&lt;code>/aws/lambda/&amp;lt;function-name&amp;gt;&lt;/code>）。function 數量超過數十個後，需要用 naming convention 加 tag 控制，否則 retention policy 難以統一套用。&lt;/p>
&lt;h3 id="naming-convention">Naming convention&lt;/h3>
&lt;p>推薦格式：&lt;code>/&amp;lt;environment&amp;gt;/&amp;lt;service&amp;gt;/&amp;lt;component&amp;gt;&lt;/code>，例如 &lt;code>/prod/checkout-api/app&lt;/code>、&lt;code>/prod/checkout-api/access-log&lt;/code>。統一前綴讓 Logs Insights 的 multi-log-group query 用 prefix matching 篩選。&lt;/p>
&lt;h2 id="logs-insights-查詢語法">Logs Insights 查詢語法&lt;/h2>
&lt;h3 id="核心語法">核心語法&lt;/h3>
&lt;p>Logs Insights 的查詢結構是 pipe-based：每行用 &lt;code>|&lt;/code> 分隔，依序處理。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">fields @timestamp, @message, @logStream
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">| filter @message like /ERROR/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">| parse @message &amp;#34;order_id=* status=*&amp;#34; as order_id, status
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">| stats count(*) as error_count by status
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">| sort error_count desc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">| limit 20&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>常用 command 對照：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Command&lt;/th>
 &lt;th>用途&lt;/th>
 &lt;th>注意事項&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>fields&lt;/code>&lt;/td>
 &lt;td>選擇要顯示的欄位&lt;/td>
 &lt;td>&lt;code>@timestamp&lt;/code>、&lt;code>@message&lt;/code> 是內建欄位&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>filter&lt;/code>&lt;/td>
 &lt;td>條件篩選&lt;/td>
 &lt;td>支援 &lt;code>like /regex/&lt;/code>、&lt;code>=&lt;/code>、&lt;code>&amp;gt;&lt;/code>、&lt;code>in []&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>parse&lt;/code>&lt;/td>
 &lt;td>從非結構化 log 擷取欄位&lt;/td>
 &lt;td>glob pattern 用 &lt;code>*&lt;/code>、regex 用 &lt;code>/pattern/&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>stats&lt;/code>&lt;/td>
 &lt;td>聚合計算&lt;/td>
 &lt;td>&lt;code>count&lt;/code>、&lt;code>avg&lt;/code>、&lt;code>sum&lt;/code>、&lt;code>min&lt;/code>、&lt;code>max&lt;/code>、&lt;code>pct&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>sort&lt;/code>&lt;/td>
 &lt;td>排序&lt;/td>
 &lt;td>預設 &lt;code>@timestamp desc&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>display&lt;/code>&lt;/td>
 &lt;td>只顯示指定欄位（跟 &lt;code>fields&lt;/code> 互補）&lt;/td>
 &lt;td>用在 &lt;code>stats&lt;/code> 後只要看聚合結果&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="json-自動解析">JSON 自動解析&lt;/h3>
&lt;p>CloudWatch Logs 會自動辨識 JSON 格式的 log event。JSON 欄位用 dot notation 存取：&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是 <a href="/blog/backend/04-observability/vendors/aws-cloudwatch/" data-link-title="AWS CloudWatch" data-link-desc="AWS 原生觀測性服務、Logs / Metrics / Traces (X-Ray)">AWS CloudWatch</a> 的 vendor deep article，深化 overview「Logs Insights query」跟「Logs lifecycle」段。初次接觸 CloudWatch 的讀者建議先讀 <a href="/blog/backend/04-observability/vendors/aws-cloudwatch/" data-link-title="AWS CloudWatch" data-link-desc="AWS 原生觀測性服務、Logs / Metrics / Traces (X-Ray)">CloudWatch 服務頁</a>。</p></blockquote>
<h2 id="問題情境">問題情境</h2>
<p>CloudWatch Logs 的成本模型跟 self-hosted log stack 不同 — ingestion、storage 跟 query 分開計費，每一層都有明確的 cost lever。理解 log group 設計、retention 設定與 subscription filter 的組合，才能在 AWS-native 環境下控制日誌成本而不犧牲事故判讀能力。</p>
<h2 id="log-group-設計">Log group 設計</h2>
<h3 id="拆分粒度">拆分粒度</h3>
<p>Log group 是 CloudWatch Logs 的計費與 retention 邊界。同一個 log group 內的所有 log stream 共用 retention policy 和 access control（IAM resource policy）。</p>
<p>合理的拆分粒度是 <strong>一個服務一個 log group</strong>，而非一個帳號一個或一個 container 一個。服務級拆分讓 retention、查詢範圍與 IAM 權限自然對齊服務 ownership。</p>
<table>
  <thead>
      <tr>
          <th>拆分策略</th>
          <th>適合場景</th>
          <th>風險</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一個服務一個 log group</td>
          <td>多數 production 服務</td>
          <td>log group 數量增長需要 naming convention</td>
      </tr>
      <tr>
          <td>一個環境一個 log group</td>
          <td>非常小的團隊、staging/dev 環境</td>
          <td>混合多個服務的日誌，查詢時需要額外 filter</td>
      </tr>
      <tr>
          <td>一個 Lambda function 一個 log group</td>
          <td>Lambda 預設行為</td>
          <td>Lambda 數量多時 log group 爆量，管理成本高</td>
      </tr>
  </tbody>
</table>
<p>Lambda 的預設行為是每個 function 自動建一個 log group（<code>/aws/lambda/&lt;function-name&gt;</code>）。function 數量超過數十個後，需要用 naming convention 加 tag 控制，否則 retention policy 難以統一套用。</p>
<h3 id="naming-convention">Naming convention</h3>
<p>推薦格式：<code>/&lt;environment&gt;/&lt;service&gt;/&lt;component&gt;</code>，例如 <code>/prod/checkout-api/app</code>、<code>/prod/checkout-api/access-log</code>。統一前綴讓 Logs Insights 的 multi-log-group query 用 prefix matching 篩選。</p>
<h2 id="logs-insights-查詢語法">Logs Insights 查詢語法</h2>
<h3 id="核心語法">核心語法</h3>
<p>Logs Insights 的查詢結構是 pipe-based：每行用 <code>|</code> 分隔，依序處理。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">fields @timestamp, @message, @logStream
</span></span><span class="line"><span class="ln">2</span><span class="cl">| filter @message like /ERROR/
</span></span><span class="line"><span class="ln">3</span><span class="cl">| parse @message &#34;order_id=* status=*&#34; as order_id, status
</span></span><span class="line"><span class="ln">4</span><span class="cl">| stats count(*) as error_count by status
</span></span><span class="line"><span class="ln">5</span><span class="cl">| sort error_count desc
</span></span><span class="line"><span class="ln">6</span><span class="cl">| limit 20</span></span></code></pre></div><p>常用 command 對照：</p>
<table>
  <thead>
      <tr>
          <th>Command</th>
          <th>用途</th>
          <th>注意事項</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>fields</code></td>
          <td>選擇要顯示的欄位</td>
          <td><code>@timestamp</code>、<code>@message</code> 是內建欄位</td>
      </tr>
      <tr>
          <td><code>filter</code></td>
          <td>條件篩選</td>
          <td>支援 <code>like /regex/</code>、<code>=</code>、<code>&gt;</code>、<code>in []</code></td>
      </tr>
      <tr>
          <td><code>parse</code></td>
          <td>從非結構化 log 擷取欄位</td>
          <td>glob pattern 用 <code>*</code>、regex 用 <code>/pattern/</code></td>
      </tr>
      <tr>
          <td><code>stats</code></td>
          <td>聚合計算</td>
          <td><code>count</code>、<code>avg</code>、<code>sum</code>、<code>min</code>、<code>max</code>、<code>pct</code></td>
      </tr>
      <tr>
          <td><code>sort</code></td>
          <td>排序</td>
          <td>預設 <code>@timestamp desc</code></td>
      </tr>
      <tr>
          <td><code>display</code></td>
          <td>只顯示指定欄位（跟 <code>fields</code> 互補）</td>
          <td>用在 <code>stats</code> 後只要看聚合結果</td>
      </tr>
  </tbody>
</table>
<h3 id="json-自動解析">JSON 自動解析</h3>
<p>CloudWatch Logs 會自動辨識 JSON 格式的 log event。JSON 欄位用 dot notation 存取：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">fields @timestamp, requestId, level, message
</span></span><span class="line"><span class="ln">2</span><span class="cl">| filter level = &#34;ERROR&#34;
</span></span><span class="line"><span class="ln">3</span><span class="cl">| stats count(*) by bin(5m)</span></span></code></pre></div><p>如果 log 是 JSON 格式，<code>parse</code> 通常不需要 — 直接用欄位名稱。混合格式（部分 JSON、部分 plain text）時，需要用 <code>isPresent()</code> 判斷欄位是否存在。</p>
<h3 id="效能考量">效能考量</h3>
<p>Logs Insights 的查詢成本按掃描的 data 量計費（每 GB scanned），不按結果數。減少掃描量的方式：</p>
<ul>
<li>縮短時間範圍：事故判讀先查最近 30 分鐘，確認 pattern 後再擴大</li>
<li>指定 log group：避免對所有 log group 做全域查詢</li>
<li>用 <code>limit</code> 限制結果集大小（不影響掃描量，但減少資料傳輸）</li>
</ul>
<p>跨 log group 查詢最多同時查 50 個 log group。超過時需要拆成多次查詢或用 subscription filter 把資料匯到集中儲存。</p>
<h2 id="retention-policy">Retention policy</h2>
<h3 id="設定方式">設定方式</h3>
<p>Retention policy 在 log group 級別設定。每個 log group 可以獨立選擇 1 天到 10 年、或永不過期。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">aws logs put-retention-policy <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --log-group-name /prod/checkout-api/app <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --retention-in-days <span class="m">30</span></span></span></code></pre></div><p>常見 retention 策略按服務性質分：</p>
<table>
  <thead>
      <tr>
          <th>服務類型</th>
          <th>建議 retention</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>核心交易路徑（checkout、payment）</td>
          <td>90-365 天</td>
          <td>事故回溯、合規稽核</td>
      </tr>
      <tr>
          <td>一般 API 服務</td>
          <td>30-90 天</td>
          <td>事故回溯足夠，cost 可控</td>
      </tr>
      <tr>
          <td>Background job / worker</td>
          <td>14-30 天</td>
          <td>失敗時看最近數天即可</td>
      </tr>
      <tr>
          <td>Lambda / short-lived function</td>
          <td>7-14 天</td>
          <td>高量低價值，過期快速清理</td>
      </tr>
      <tr>
          <td>Audit log</td>
          <td>365 天以上或永不過期</td>
          <td>法規要求，見 <a href="/blog/backend/04-observability/audit-log-governance/" data-link-title="4.12 Audit Log 邊界與 PII 治理" data-link-desc="把稽核訊號從 operational log 拆出、按法規與不變性治理">4.12 Audit Log Governance</a></td>
      </tr>
  </tbody>
</table>
<p>未設定 retention 的 log group 預設永不過期 — 這是 CloudWatch 日誌成本超支的常見原因。新 log group 建立後應立即設定 retention。</p>
<h3 id="fintech-合規場景的-log-group-分離">FinTech 合規場景的 log group 分離</h3>
<p><a href="/blog/backend/04-observability/cases/fintech-audit-evidence-observability/" data-link-title="FinTech：審計證據鏈的可觀測性設計" data-link-desc="把交易與存取事件轉成可回查證據，降低合規審核與事故判讀落差。">FinTech 審計證據案例</a>揭露一個常見問題：audit log 跟 operational log 混在同一個 log group，retention 只能統一設定。結果要嘛 operational log 為了合規被迫留太久（成本浪費）、要嘛 audit log 跟著 operational log 的短 retention 被刪掉（合規風險）。</p>
<p>CloudWatch 的 log group 設計天然支援這種分離 — audit log 跟 operational log 用不同 log group、各自設定 retention：</p>
<table>
  <thead>
      <tr>
          <th>Log 類型</th>
          <th>Log group 命名</th>
          <th>Retention</th>
          <th>Log class</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>交易 audit log</td>
          <td><code>/prod/checkout-api/audit</code></td>
          <td>2555 天（7 年）</td>
          <td>Infrequent Access</td>
      </tr>
      <tr>
          <td>Application operational log</td>
          <td><code>/prod/checkout-api/app</code></td>
          <td>30 天</td>
          <td>Standard</td>
      </tr>
      <tr>
          <td>Access log（ALB / API Gateway）</td>
          <td><code>/prod/checkout-api/access</code></td>
          <td>90 天</td>
          <td>Standard</td>
      </tr>
  </tbody>
</table>
<p>Audit log group 的額外治理：</p>
<ul>
<li><strong>IAM 權限分離</strong>：audit log group 的讀取權限（<code>logs:GetLogEvents</code>）限縮到 compliance team 跟 security team，application developer 只能讀 operational log group。避免 audit log 被隨意查詢或汙染</li>
<li><strong>Immutability</strong>：CloudWatch Logs 本身不支援 WORM（write once read many），合規要求 immutable 存檔時用 subscription filter 把 audit log 同步送到 S3 + Object Lock</li>
<li><strong>Cross-account 集中</strong>：audit log 的 cross-account aggregation（見下方段落）的 IAM 權限要比 operational log 嚴格 — aggregated sink 的 destination 只能由 security team 控制</li>
</ul>
<h3 id="infrequent-access-log-class">Infrequent Access log class</h3>
<p>CloudWatch Logs 提供兩種 log class：<strong>Standard</strong>（完整查詢、即時 subscription filter、metric filter）跟 <strong>Infrequent Access</strong>（僅支援 Logs Insights 查詢、不支援即時 subscription filter 跟 metric filter、ingestion 成本約降 50%）。</p>
<p>Audit log 的存取模式通常是「寫入頻繁、查詢極少（只在稽核或事故時才查）」— 正好符合 Infrequent Access 的定位。把 7 年 retention 的 audit log group 設成 Infrequent Access，ingestion 成本直接砍半。</p>
<p>注意 Infrequent Access 的限制：不能用 subscription filter 即時轉發到 Lambda 或 Kinesis，不能用 metric filter 從 log 產生 CloudWatch metric。如果 audit log 需要即時異常偵測（例如偵測大量失敗交易），要用 Standard class + subscription filter 做即時處理、再用 Lambda 寫到長期 audit log group（Infrequent Access）。</p>
<h3 id="自動化套用">自動化套用</h3>
<p>用 AWS Config rule 或 CloudFormation / CDK 的 log group 定義統一設定 retention。Lambda function 自動建立的 log group 不會自動套用 retention，需要額外自動化（Lambda post-hook 或 EventBridge rule + Lambda 設定 retention）。</p>
<h2 id="cross-account-log-aggregation">Cross-account log aggregation</h2>
<h3 id="架構模式">架構模式</h3>
<p>多帳號環境下，常見做法是設立一個「觀測帳號」（observability account），把其他帳號的 logs 匯入。</p>
<p>兩種匯入方式：</p>
<p><strong>Subscription filter + Kinesis Data Firehose</strong>：每個 source 帳號的 log group 設 subscription filter，把 log event 送到 observability 帳號的 Kinesis Data Firehose，再寫到 S3 或 OpenSearch。適合需要長期存檔或進階查詢的場景。</p>
<p><strong>CloudWatch cross-account observability</strong>：AWS 原生功能，在 monitoring account 直接查詢 source accounts 的 CloudWatch 資料（metrics、logs、traces）。設定較簡單，但查詢延遲較高，且 Logs Insights 的 cross-account 查詢有 region 限制。</p>
<table>
  <thead>
      <tr>
          <th>匯入方式</th>
          <th>適合場景</th>
          <th>限制</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Subscription filter + Firehose</td>
          <td>需要 S3 archive、OpenSearch 全文搜尋、離線分析</td>
          <td>每個 log group 最多 2 個 subscription filter</td>
      </tr>
      <tr>
          <td>Cross-account observability</td>
          <td>只需要 CloudWatch console 統一查詢</td>
          <td>同 region 限制、查詢延遲較高</td>
      </tr>
  </tbody>
</table>
<h3 id="subscription-filter-實務">Subscription filter 實務</h3>
<p>Subscription filter 可以把 log event 送到 Lambda（即時處理）、Kinesis Data Stream（緩衝）、Kinesis Data Firehose（直接寫 S3/OpenSearch）或另一個 log group。</p>
<p>每個 log group 最多 2 個 subscription filter — 這是硬限制。如果同一個 log group 需要同時送 S3 archive 跟即時 alerting，要用 Kinesis Data Stream 做 fan-out，讓 stream 下游各自消費。</p>
<p>filter pattern 語法支援 JSON 欄位匹配：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">{ $.level = &#34;ERROR&#34; }</span></span></code></pre></div><p>只把 ERROR 級別的 log 送到 alerting pipeline，可以大幅降低下游處理量跟成本。</p>
<h2 id="cost-governance">Cost governance</h2>
<h3 id="計費結構">計費結構</h3>
<p>CloudWatch Logs 的成本由三個維度組成：</p>
<table>
  <thead>
      <tr>
          <th>計費項目</th>
          <th>計費方式</th>
          <th>常見比例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Ingestion</td>
          <td>每 GB ingested</td>
          <td>通常佔 50-70%</td>
      </tr>
      <tr>
          <td>Storage</td>
          <td>每 GB-month stored</td>
          <td>通常佔 20-40%</td>
      </tr>
      <tr>
          <td>Query（Logs Insights）</td>
          <td>每 GB scanned</td>
          <td>通常佔 5-15%</td>
      </tr>
  </tbody>
</table>
<p>Ingestion 是最大成本。降低 ingestion 的手段：</p>
<ul>
<li><strong>調整 log level</strong>：production 只保留 INFO 以上，DEBUG 只在問題排查時短暫開啟</li>
<li><strong>去除重複資訊</strong>：access log 跟 application log 不要記錄相同欄位</li>
<li><strong>用 metric filter 替代 log query</strong>：高頻計數（error count、request count）用 CloudWatch Metric Filter 從 log 產生 metric，查詢成本從 log scan 轉成 metric query</li>
</ul>
<h3 id="成本觀測">成本觀測</h3>
<p>用 CloudWatch 自己的 metric 觀測 log 成本：</p>
<ul>
<li><code>IncomingBytes</code>（per log group）：監控哪個 log group ingestion 最大</li>
<li><code>IncomingLogEvents</code>（per log group）：監控 event 數量</li>
<li>AWS Cost Explorer 按 CloudWatch 拆分：看 log ingestion vs storage vs API call 的比例</li>
</ul>
<h3 id="降本決策樹">降本決策樹</h3>
<p>判斷成本是否合理的順序：</p>
<ol>
<li>最大 ingestion 的 log group 是哪個？是否合理（核心服務的 access log 量大是正常的）</li>
<li>Retention 是否都有設定？未設定的 log group 會持續累積 storage 成本</li>
<li>是否有 DEBUG 級別 log 在 production 長期開啟？</li>
<li>是否有 subscription filter 把全量 log 送到外部？能否加 filter pattern 只送需要的部分</li>
</ol>
<h2 id="整合與下一步">整合與下一步</h2>
<ul>
<li>觀測管線整合：CloudWatch Logs → Subscription Filter → Kinesis Firehose → S3 / OpenSearch，見 <a href="/blog/backend/04-observability/telemetry-pipeline/" data-link-title="4.11 Telemetry Pipeline 架構" data-link-desc="把 log / metric / trace 的 agent → collector → ingest → storage → query 分層治理">4.11 Telemetry Pipeline</a></li>
<li>Audit log 治理：合規場景的 log retention 跟 access control，見 <a href="/blog/backend/04-observability/audit-log-governance/" data-link-title="4.12 Audit Log 邊界與 PII 治理" data-link-desc="把稽核訊號從 operational log 拆出、按法規與不變性治理">4.12 Audit Log Governance</a></li>
<li>Evidence package：把 Logs Insights query link 跟時間窗放進 evidence，見 <a href="/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">4.20 Observability Evidence Package</a></li>
<li>OTel 整合：ADOT 可以把 log 送到 CloudWatch Logs 或其他 backend，見 <a href="/blog/backend/04-observability/vendors/opentelemetry/collector-deployment-patterns/" data-link-title="OTel Collector 部署模式：agent / gateway / sidecar 與 pipeline 設計" data-link-desc="說明 OpenTelemetry Collector 三種部署位置的責任分工、receivers/processors/exporters pipeline 設計，以及 collector 失效、記憶體壓力與 backpressure 的故障演練與容量邊界">OpenTelemetry Collector 部署模式</a></li>
</ul>
]]></content:encoded></item></channel></rss>