<?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>Monitoring 知識卡片 on Tarragon</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/</link><description>Recent content in Monitoring 知識卡片 on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/index.xml" rel="self" type="application/rss+xml"/><item><title>Funnel Analysis</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/</guid><description>&lt;p>Funnel analysis 的核心概念是「追蹤使用者在多步驟流程中每一步的轉換率和流失率」。每一步有多少使用者完成、多少使用者離開，構成漏斗形狀的轉換圖。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/cohort-analysis/" data-link-title="Cohort Analysis" data-link-desc="說明把使用者按共同特徵分群、比較不同群組行為差異的分析方法">cohort analysis&lt;/a>（按群組比較留存）和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rfm/" data-link-title="RFM" data-link-desc="說明用 Recency / Frequency / Monetary 三個維度把使用者分成可操作群組的分群方法">RFM&lt;/a>（按行為分群）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Funnel analysis 位在行為資料收集之後、產品決策之前。它的輸入是 event 類監控事件（使用者操作記錄），輸出是每步的轉換率。Funnel analysis 的前提是去識別化（&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction&lt;/a>）已完成 — 分析行為資料前必須確保資料不含可識別個人的敏感欄位。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>產品需要 funnel analysis 的訊號是「使用者在某個流程中的完成率低於預期，但不知道卡在哪一步」。註冊流程的轉換率從填寫 email 到完成驗證只有 30%，funnel analysis 揭露 60% 的使用者在「等待驗證信」步驟流失。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Funnel analysis 要定義步驟順序、步驟之間的時間窗口（使用者在多久內完成下一步才算轉換）、以及分群維度（按平台、來源、使用者類型拆分 funnel）。步驟定義需要和事件命名規範對齊 — funnel 的每一步對應一個具體的事件名稱。&lt;/p></description><content:encoded><![CDATA[<p>Funnel analysis 的核心概念是「追蹤使用者在多步驟流程中每一步的轉換率和流失率」。每一步有多少使用者完成、多少使用者離開，構成漏斗形狀的轉換圖。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/cohort-analysis/" data-link-title="Cohort Analysis" data-link-desc="說明把使用者按共同特徵分群、比較不同群組行為差異的分析方法">cohort analysis</a>（按群組比較留存）和 <a href="/blog/devops/monitoring/knowledge-cards/rfm/" data-link-title="RFM" data-link-desc="說明用 Recency / Frequency / Monetary 三個維度把使用者分成可操作群組的分群方法">RFM</a>（按行為分群）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Funnel analysis 位在行為資料收集之後、產品決策之前。它的輸入是 event 類監控事件（使用者操作記錄），輸出是每步的轉換率。Funnel analysis 的前提是去識別化（<a href="/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction</a>）已完成 — 分析行為資料前必須確保資料不含可識別個人的敏感欄位。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>產品需要 funnel analysis 的訊號是「使用者在某個流程中的完成率低於預期，但不知道卡在哪一步」。註冊流程的轉換率從填寫 email 到完成驗證只有 30%，funnel analysis 揭露 60% 的使用者在「等待驗證信」步驟流失。</p>
<h2 id="設計責任">設計責任</h2>
<p>Funnel analysis 要定義步驟順序、步驟之間的時間窗口（使用者在多久內完成下一步才算轉換）、以及分群維度（按平台、來源、使用者類型拆分 funnel）。步驟定義需要和事件命名規範對齊 — funnel 的每一步對應一個具體的事件名稱。</p>
]]></content:encoded></item><item><title>Redaction</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/</guid><description>&lt;p>Redaction 的核心概念是「在事件資料離開 client 之前，把敏感欄位的值替換成遮罩或移除」。密碼、API key、個人識別資訊在送到 collector 之前就被處理，確保敏感資料不進入傳輸和儲存層。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis&lt;/a>（去識別化是行為分析的入場條件）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Redaction 位在 SDK 端的事件產生和 collector 端的事件接收之間。它是監控資料安全的第一道防線 — 在資料離開使用者裝置之前處理，比 collector 端的 access control 更早介入。Redaction 和 transport 加密（HTTPS）互補：redaction 保護欄位內容，transport 加密保護傳輸過程。與 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/error-fingerprint/" data-link-title="Error Fingerprint" data-link-desc="從 error 事件的 type、normalized message、stack trace 計算 hash，把相同根因的 error 歸為同一 error group">error fingerprint&lt;/a> 相比，兩者都在資料落地前處理，但 redaction 防止敏感內容外洩、fingerprint 防止同因錯誤重複灌爆列表。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>系統需要 redaction 的訊號是監控事件的 data 欄位可能包含使用者輸入。CLI 輸入可能含密碼（&lt;code>mysql -p'secret'&lt;/code>）、API key（&lt;code>Authorization: Bearer sk-...&lt;/code>）、連線字串（含帳密的 URL）。IME 個人化學習也是洩漏面 — 輸入框的內容被 IME 學習後跨 app 可見。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Redaction 要定義預設規則（哪些欄位名稱自動 redact）、自訂 pattern（正則表達式比對敏感值）、執行時機（event 進入 buffer 前還是 flush 時）、以及 redaction 失敗的處理（丟棄整筆事件 vs 只移除敏感欄位）。這些規則只管得到網站自己 SDK 送出的事件；同一個頁面上的商業追蹤碼由 vendor 的 script 直接送出，遮蔽要用 vendor 提供的設定，見 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">Autocapture（自動事件收集）&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Redaction 的核心概念是「在事件資料離開 client 之前，把敏感欄位的值替換成遮罩或移除」。密碼、API key、個人識別資訊在送到 collector 之前就被處理，確保敏感資料不進入傳輸和儲存層。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis</a>（去識別化是行為分析的入場條件）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Redaction 位在 SDK 端的事件產生和 collector 端的事件接收之間。它是監控資料安全的第一道防線 — 在資料離開使用者裝置之前處理，比 collector 端的 access control 更早介入。Redaction 和 transport 加密（HTTPS）互補：redaction 保護欄位內容，transport 加密保護傳輸過程。與 <a href="/blog/devops/monitoring/knowledge-cards/error-fingerprint/" data-link-title="Error Fingerprint" data-link-desc="從 error 事件的 type、normalized message、stack trace 計算 hash，把相同根因的 error 歸為同一 error group">error fingerprint</a> 相比，兩者都在資料落地前處理，但 redaction 防止敏感內容外洩、fingerprint 防止同因錯誤重複灌爆列表。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>系統需要 redaction 的訊號是監控事件的 data 欄位可能包含使用者輸入。CLI 輸入可能含密碼（<code>mysql -p'secret'</code>）、API key（<code>Authorization: Bearer sk-...</code>）、連線字串（含帳密的 URL）。IME 個人化學習也是洩漏面 — 輸入框的內容被 IME 學習後跨 app 可見。</p>
<h2 id="設計責任">設計責任</h2>
<p>Redaction 要定義預設規則（哪些欄位名稱自動 redact）、自訂 pattern（正則表達式比對敏感值）、執行時機（event 進入 buffer 前還是 flush 時）、以及 redaction 失敗的處理（丟棄整筆事件 vs 只移除敏感欄位）。這些規則只管得到網站自己 SDK 送出的事件；同一個頁面上的商業追蹤碼由 vendor 的 script 直接送出，遮蔽要用 vendor 提供的設定，見 <a href="/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">Autocapture（自動事件收集）</a>。</p>
]]></content:encoded></item><item><title>Cohort Analysis</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/cohort-analysis/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/cohort-analysis/</guid><description>&lt;p>Cohort analysis 的核心概念是「把使用者按共同特徵分群，比較不同群組的行為差異」。Cohort 通常按時間（註冊月份）、行為（首次使用的功能）、或屬性（付費方案）分群。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis&lt;/a>（追蹤單一流程的每步轉換）和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rfm/" data-link-title="RFM" data-link-desc="說明用 Recency / Frequency / Monetary 三個維度把使用者分成可操作群組的分群方法">RFM&lt;/a>（按行為指標分群）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Cohort analysis 位在 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis&lt;/a> 之後、策略制定之前。Funnel analysis 回答「使用者在哪一步流失」，cohort analysis 回答「哪種使用者流失率高」。兩者搭配使用：funnel 找到流失步驟，cohort 找到流失群組，策略針對特定群組的流失步驟設計。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>產品需要 cohort analysis 的訊號是「整體留存率或轉換率的平均值遮蔽了群組差異」。整體 30 天留存率 40%，但按註冊來源拆分後發現自然搜尋來的使用者留存 60%、廣告來的使用者留存 20% — 平均值沒有揭露這個差異。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Cohort analysis 要定義分群維度（按什麼特徵分）、觀察指標（留存率、活躍度、付費率）、觀察時間窗口（7 天、30 天、90 天）、以及最小群組大小（群組太小時統計不顯著）。分群維度的選擇決定了分析能揭露什麼 — 按「註冊來源」分群能看到獲客通路的品質差異，按「使用的功能」分群能看到功能黏著度差異。&lt;/p></description><content:encoded><![CDATA[<p>Cohort analysis 的核心概念是「把使用者按共同特徵分群，比較不同群組的行為差異」。Cohort 通常按時間（註冊月份）、行為（首次使用的功能）、或屬性（付費方案）分群。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis</a>（追蹤單一流程的每步轉換）和 <a href="/blog/devops/monitoring/knowledge-cards/rfm/" data-link-title="RFM" data-link-desc="說明用 Recency / Frequency / Monetary 三個維度把使用者分成可操作群組的分群方法">RFM</a>（按行為指標分群）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Cohort analysis 位在 <a href="/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis</a> 之後、策略制定之前。Funnel analysis 回答「使用者在哪一步流失」，cohort analysis 回答「哪種使用者流失率高」。兩者搭配使用：funnel 找到流失步驟，cohort 找到流失群組，策略針對特定群組的流失步驟設計。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>產品需要 cohort analysis 的訊號是「整體留存率或轉換率的平均值遮蔽了群組差異」。整體 30 天留存率 40%，但按註冊來源拆分後發現自然搜尋來的使用者留存 60%、廣告來的使用者留存 20% — 平均值沒有揭露這個差異。</p>
<h2 id="設計責任">設計責任</h2>
<p>Cohort analysis 要定義分群維度（按什麼特徵分）、觀察指標（留存率、活躍度、付費率）、觀察時間窗口（7 天、30 天、90 天）、以及最小群組大小（群組太小時統計不顯著）。分群維度的選擇決定了分析能揭露什麼 — 按「註冊來源」分群能看到獲客通路的品質差異，按「使用的功能」分群能看到功能黏著度差異。</p>
]]></content:encoded></item><item><title>RFM</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rfm/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rfm/</guid><description>&lt;p>RFM 的核心概念是「用 Recency（最近活躍度）、Frequency（使用頻率）、Monetary（貢獻價值）三個維度把使用者分成可操作的群組」。每個維度獨立評分後組合，識別出忠實客戶、潛在流失、新使用者、休眠使用者等群組。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/cohort-analysis/" data-link-title="Cohort Analysis" data-link-desc="說明把使用者按共同特徵分群、比較不同群組行為差異的分析方法">cohort analysis&lt;/a>（按共同特徵分群）和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis&lt;/a>（追蹤流程轉換率）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>RFM 位在行為資料累積到一定量之後。它需要每個使用者的 session 歷史（計算 Recency 和 Frequency）和交易歷史（計算 Monetary）。免費產品可以用替代指標取代 Monetary — 產生的內容數量、邀請的使用者數、完成的關鍵操作數。RFM 的前提和 cohort analysis 相同：去識別化（&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction&lt;/a>）已完成。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>產品需要 RFM 的訊號是「需要對不同行為模式的使用者採取不同策略」。高 R 高 F 高 M 的忠實客戶需要維護關係，低 R 高 F 高 M 的潛在流失客戶需要挽留，高 R 低 F 低 M 的新使用者需要引導降低入門門檻。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>RFM 要定義每個維度的計算方式（Recency 用天數還是週數、Frequency 的時間窗口多長、Monetary 用什麼指標）、分位數（五等分還是三等分）、群組歸納（125 種 profile 歸納成幾個可操作群組）、以及重新計算的頻率（每週還是每月）。分群結果是動態的 — 使用者行為改變時群組會變。&lt;/p></description><content:encoded><![CDATA[<p>RFM 的核心概念是「用 Recency（最近活躍度）、Frequency（使用頻率）、Monetary（貢獻價值）三個維度把使用者分成可操作的群組」。每個維度獨立評分後組合，識別出忠實客戶、潛在流失、新使用者、休眠使用者等群組。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/cohort-analysis/" data-link-title="Cohort Analysis" data-link-desc="說明把使用者按共同特徵分群、比較不同群組行為差異的分析方法">cohort analysis</a>（按共同特徵分群）和 <a href="/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis</a>（追蹤流程轉換率）。</p>
<h2 id="概念位置">概念位置</h2>
<p>RFM 位在行為資料累積到一定量之後。它需要每個使用者的 session 歷史（計算 Recency 和 Frequency）和交易歷史（計算 Monetary）。免費產品可以用替代指標取代 Monetary — 產生的內容數量、邀請的使用者數、完成的關鍵操作數。RFM 的前提和 cohort analysis 相同：去識別化（<a href="/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction</a>）已完成。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>產品需要 RFM 的訊號是「需要對不同行為模式的使用者採取不同策略」。高 R 高 F 高 M 的忠實客戶需要維護關係，低 R 高 F 高 M 的潛在流失客戶需要挽留，高 R 低 F 低 M 的新使用者需要引導降低入門門檻。</p>
<h2 id="設計責任">設計責任</h2>
<p>RFM 要定義每個維度的計算方式（Recency 用天數還是週數、Frequency 的時間窗口多長、Monetary 用什麼指標）、分位數（五等分還是三等分）、群組歸納（125 種 profile 歸納成幾個可操作群組）、以及重新計算的頻率（每週還是每月）。分群結果是動態的 — 使用者行為改變時群組會變。</p>
]]></content:encoded></item><item><title>Error Fingerprint</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/error-fingerprint/</link><pubDate>Wed, 24 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/error-fingerprint/</guid><description>&lt;p>Error fingerprint 的核心概念是「從 error 事件中提取關鍵欄位計算 hash，相同 hash 的事件歸為同一 error group」。沒有 fingerprint 時，1000 筆同因 error 在 dashboard 上是 1000 行；有 fingerprint 後歸為 1 組，顯示 count / first_seen / last_seen / affected_sessions。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction&lt;/a>（事件送出前的資料脫敏）和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis&lt;/a>（行為事件的轉換率分析）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Error fingerprint 位在 collector 收到 error 事件之後、寫入 storage 之前。它的輸入是通過 schema validation 的 error 事件，輸出是附加了 &lt;code>_fingerprint&lt;/code> 欄位的事件和更新後的 error_groups 摘要表。Fingerprint 只作用於 &lt;code>type: &amp;quot;error&amp;quot;&lt;/code> 的事件 — 其他三類事件（event / metric / lifecycle）不需要去重分群。與 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction&lt;/a> 同樣運作在事件寫入 storage 之前，但目的不同——redaction 處理欄位內容的隱私、fingerprint 處理事件的分群鍵。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>需要 fingerprint 的訊號是「dashboard 的 error 列表中，同一個 bug 因為 error message 包含動態值（user ID、timestamp、IP）而分裂成多個不同的行」。例如 &lt;code>&amp;quot;User 12345 not found&amp;quot;&lt;/code> 和 &lt;code>&amp;quot;User 67890 not found&amp;quot;&lt;/code> 是同一個 bug，但 name-based grouping（&lt;code>GROUP BY name&lt;/code>）把它們歸為同一行時，丟失了 message 中的動態值資訊；而沒有 normalization 的 message-based grouping 會把它們分裂成兩行。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Fingerprint 承擔的設計責任是「在 error 的精確識別和分群粒度之間找到平衡」。過粗的 fingerprint（只用 error type）把不同 bug 混在同一組；過細的 fingerprint（用完整 message 含動態值）把同因 error 分裂成多組。&lt;/p>
&lt;h2 id="自架-vs-商業方案">自架 vs 商業方案&lt;/h2>
&lt;p>自架方案用規則做 fingerprint — regex normalize message（替換數字 / UUID / email / IP 等動態值）+ stack trace top N frames 做 hash。Sentry 在規則之上加了 in-app frame 過濾（忽略 framework / library frame）、source map 反解（minified JS → 原始碼位置）、和 ML-based grouping（語意相同但結構不同的 error 歸組）。差距主要在 minified / obfuscated 環境和 ML — 明文 stack trace 的場景下兩者效果相當。&lt;/p>
&lt;h2 id="完整章節">完整章節&lt;/h2>
&lt;p>Fingerprint 演算法（基礎 / 進階 / Sentry / 自定義）、message normalization 的替換規則和風險、error_groups 表的 DDL 和 UPSERT 流程、dashboard 整合、自架方案的務實邊界 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/04-collector/error-fingerprint/" data-link-title="Error Fingerprint 與去重分群" data-link-desc="把大量 error 事件歸組成可管理的 issue 列表 — fingerprint 演算法、message normalization、error_groups 表設計、自架方案的務實邊界">Error Fingerprint 與去重分群&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Error fingerprint 的核心概念是「從 error 事件中提取關鍵欄位計算 hash，相同 hash 的事件歸為同一 error group」。沒有 fingerprint 時，1000 筆同因 error 在 dashboard 上是 1000 行；有 fingerprint 後歸為 1 組，顯示 count / first_seen / last_seen / affected_sessions。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction</a>（事件送出前的資料脫敏）和 <a href="/blog/devops/monitoring/knowledge-cards/funnel-analysis/" data-link-title="Funnel Analysis" data-link-desc="說明追蹤使用者在多步驟流程中每一步的轉換率和流失率的分析方法">funnel analysis</a>（行為事件的轉換率分析）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Error fingerprint 位在 collector 收到 error 事件之後、寫入 storage 之前。它的輸入是通過 schema validation 的 error 事件，輸出是附加了 <code>_fingerprint</code> 欄位的事件和更新後的 error_groups 摘要表。Fingerprint 只作用於 <code>type: &quot;error&quot;</code> 的事件 — 其他三類事件（event / metric / lifecycle）不需要去重分群。與 <a href="/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">redaction</a> 同樣運作在事件寫入 storage 之前，但目的不同——redaction 處理欄位內容的隱私、fingerprint 處理事件的分群鍵。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>需要 fingerprint 的訊號是「dashboard 的 error 列表中，同一個 bug 因為 error message 包含動態值（user ID、timestamp、IP）而分裂成多個不同的行」。例如 <code>&quot;User 12345 not found&quot;</code> 和 <code>&quot;User 67890 not found&quot;</code> 是同一個 bug，但 name-based grouping（<code>GROUP BY name</code>）把它們歸為同一行時，丟失了 message 中的動態值資訊；而沒有 normalization 的 message-based grouping 會把它們分裂成兩行。</p>
<h2 id="設計責任">設計責任</h2>
<p>Fingerprint 承擔的設計責任是「在 error 的精確識別和分群粒度之間找到平衡」。過粗的 fingerprint（只用 error type）把不同 bug 混在同一組；過細的 fingerprint（用完整 message 含動態值）把同因 error 分裂成多組。</p>
<h2 id="自架-vs-商業方案">自架 vs 商業方案</h2>
<p>自架方案用規則做 fingerprint — regex normalize message（替換數字 / UUID / email / IP 等動態值）+ stack trace top N frames 做 hash。Sentry 在規則之上加了 in-app frame 過濾（忽略 framework / library frame）、source map 反解（minified JS → 原始碼位置）、和 ML-based grouping（語意相同但結構不同的 error 歸組）。差距主要在 minified / obfuscated 環境和 ML — 明文 stack trace 的場景下兩者效果相當。</p>
<h2 id="完整章節">完整章節</h2>
<p>Fingerprint 演算法（基礎 / 進階 / Sentry / 自定義）、message normalization 的替換規則和風險、error_groups 表的 DDL 和 UPSERT 流程、dashboard 整合、自架方案的務實邊界 → <a href="/blog/devops/monitoring/04-collector/error-fingerprint/" data-link-title="Error Fingerprint 與去重分群" data-link-desc="把大量 error 事件歸組成可管理的 issue 列表 — fingerprint 演算法、message normalization、error_groups 表設計、自架方案的務實邊界">Error Fingerprint 與去重分群</a>。</p>
]]></content:encoded></item><item><title>Backpressure</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/</link><pubDate>Wed, 24 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/</guid><description>&lt;p>背壓（backpressure）的通用概念見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="說明下游處理速度不足時系統如何讓上游依下游能力送出工作">Backend 知識卡：Backpressure&lt;/a> — 下游處理能力不足時向上游回傳「慢下來」訊號。本卡聚焦監控系統中的具體實作：collector 是下游、SDK 是上游，collector 的寫入 channel 滿時回 HTTP 429（Too Many Requests），SDK 收到 429 後自動降低&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">取樣&lt;/a>率。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rate-limiting/" data-link-title="Rate Limiting" data-link-desc="限制每個 client 在單位時間內可送出的事件數量 — 防止單一 SDK bug 或偽造流量消耗整個 collector 的處理能力">rate limiting&lt;/a>（per-client 的配額限制）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>背壓位在 SDK 和 collector 之間的 HTTP 通訊層。觸發順序：collector 的寫入 channel 容量耗盡 → HTTP handler 無法送入事件 → 回 429 → SDK 收到 429 → SDK 降低&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">取樣&lt;/a>率（從 1.0 → 0.5 → 0.1）。背壓是全域的容量訊號 — 所有 SDK 同時收到，所有 SDK 同時降速。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>需要關注背壓的訊號是 collector 端的 &lt;code>collector.events.backpressure&lt;/code> 計數器持續上升、或 SDK 端的 &lt;code>sdk.sampling.rate&lt;/code> 低於 1.0。典型場景：行銷活動導致同時在線使用者暴增 → 所有 SDK 同時 flush → collector channel 瞬間填滿 → 全域 429 → 所有 SDK 動態降採樣。&lt;/p>
&lt;h2 id="和-devops-背壓的關係">和 DevOps 背壓的關係&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/devops/operations/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">運行期維運 流量管控&lt;/a>討論通用的背壓概念（TCP flow control、message queue consumer lag、circuit breaker）。本系列聚焦 SDK ↔ collector 之間的具體實作 — HTTP 429 是訊號、動態取樣是回應、Go channel 容量是觸發條件。通用概念在 運維模組，監控場景的具體機制在本系列。&lt;/p>
&lt;h2 id="完整章節">完整章節&lt;/h2>
&lt;p>背壓在四層防線中的位置（第二層 collector 單機防護）→ &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/04-collector/ingestion-scaling/" data-link-title="Ingestion Scaling" data-link-desc="四層防線應對 ingestion 端的流量擴展 — SDK 取樣、Collector 背壓、水平擴展、Queue 解耦">Ingestion Scaling&lt;/a>。背壓造成的資料損失和控制策略 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/04-collector/data-integrity/" data-link-title="端到端資料完整性" data-link-desc="從 SDK 到 storage 的資料損失地圖 — 每個環節的損失類型、控制策略、完整性指標、被自己 SDK DDoS 的防護">端到端資料完整性&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>背壓（backpressure）的通用概念見 <a href="/blog/backend/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="說明下游處理速度不足時系統如何讓上游依下游能力送出工作">Backend 知識卡：Backpressure</a> — 下游處理能力不足時向上游回傳「慢下來」訊號。本卡聚焦監控系統中的具體實作：collector 是下游、SDK 是上游，collector 的寫入 channel 滿時回 HTTP 429（Too Many Requests），SDK 收到 429 後自動降低<a href="/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">取樣</a>率。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/rate-limiting/" data-link-title="Rate Limiting" data-link-desc="限制每個 client 在單位時間內可送出的事件數量 — 防止單一 SDK bug 或偽造流量消耗整個 collector 的處理能力">rate limiting</a>（per-client 的配額限制）。</p>
<h2 id="概念位置">概念位置</h2>
<p>背壓位在 SDK 和 collector 之間的 HTTP 通訊層。觸發順序：collector 的寫入 channel 容量耗盡 → HTTP handler 無法送入事件 → 回 429 → SDK 收到 429 → SDK 降低<a href="/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">取樣</a>率（從 1.0 → 0.5 → 0.1）。背壓是全域的容量訊號 — 所有 SDK 同時收到，所有 SDK 同時降速。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>需要關注背壓的訊號是 collector 端的 <code>collector.events.backpressure</code> 計數器持續上升、或 SDK 端的 <code>sdk.sampling.rate</code> 低於 1.0。典型場景：行銷活動導致同時在線使用者暴增 → 所有 SDK 同時 flush → collector channel 瞬間填滿 → 全域 429 → 所有 SDK 動態降採樣。</p>
<h2 id="和-devops-背壓的關係">和 DevOps 背壓的關係</h2>
<p><a href="/blog/devops/operations/03-traffic-management/" data-link-title="模組三：流量管控" data-link-desc="收到的流量超過處理能力時怎麼辦 — 背壓、rate limit、熔斷、bulkhead 四種防護機制">運行期維運 流量管控</a>討論通用的背壓概念（TCP flow control、message queue consumer lag、circuit breaker）。本系列聚焦 SDK ↔ collector 之間的具體實作 — HTTP 429 是訊號、動態取樣是回應、Go channel 容量是觸發條件。通用概念在 運維模組，監控場景的具體機制在本系列。</p>
<h2 id="完整章節">完整章節</h2>
<p>背壓在四層防線中的位置（第二層 collector 單機防護）→ <a href="/blog/devops/monitoring/04-collector/ingestion-scaling/" data-link-title="Ingestion Scaling" data-link-desc="四層防線應對 ingestion 端的流量擴展 — SDK 取樣、Collector 背壓、水平擴展、Queue 解耦">Ingestion Scaling</a>。背壓造成的資料損失和控制策略 → <a href="/blog/devops/monitoring/04-collector/data-integrity/" data-link-title="端到端資料完整性" data-link-desc="從 SDK 到 storage 的資料損失地圖 — 每個環節的損失類型、控制策略、完整性指標、被自己 SDK DDoS 的防護">端到端資料完整性</a>。</p>
]]></content:encoded></item><item><title>Sampling</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/sampling/</link><pubDate>Wed, 24 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/sampling/</guid><description>&lt;p>取樣（sampling）的通用概念見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="說明觀測資料如何抽樣以控制成本並保留診斷能力">Backend 知識卡：Sampling&lt;/a> — 只保留部分觀測資料以控制成本。本卡聚焦監控 SDK 中的具體實作：在事件產生階段按比例丟棄部分事件，降低後續管線（buffer → transport → collector → storage）的負載。取樣是設計內的損失 — 取樣率是明確的 config 參數，損失量可預測。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure&lt;/a>（觸發動態取樣的訊號來源）和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rate-limiting/" data-link-title="Rate Limiting" data-link-desc="限制每個 client 在單位時間內可送出的事件數量 — 防止單一 SDK bug 或偽造流量消耗整個 collector 的處理能力">rate limiting&lt;/a>（collector 端的 per-client 限制）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Sampling 位在管線最上游（SDK 產生事件的階段），比 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure&lt;/a> 早一步 — backpressure 是下游滿載後回傳的訊號，動態取樣正是 SDK 收到這個訊號後的回應動作。靜態取樣則跟 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rate-limiting/" data-link-title="Rate Limiting" data-link-desc="限制每個 client 在單位時間內可送出的事件數量 — 防止單一 SDK bug 或偽造流量消耗整個 collector 的處理能力">rate limiting&lt;/a> 一樣是主動設定的固定策略，差別在取樣發生在事件產生端、rate limiting 發生在 collector 接收端。&lt;/p>
&lt;h2 id="兩種取樣">兩種取樣&lt;/h2>
&lt;p>&lt;strong>靜態取樣&lt;/strong>：SDK config 中設定固定比例（例如 metric 類 0.1 = 每 10 筆只收 1 筆），在 SDK 整個生命週期保持不變。適合已知高頻但單筆 debug 價值低的事件（render.frame_time、scroll.position）。&lt;/p>
&lt;p>&lt;strong>動態取樣&lt;/strong>：SDK 在收到 collector 的 HTTP 429 後自動降低取樣率，collector 恢復正常後逐步回升。動態取樣在正常情況下不生效（取樣率 = 1.0），只在 collector 過載時啟用。和靜態取樣互補 — 靜態控制基線負載，動態應對突發。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>分析時用取樣率還原原始量級。取樣率 0.1 時收到 100 筆事件，推估原始量為 100 / 0.1 = 1000 筆。SDK 端的 &lt;code>sdk.sampling.rate&lt;/code> 指標記錄當前取樣率，讓下游分析知道如何校正。&lt;/p>
&lt;h2 id="判讀方式">判讀方式&lt;/h2>
&lt;p>取樣校正對 funnel 和 cohort 分析有效（趨勢和比例不變），對個別事件追蹤無效（被丟棄的事件無法回復）。取樣承擔的設計責任是「在可觀測性覆蓋率和系統負載之間找到平衡」。Error 類事件不做取樣（每筆都可能是需要修的 bug），metric 類事件適合高比例取樣（丟幾筆不影響趨勢），event 類和 lifecycle 類取決於分析需求。&lt;/p>
&lt;h2 id="完整章節">完整章節&lt;/h2>
&lt;p>靜態取樣率的設定 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/03-sdk-design/sensor-lifecycle-management/" data-link-title="感測器生命週期管理" data-link-desc="產品生命週期的五個階段各啟用什麼感測器 — feature flag 整合、取樣率動態調整、感測器開關的可觀察性">感測器生命週期管理&lt;/a>。動態取樣在四層防線中的位置 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/04-collector/ingestion-scaling/" data-link-title="Ingestion Scaling" data-link-desc="四層防線應對 ingestion 端的流量擴展 — SDK 取樣、Collector 背壓、水平擴展、Queue 解耦">Ingestion Scaling&lt;/a>。取樣造成的損失量化和控制 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/04-collector/data-integrity/" data-link-title="端到端資料完整性" data-link-desc="從 SDK 到 storage 的資料損失地圖 — 每個環節的損失類型、控制策略、完整性指標、被自己 SDK DDoS 的防護">端到端資料完整性&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>取樣（sampling）的通用概念見 <a href="/blog/backend/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="說明觀測資料如何抽樣以控制成本並保留診斷能力">Backend 知識卡：Sampling</a> — 只保留部分觀測資料以控制成本。本卡聚焦監控 SDK 中的具體實作：在事件產生階段按比例丟棄部分事件，降低後續管線（buffer → transport → collector → storage）的負載。取樣是設計內的損失 — 取樣率是明確的 config 參數，損失量可預測。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure</a>（觸發動態取樣的訊號來源）和 <a href="/blog/devops/monitoring/knowledge-cards/rate-limiting/" data-link-title="Rate Limiting" data-link-desc="限制每個 client 在單位時間內可送出的事件數量 — 防止單一 SDK bug 或偽造流量消耗整個 collector 的處理能力">rate limiting</a>（collector 端的 per-client 限制）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Sampling 位在管線最上游（SDK 產生事件的階段），比 <a href="/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure</a> 早一步 — backpressure 是下游滿載後回傳的訊號，動態取樣正是 SDK 收到這個訊號後的回應動作。靜態取樣則跟 <a href="/blog/devops/monitoring/knowledge-cards/rate-limiting/" data-link-title="Rate Limiting" data-link-desc="限制每個 client 在單位時間內可送出的事件數量 — 防止單一 SDK bug 或偽造流量消耗整個 collector 的處理能力">rate limiting</a> 一樣是主動設定的固定策略，差別在取樣發生在事件產生端、rate limiting 發生在 collector 接收端。</p>
<h2 id="兩種取樣">兩種取樣</h2>
<p><strong>靜態取樣</strong>：SDK config 中設定固定比例（例如 metric 類 0.1 = 每 10 筆只收 1 筆），在 SDK 整個生命週期保持不變。適合已知高頻但單筆 debug 價值低的事件（render.frame_time、scroll.position）。</p>
<p><strong>動態取樣</strong>：SDK 在收到 collector 的 HTTP 429 後自動降低取樣率，collector 恢復正常後逐步回升。動態取樣在正常情況下不生效（取樣率 = 1.0），只在 collector 過載時啟用。和靜態取樣互補 — 靜態控制基線負載，動態應對突發。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>分析時用取樣率還原原始量級。取樣率 0.1 時收到 100 筆事件，推估原始量為 100 / 0.1 = 1000 筆。SDK 端的 <code>sdk.sampling.rate</code> 指標記錄當前取樣率，讓下游分析知道如何校正。</p>
<h2 id="判讀方式">判讀方式</h2>
<p>取樣校正對 funnel 和 cohort 分析有效（趨勢和比例不變），對個別事件追蹤無效（被丟棄的事件無法回復）。取樣承擔的設計責任是「在可觀測性覆蓋率和系統負載之間找到平衡」。Error 類事件不做取樣（每筆都可能是需要修的 bug），metric 類事件適合高比例取樣（丟幾筆不影響趨勢），event 類和 lifecycle 類取決於分析需求。</p>
<h2 id="完整章節">完整章節</h2>
<p>靜態取樣率的設定 → <a href="/blog/devops/monitoring/03-sdk-design/sensor-lifecycle-management/" data-link-title="感測器生命週期管理" data-link-desc="產品生命週期的五個階段各啟用什麼感測器 — feature flag 整合、取樣率動態調整、感測器開關的可觀察性">感測器生命週期管理</a>。動態取樣在四層防線中的位置 → <a href="/blog/devops/monitoring/04-collector/ingestion-scaling/" data-link-title="Ingestion Scaling" data-link-desc="四層防線應對 ingestion 端的流量擴展 — SDK 取樣、Collector 背壓、水平擴展、Queue 解耦">Ingestion Scaling</a>。取樣造成的損失量化和控制 → <a href="/blog/devops/monitoring/04-collector/data-integrity/" data-link-title="端到端資料完整性" data-link-desc="從 SDK 到 storage 的資料損失地圖 — 每個環節的損失類型、控制策略、完整性指標、被自己 SDK DDoS 的防護">端到端資料完整性</a>。</p>
]]></content:encoded></item><item><title>Rate Limiting</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rate-limiting/</link><pubDate>Wed, 24 Jun 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/rate-limiting/</guid><description>&lt;p>速率限制（rate limiting）的通用概念見 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/rate-limit/" data-link-title="Rate Limit" data-link-desc="說明限流如何保護服務入口、下游依賴與租戶公平性">Backend 知識卡：Rate Limit&lt;/a> — 限制某個主體在一段時間內可使用的資源量。本卡聚焦監控系統中的具體實作：限制每個 client（API key / source.app）在單位時間內可送出的事件數量，保護 collector 不被單一 SDK 的 bug（事件風暴）或偽造流量消耗處理能力。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure&lt;/a>（全域的容量訊號）和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">sampling&lt;/a>（SDK 端的主動降載）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Rate limiting 和 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure&lt;/a> 都限制流量，但保護的維度不同。Rate limiting 是 per-client 的配額機制 — 每個 API key 有獨立的速率上限，一個 client 超限不影響其他 client。Backpressure 是全域的容量訊號 — collector 的寫入 channel 滿時對所有 client 回 429，不區分來源。一個 client 的失控用 rate limiting 處理（隔離問題源），全域流量過大用 backpressure 處理（全體降速）。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Rate limiting 觸發的訊號是 collector 端對特定 API key 回 429 的次數上升、而其他 key 正常。典型場景：某個 SDK 版本有 bug 導致每秒產生 1000 筆事件 → per-key rate limiter 超過閾值 → 該 key 的後續 request 被回 429 → 其他 SDK 不受影響。&lt;/p>
&lt;h2 id="判讀方式">判讀方式&lt;/h2>
&lt;p>Rate limiting 承擔的設計責任是「在公平性和可用性之間取得平衡」。閾值設太低，正常的 burst flush（攢批後一次送出）會被誤觸；閾值設太高，失控的 SDK 要送很多筆才被擋。合理的閾值需高於正常 burst 的事件速率。&lt;/p>
&lt;h2 id="完整章節">完整章節&lt;/h2>
&lt;p>Per-SDK rate limiting 的實作 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/04-collector/ingestion-scaling/" data-link-title="Ingestion Scaling" data-link-desc="四層防線應對 ingestion 端的流量擴展 — SDK 取樣、Collector 背壓、水平擴展、Queue 解耦">Ingestion Scaling&lt;/a>。Rate limiting 在 collector access control 中的角色 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/07-security-privacy/collector-access-control/" data-link-title="Collector Access Control 實作" data-link-desc="認證（誰在送資料）/ 授權（允許送什麼）/ access log（誰在什麼時候送了什麼）— collector 端的三層存取控制">Collector Access Control 實作&lt;/a>。偽造流量場景下 rate limiting 和其他防護層的配合 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/07-security-privacy/client-sdk-authentication/" data-link-title="Client-side SDK 認證的根本限制" data-link-desc="嵌在 client 端的 credential 必然可被提取 — 認清 architecture 天花板後的多層緩解策略，從 origin 驗證到 device attestation">Client-side SDK 認證&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>速率限制（rate limiting）的通用概念見 <a href="/blog/backend/knowledge-cards/rate-limit/" data-link-title="Rate Limit" data-link-desc="說明限流如何保護服務入口、下游依賴與租戶公平性">Backend 知識卡：Rate Limit</a> — 限制某個主體在一段時間內可使用的資源量。本卡聚焦監控系統中的具體實作：限制每個 client（API key / source.app）在單位時間內可送出的事件數量，保護 collector 不被單一 SDK 的 bug（事件風暴）或偽造流量消耗處理能力。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure</a>（全域的容量訊號）和 <a href="/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">sampling</a>（SDK 端的主動降載）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Rate limiting 和 <a href="/blog/devops/monitoring/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="下游處理能力不足時向上游回傳「慢下來」訊號的流量控制機制 — 監控系統中 collector 用 HTTP 429 向 SDK 傳遞背壓">backpressure</a> 都限制流量，但保護的維度不同。Rate limiting 是 per-client 的配額機制 — 每個 API key 有獨立的速率上限，一個 client 超限不影響其他 client。Backpressure 是全域的容量訊號 — collector 的寫入 channel 滿時對所有 client 回 429，不區分來源。一個 client 的失控用 rate limiting 處理（隔離問題源），全域流量過大用 backpressure 處理（全體降速）。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Rate limiting 觸發的訊號是 collector 端對特定 API key 回 429 的次數上升、而其他 key 正常。典型場景：某個 SDK 版本有 bug 導致每秒產生 1000 筆事件 → per-key rate limiter 超過閾值 → 該 key 的後續 request 被回 429 → 其他 SDK 不受影響。</p>
<h2 id="判讀方式">判讀方式</h2>
<p>Rate limiting 承擔的設計責任是「在公平性和可用性之間取得平衡」。閾值設太低，正常的 burst flush（攢批後一次送出）會被誤觸；閾值設太高，失控的 SDK 要送很多筆才被擋。合理的閾值需高於正常 burst 的事件速率。</p>
<h2 id="完整章節">完整章節</h2>
<p>Per-SDK rate limiting 的實作 → <a href="/blog/devops/monitoring/04-collector/ingestion-scaling/" data-link-title="Ingestion Scaling" data-link-desc="四層防線應對 ingestion 端的流量擴展 — SDK 取樣、Collector 背壓、水平擴展、Queue 解耦">Ingestion Scaling</a>。Rate limiting 在 collector access control 中的角色 → <a href="/blog/devops/monitoring/07-security-privacy/collector-access-control/" data-link-title="Collector Access Control 實作" data-link-desc="認證（誰在送資料）/ 授權（允許送什麼）/ access log（誰在什麼時候送了什麼）— collector 端的三層存取控制">Collector Access Control 實作</a>。偽造流量場景下 rate limiting 和其他防護層的配合 → <a href="/blog/devops/monitoring/07-security-privacy/client-sdk-authentication/" data-link-title="Client-side SDK 認證的根本限制" data-link-desc="嵌在 client 端的 credential 必然可被提取 — 認清 architecture 天花板後的多層緩解策略，從 origin 驗證到 device attestation">Client-side SDK 認證</a>。</p>
]]></content:encoded></item><item><title>First-party Cookie（第一方 cookie）</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/first-party-cookie/</link><pubDate>Fri, 23 Oct 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/first-party-cookie/</guid><description>&lt;p>第一方 cookie（first-party cookie）是寫在使用者正在瀏覽的那個網站網域上的 cookie；寫在別的網域上、隨對那個網域的請求送出的，是第三方 cookie（third-party cookie）。歸屬只看 cookie 的網域，不看寫入它的 script 是誰的：Meta Pixel 與 GA4 的 script 從 Meta 與 Google 的網域載入，卻用 JavaScript 把識別碼寫在網站自己的網域上，所以 &lt;code>_fbp&lt;/code>、&lt;code>_fbc&lt;/code>、&lt;code>_ga&lt;/code> 都是第一方 cookie。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/headless-browser/" data-link-title="Headless Browser（無頭瀏覽器）" data-link-desc="用 Playwright 或 Puppeteer 測追蹤碼、分析報表裡的機器流量，或自建統計與商業追蹤碼的訪問數對不上時">Headless Browser（無頭瀏覽器）&lt;/a>（同一批追蹤碼在無頭模式下照樣寫 cookie、事件卻可能不送）與 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">Autocapture（自動事件收集）&lt;/a>（這些識別碼會隨自動事件一起送出）；識別碼與瀏覽器指紋的差別見 &lt;a href="https://tarrragon.github.io/blog/automation/knowledge-cards/browser-fingerprint/" data-link-title="Browser Fingerprint（瀏覽器指紋）" data-link-desc="由多個單獨無害的瀏覽器環境屬性組合而成的裝置特徵集合，決定自建統計蒐集判別訊號時的能力上限">Browser Fingerprint（瀏覽器指紋）&lt;/a>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>第一方 cookie 是追蹤碼在第三方 cookie 被瀏覽器限制之後保存識別碼的位置。第三方 cookie 由 vendor 的網域直接讀寫，第一方 cookie 寫在網站網域上，瀏覽器送往 vendor 網域的請求不會在 Cookie 標頭裡帶上網站網域的 cookie，所以追蹤碼在瀏覽器裡讀出它的值，放進事件請求的參數送出：在預設設定下（使用者沒有透過同意機制拒絕、追蹤碼的第一方 cookie 設定沒有關掉），Meta Pixel 的每一筆事件都帶 &lt;code>fbp&lt;/code> 參數，值就是 &lt;code>_fbp&lt;/code> 的內容；GA4 的 collect 請求帶 &lt;code>cid&lt;/code>，與 &lt;code>_ga&lt;/code> 值以點分隔的最後兩段數字相同。網站自己沒有呼叫的&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">自動事件&lt;/a>也帶著這些參數送出。&lt;/p>
&lt;h2 id="cookie-期限的設定者與瀏覽器上限">cookie 期限的設定者與瀏覽器上限&lt;/h2>
&lt;p>cookie 的到期時間由寫入它的 script 設定，再受瀏覽器的規則截斷。Chrome 從 104 版起把任何 cookie 的到期時間上限訂為 400 天，要求更久的 cookie 會被改成 400 天。Safari 的 Intelligent Tracking Prevention（ITP）對追蹤碼常用的寫法另有三條限制，依 WebKit 的追蹤防護說明頁：由 JavaScript 寫入的 cookie 與其他 script 寫得到的儲存資料（例如 localStorage），在使用者 7 天沒有與這個網站互動之後刪除（WebKit 先前的說明以使用 Safari 的天數計，現行說明頁沒有寫單位），重新起算的條件是互動、不是單純的造訪；ITP 偵測到網址帶著點擊 ID 這類參數（link decoration）時，落地頁上由 JavaScript 寫入的 cookie 期限上限是 24 小時（WebKit 先前的說明寫明的條件是：把使用者導過來的網域被分類為追蹤者，而且網址帶查詢字串或片段）；回應來自偽裝成第一方、實際指向第三方的伺服器（CNAME 或第三方 IP 偽裝）時，那個 HTTP 回應寫入的 cookie 期限上限是 7 天。所以同一個追蹤碼在不同瀏覽器上的 cookie 壽命不同：GA4 代碼替 &lt;code>_ga&lt;/code> 與 &lt;code>_ga_&amp;lt;評估 ID&amp;gt;&lt;/code> 設的預設期限是兩年，在 Chromium 上實測看到的 400 天是瀏覽器的上限，不是 GA4 的設定；從 Meta 廣告帶著 &lt;code>fbclid&lt;/code> 點進來的那一次，&lt;code>_fbc&lt;/code> 與 &lt;code>_fbp&lt;/code> 正好在落地頁上由 JavaScript 寫入，在 Safari 上可能只留一天。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>在開發者工具的 Application 面板（Chrome）或儲存空間面板（Firefox）查看網站網域底下的 cookie，看名稱、網域、到期時間與 &lt;code>HttpOnly&lt;/code> 欄位；由 JavaScript 寫入的 cookie 不能設 &lt;code>HttpOnly&lt;/code>，所以頁面上任何 script 都讀得到它。一次在 Chromium 上的實測裡，&lt;code>_fbp&lt;/code> 與 &lt;code>_fbc&lt;/code> 的到期時間是寫入起算 90 天，&lt;code>_ga&lt;/code> 與 &lt;code>_ga_&amp;lt;評估 ID&amp;gt;&lt;/code> 是 400 天，四個都不是 &lt;code>HttpOnly&lt;/code>、&lt;code>SameSite&lt;/code> 都是 &lt;code>Lax&lt;/code>；&lt;code>_fbc&lt;/code> 只有網址帶了廣告的&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/08-business-analytics/attribution/" data-link-title="Attribution" data-link-desc="使用者從哪來、哪個渠道帶來轉換 — last-touch / first-touch / multi-touch 歸因模型的差異和選擇">點擊 ID&lt;/a>（&lt;code>fbclid&lt;/code>）時才寫入。各 cookie 的值怎麼對應到事件參數，以 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求&lt;/a> 的結果檔為準。&lt;/p></description><content:encoded><![CDATA[<p>第一方 cookie（first-party cookie）是寫在使用者正在瀏覽的那個網站網域上的 cookie；寫在別的網域上、隨對那個網域的請求送出的，是第三方 cookie（third-party cookie）。歸屬只看 cookie 的網域，不看寫入它的 script 是誰的：Meta Pixel 與 GA4 的 script 從 Meta 與 Google 的網域載入，卻用 JavaScript 把識別碼寫在網站自己的網域上，所以 <code>_fbp</code>、<code>_fbc</code>、<code>_ga</code> 都是第一方 cookie。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/headless-browser/" data-link-title="Headless Browser（無頭瀏覽器）" data-link-desc="用 Playwright 或 Puppeteer 測追蹤碼、分析報表裡的機器流量，或自建統計與商業追蹤碼的訪問數對不上時">Headless Browser（無頭瀏覽器）</a>（同一批追蹤碼在無頭模式下照樣寫 cookie、事件卻可能不送）與 <a href="/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">Autocapture（自動事件收集）</a>（這些識別碼會隨自動事件一起送出）；識別碼與瀏覽器指紋的差別見 <a href="/blog/automation/knowledge-cards/browser-fingerprint/" data-link-title="Browser Fingerprint（瀏覽器指紋）" data-link-desc="由多個單獨無害的瀏覽器環境屬性組合而成的裝置特徵集合，決定自建統計蒐集判別訊號時的能力上限">Browser Fingerprint（瀏覽器指紋）</a>。</p>
<h2 id="概念位置">概念位置</h2>
<p>第一方 cookie 是追蹤碼在第三方 cookie 被瀏覽器限制之後保存識別碼的位置。第三方 cookie 由 vendor 的網域直接讀寫，第一方 cookie 寫在網站網域上，瀏覽器送往 vendor 網域的請求不會在 Cookie 標頭裡帶上網站網域的 cookie，所以追蹤碼在瀏覽器裡讀出它的值，放進事件請求的參數送出：在預設設定下（使用者沒有透過同意機制拒絕、追蹤碼的第一方 cookie 設定沒有關掉），Meta Pixel 的每一筆事件都帶 <code>fbp</code> 參數，值就是 <code>_fbp</code> 的內容；GA4 的 collect 請求帶 <code>cid</code>，與 <code>_ga</code> 值以點分隔的最後兩段數字相同。網站自己沒有呼叫的<a href="/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">自動事件</a>也帶著這些參數送出。</p>
<h2 id="cookie-期限的設定者與瀏覽器上限">cookie 期限的設定者與瀏覽器上限</h2>
<p>cookie 的到期時間由寫入它的 script 設定，再受瀏覽器的規則截斷。Chrome 從 104 版起把任何 cookie 的到期時間上限訂為 400 天，要求更久的 cookie 會被改成 400 天。Safari 的 Intelligent Tracking Prevention（ITP）對追蹤碼常用的寫法另有三條限制，依 WebKit 的追蹤防護說明頁：由 JavaScript 寫入的 cookie 與其他 script 寫得到的儲存資料（例如 localStorage），在使用者 7 天沒有與這個網站互動之後刪除（WebKit 先前的說明以使用 Safari 的天數計，現行說明頁沒有寫單位），重新起算的條件是互動、不是單純的造訪；ITP 偵測到網址帶著點擊 ID 這類參數（link decoration）時，落地頁上由 JavaScript 寫入的 cookie 期限上限是 24 小時（WebKit 先前的說明寫明的條件是：把使用者導過來的網域被分類為追蹤者，而且網址帶查詢字串或片段）；回應來自偽裝成第一方、實際指向第三方的伺服器（CNAME 或第三方 IP 偽裝）時，那個 HTTP 回應寫入的 cookie 期限上限是 7 天。所以同一個追蹤碼在不同瀏覽器上的 cookie 壽命不同：GA4 代碼替 <code>_ga</code> 與 <code>_ga_&lt;評估 ID&gt;</code> 設的預設期限是兩年，在 Chromium 上實測看到的 400 天是瀏覽器的上限，不是 GA4 的設定；從 Meta 廣告帶著 <code>fbclid</code> 點進來的那一次，<code>_fbc</code> 與 <code>_fbp</code> 正好在落地頁上由 JavaScript 寫入，在 Safari 上可能只留一天。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>在開發者工具的 Application 面板（Chrome）或儲存空間面板（Firefox）查看網站網域底下的 cookie，看名稱、網域、到期時間與 <code>HttpOnly</code> 欄位；由 JavaScript 寫入的 cookie 不能設 <code>HttpOnly</code>，所以頁面上任何 script 都讀得到它。一次在 Chromium 上的實測裡，<code>_fbp</code> 與 <code>_fbc</code> 的到期時間是寫入起算 90 天，<code>_ga</code> 與 <code>_ga_&lt;評估 ID&gt;</code> 是 400 天，四個都不是 <code>HttpOnly</code>、<code>SameSite</code> 都是 <code>Lax</code>；<code>_fbc</code> 只有網址帶了廣告的<a href="/blog/devops/monitoring/08-business-analytics/attribution/" data-link-title="Attribution" data-link-desc="使用者從哪來、哪個渠道帶來轉換 — last-touch / first-touch / multi-touch 歸因模型的差異和選擇">點擊 ID</a>（<code>fbclid</code>）時才寫入。各 cookie 的值怎麼對應到事件參數，以 <a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a> 的結果檔為準。</p>
<h2 id="判讀方式">判讀方式</h2>
<p>一個 cookie 受哪些限制，取決於兩個屬性：它寫在哪個網域，以及它由 JavaScript 寫入還是由伺服器回應的 <code>Set-Cookie</code> 標頭寫入。寫入方式可以在 Network 面板分辨：某個回應的 <code>Set-Cookie</code> 標頭帶著這個名稱，就是伺服器寫的；所有回應都沒有、而它在 script 執行之後出現，就是 JavaScript 寫的。網域決定瀏覽器的第三方 cookie 封鎖管不管得到它，封鎖第三方 cookie 不影響第一方 cookie；寫入方式（連同回應來自誰的伺服器）決定 ITP 的哪一條限制管得到它，JavaScript 寫入的第一方 cookie 仍然受 ITP 限制，所以同一個人隔一週以上沒有互動、或從廣告點進來隔天才回來時，可能被追蹤碼當成另一個瀏覽器。用 Network 面板分辨寫入方式時，要用無痕視窗或先清掉這個網站的 cookie、在載入頁面之前就打開面板，否則前一次造訪留下的 cookie 會被誤判成 JavaScript 寫的。在歐盟 ePrivacy 指令下（第 5(3) 條，本站的解讀見<a href="/blog/automation/05-deploy-quota-security/quota-abuse-privacy/" data-link-title="配額、濫用防護、隱私與遷移訊號" data-link-desc="免費配額實際碰撞時會怎樣、擋髒資料與過濾自己瀏覽的做法、不記 PII 的隱私立場、以及量大到該離開 Sheets 的訊號">配額、濫用防護、隱私與遷移訊號</a>的〈隱私與 PII 邊界〉），判斷是否要取得使用者同意時，看的是「在使用者的裝置上儲存或讀取資訊」這個動作，第一方或第三方都在範圍內；把識別碼寫成第一方 cookie 改變的是瀏覽器的限制，改變不了這條同意的要求。</p>
<h2 id="完整章節">完整章節</h2>
<p>追蹤碼寫下哪些 cookie、值怎麼對應到事件參數 → <a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a>。<code>_fbp</code>、<code>_fbc</code> 在伺服器端事件裡的用途與 ITP 造成的損失 → <a href="/blog/devops/monitoring/vendors/meta-pixel-conversions-api/" data-link-title="Meta Pixel 與 Conversions API：廣告平台轉換追蹤的瀏覽器端與伺服器端" data-link-desc="Meta Pixel 在頁面上送出的標準事件與它的資料消費者、瀏覽器端事件被攔截的路徑、Conversions API 從伺服器補送同一批事件的必填欄位，以及兩路並送時以 event_id 去重與用 Test Events 驗證的方式">Meta Pixel 與 Conversions API</a>。cookie 期限在儲存限制裡的位置 → <a href="/blog/devops/monitoring/07-security-privacy/gdpr-minimization/" data-link-title="GDPR 最小化原則的工程落地" data-link-desc="資料最小化、目的限制、儲存限制 — GDPR 三個核心原則在監控系統的工程實作方式">GDPR 最小化原則的工程落地</a>。</p>
]]></content:encoded></item><item><title>Headless Browser（無頭瀏覽器）</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/headless-browser/</link><pubDate>Fri, 23 Oct 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/headless-browser/</guid><description>&lt;p>無頭瀏覽器（headless browser）是不開啟可見視窗的瀏覽器：頁面照常載入、JavaScript 照常執行，只是畫面不顯示出來。無頭與被程式驅動是兩個獨立的屬性：有視窗的瀏覽器同樣可以被程式驅動，命令列直接執行 &lt;code>chrome --headless&lt;/code> 輸出截圖也不經過任何自動化框架；Playwright、Puppeteer 這類自動化工具則多半同時具備兩者，預設就以無頭模式啟動 Chromium。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/first-party-cookie/" data-link-title="First-party Cookie（第一方 cookie）" data-link-desc="盤點網站寫下的識別碼 cookie、比對追蹤碼的 cookie 期限，或判斷某個 cookie 受不受瀏覽器的第三方 cookie 限制時">First-party Cookie（第一方 cookie）&lt;/a>（無頭模式下追蹤碼照樣寫 cookie）與 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">Autocapture（自動事件收集）&lt;/a>（網站沒有呼叫的事件由誰決定送出）；把無頭瀏覽器當成要辨識的訪客時的訊號設計，見 &lt;a href="https://tarrragon.github.io/blog/automation/06-reading-the-data/automated-traffic/" data-link-title="辨識自動化流量" data-link-desc="接收端讀不到 HTTP 標頭時在前端蒐集訊號分辨機器與真人；多數 AI 訓練爬蟲不執行 JavaScript，因此不會出現在這份統計裡">辨識自動化流量&lt;/a>；不靠 User-Agent、改從瀏覽器環境辨識自動化的做法，見 &lt;a href="https://tarrragon.github.io/blog/automation/knowledge-cards/browser-fingerprint/" data-link-title="Browser Fingerprint（瀏覽器指紋）" data-link-desc="由多個單獨無害的瀏覽器環境屬性組合而成的裝置特徵集合，決定自建統計蒐集判別訊號時的能力上限">Browser Fingerprint（瀏覽器指紋）&lt;/a>。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>無頭模式改變的是瀏覽器自己對外暴露的特徵，追蹤碼在訪客的瀏覽器裡、收資料的伺服器在 vendor 那一端，都可能依這些特徵決定事件送不送出、收不收下。最直接的特徵是 User-Agent（瀏覽器在每個請求裡附上的身分字串）：一次以 Playwright 預設無頭模式啟動 Chromium 的實測裡，User-Agent 帶 &lt;code>HeadlessChrome&lt;/code> 字樣，有視窗模式下是一般的 &lt;code>Chrome&lt;/code>。被程式驅動則另有自己的特徵，&lt;code>navigator.webdriver&lt;/code> 在 Playwright、Puppeteer、Selenium 驅動的瀏覽器裡是 &lt;code>true&lt;/code>，有沒有視窗都一樣。所以「擋無頭瀏覽器」與「擋自動化」是兩條不同的規則：比對 &lt;code>HeadlessChrome&lt;/code> 字樣的規則換成有視窗模式就不命中，比對 &lt;code>navigator.webdriver&lt;/code> 的規則兩種模式都命中。被攔下的事件裡也包括網站沒有呼叫的&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">自動事件&lt;/a>，它們走的是同一條送出路徑。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>本站用 Playwright 寫的擷取腳本（&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求&lt;/a>）在實測頁上載入本站測試用的一個 Meta Pixel。&lt;code>fbevents.js&lt;/code> 載入後會向 Meta 取得這個 Pixel 的設定檔，設定檔指定要載入的模組（plugin）裡有一個 &lt;code>botblocking&lt;/code>，它拿 &lt;code>navigator.userAgent&lt;/code> 比對一份含 &lt;code>HeadlessChrome/&lt;/code> 的機器人規則清單。無頭模式下 &lt;code>fbevents.js&lt;/code> 照樣載入、&lt;code>_fbp&lt;/code> 照樣寫入，而 PageView、ViewContent、Purchase 一筆都沒有送出；腳本改用有視窗模式之後，三筆事件都送出了。這個模組只攔事件請求，script 的載入與&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/first-party-cookie/" data-link-title="First-party Cookie（第一方 cookie）" data-link-desc="盤點網站寫下的識別碼 cookie、比對追蹤碼的 cookie 期限，或判斷某個 cookie 受不受瀏覽器的第三方 cookie 限制時">第一方 cookie&lt;/a> 的寫入不受影響，頁面上的狀態訊息在兩種模式下也相同，從頁面上看不出事件沒送。GA4 的 collect 請求在無頭模式下照樣送出並收到回應；GA4 在接收端預設排除已知機器人流量，依據是 Google 的研究與 IAB（Interactive Advertising Bureau，網路廣告業的產業組織）的機器人清單，被排除了多少不會顯示，所以從擷取結果判斷不出無頭模式的事件是否進了報表。&lt;/p>
&lt;h2 id="判讀方式">判讀方式&lt;/h2>
&lt;p>兩次擷取用同一個 Pixel、在相近的時間、做相同的操作、只切換有沒有視窗時，兩種模式的結果差異量的是追蹤碼對無頭特徵的反應：有視窗模式下送得出、無頭模式下送不出的事件，是被比對 User-Agent 這類無頭特徵的規則攔下的。兩次之間隔得久，Pixel 的設定檔可能已經改版，差異就不能只歸給無頭模式。有視窗模式的 Playwright 仍然是被程式驅動的瀏覽器（&lt;code>navigator.webdriver&lt;/code> 為真），所以它的結果不等於真人訪客的結果；追蹤碼改成依 &lt;code>navigator.webdriver&lt;/code> 判斷時，有視窗模式也會被攔。比對自建統計與商業追蹤碼的訪問數時，差額裡可能有一部分是無頭瀏覽器的訪問：自建統計的接收端收下並標成機器流量，Meta Pixel 在瀏覽器裡就丟掉。反過來，GA4 的代碼在無頭模式下照常送出事件，所以拿正式網站的評估 ID 或 Pixel ID 跑自動化測試，事件會送進正式的資源，進不進報表由 Google 的已知機器人排除判定，而排除了多少看不到；擷取與測試用測試專用的帳戶與 ID，做法見&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求&lt;/a>的〈擷取用的測試帳號〉。&lt;/p>
&lt;h2 id="完整章節">完整章節&lt;/h2>
&lt;p>無頭與有視窗兩種模式下 Meta Pixel 實際送出的請求、&lt;code>botblocking&lt;/code> 的機制與擷取紀錄要記下的模式 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求&lt;/a>。自建統計怎麼用 User-Agent、&lt;code>navigator.webdriver&lt;/code> 等訊號標記機器流量 → &lt;a href="https://tarrragon.github.io/blog/automation/06-reading-the-data/automated-traffic/" data-link-title="辨識自動化流量" data-link-desc="接收端讀不到 HTTP 標頭時在前端蒐集訊號分辨機器與真人；多數 AI 訓練爬蟲不執行 JavaScript，因此不會出現在這份統計裡">辨識自動化流量&lt;/a>。GA4 預設的已知機器人排除與主機名稱篩選器 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/07-security-privacy/client-sdk-authentication/" data-link-title="Client-side SDK 認證的根本限制" data-link-desc="嵌在 client 端的 credential 必然可被提取 — 認清 architecture 天花板後的多層緩解策略，從 origin 驗證到 device attestation">Client-side SDK 認證的根本限制&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>無頭瀏覽器（headless browser）是不開啟可見視窗的瀏覽器：頁面照常載入、JavaScript 照常執行，只是畫面不顯示出來。無頭與被程式驅動是兩個獨立的屬性：有視窗的瀏覽器同樣可以被程式驅動，命令列直接執行 <code>chrome --headless</code> 輸出截圖也不經過任何自動化框架；Playwright、Puppeteer 這類自動化工具則多半同時具備兩者，預設就以無頭模式啟動 Chromium。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/first-party-cookie/" data-link-title="First-party Cookie（第一方 cookie）" data-link-desc="盤點網站寫下的識別碼 cookie、比對追蹤碼的 cookie 期限，或判斷某個 cookie 受不受瀏覽器的第三方 cookie 限制時">First-party Cookie（第一方 cookie）</a>（無頭模式下追蹤碼照樣寫 cookie）與 <a href="/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">Autocapture（自動事件收集）</a>（網站沒有呼叫的事件由誰決定送出）；把無頭瀏覽器當成要辨識的訪客時的訊號設計，見 <a href="/blog/automation/06-reading-the-data/automated-traffic/" data-link-title="辨識自動化流量" data-link-desc="接收端讀不到 HTTP 標頭時在前端蒐集訊號分辨機器與真人；多數 AI 訓練爬蟲不執行 JavaScript，因此不會出現在這份統計裡">辨識自動化流量</a>；不靠 User-Agent、改從瀏覽器環境辨識自動化的做法，見 <a href="/blog/automation/knowledge-cards/browser-fingerprint/" data-link-title="Browser Fingerprint（瀏覽器指紋）" data-link-desc="由多個單獨無害的瀏覽器環境屬性組合而成的裝置特徵集合，決定自建統計蒐集判別訊號時的能力上限">Browser Fingerprint（瀏覽器指紋）</a>。</p>
<h2 id="概念位置">概念位置</h2>
<p>無頭模式改變的是瀏覽器自己對外暴露的特徵，追蹤碼在訪客的瀏覽器裡、收資料的伺服器在 vendor 那一端，都可能依這些特徵決定事件送不送出、收不收下。最直接的特徵是 User-Agent（瀏覽器在每個請求裡附上的身分字串）：一次以 Playwright 預設無頭模式啟動 Chromium 的實測裡，User-Agent 帶 <code>HeadlessChrome</code> 字樣，有視窗模式下是一般的 <code>Chrome</code>。被程式驅動則另有自己的特徵，<code>navigator.webdriver</code> 在 Playwright、Puppeteer、Selenium 驅動的瀏覽器裡是 <code>true</code>，有沒有視窗都一樣。所以「擋無頭瀏覽器」與「擋自動化」是兩條不同的規則：比對 <code>HeadlessChrome</code> 字樣的規則換成有視窗模式就不命中，比對 <code>navigator.webdriver</code> 的規則兩種模式都命中。被攔下的事件裡也包括網站沒有呼叫的<a href="/blog/devops/monitoring/knowledge-cards/autocapture/" data-link-title="Autocapture（自動事件收集）" data-link-desc="盤點網站實際送出哪些事件與內容、報表裡出現網站沒有呼叫過的事件，或在手動埋點與自動收集之間取捨時">自動事件</a>，它們走的是同一條送出路徑。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>本站用 Playwright 寫的擷取腳本（<a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a>）在實測頁上載入本站測試用的一個 Meta Pixel。<code>fbevents.js</code> 載入後會向 Meta 取得這個 Pixel 的設定檔，設定檔指定要載入的模組（plugin）裡有一個 <code>botblocking</code>，它拿 <code>navigator.userAgent</code> 比對一份含 <code>HeadlessChrome/</code> 的機器人規則清單。無頭模式下 <code>fbevents.js</code> 照樣載入、<code>_fbp</code> 照樣寫入，而 PageView、ViewContent、Purchase 一筆都沒有送出；腳本改用有視窗模式之後，三筆事件都送出了。這個模組只攔事件請求，script 的載入與<a href="/blog/devops/monitoring/knowledge-cards/first-party-cookie/" data-link-title="First-party Cookie（第一方 cookie）" data-link-desc="盤點網站寫下的識別碼 cookie、比對追蹤碼的 cookie 期限，或判斷某個 cookie 受不受瀏覽器的第三方 cookie 限制時">第一方 cookie</a> 的寫入不受影響，頁面上的狀態訊息在兩種模式下也相同，從頁面上看不出事件沒送。GA4 的 collect 請求在無頭模式下照樣送出並收到回應；GA4 在接收端預設排除已知機器人流量，依據是 Google 的研究與 IAB（Interactive Advertising Bureau，網路廣告業的產業組織）的機器人清單，被排除了多少不會顯示，所以從擷取結果判斷不出無頭模式的事件是否進了報表。</p>
<h2 id="判讀方式">判讀方式</h2>
<p>兩次擷取用同一個 Pixel、在相近的時間、做相同的操作、只切換有沒有視窗時，兩種模式的結果差異量的是追蹤碼對無頭特徵的反應：有視窗模式下送得出、無頭模式下送不出的事件，是被比對 User-Agent 這類無頭特徵的規則攔下的。兩次之間隔得久，Pixel 的設定檔可能已經改版，差異就不能只歸給無頭模式。有視窗模式的 Playwright 仍然是被程式驅動的瀏覽器（<code>navigator.webdriver</code> 為真），所以它的結果不等於真人訪客的結果；追蹤碼改成依 <code>navigator.webdriver</code> 判斷時，有視窗模式也會被攔。比對自建統計與商業追蹤碼的訪問數時，差額裡可能有一部分是無頭瀏覽器的訪問：自建統計的接收端收下並標成機器流量，Meta Pixel 在瀏覽器裡就丟掉。反過來，GA4 的代碼在無頭模式下照常送出事件，所以拿正式網站的評估 ID 或 Pixel ID 跑自動化測試，事件會送進正式的資源，進不進報表由 Google 的已知機器人排除判定，而排除了多少看不到；擷取與測試用測試專用的帳戶與 ID，做法見<a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a>的〈擷取用的測試帳號〉。</p>
<h2 id="完整章節">完整章節</h2>
<p>無頭與有視窗兩種模式下 Meta Pixel 實際送出的請求、<code>botblocking</code> 的機制與擷取紀錄要記下的模式 → <a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a>。自建統計怎麼用 User-Agent、<code>navigator.webdriver</code> 等訊號標記機器流量 → <a href="/blog/automation/06-reading-the-data/automated-traffic/" data-link-title="辨識自動化流量" data-link-desc="接收端讀不到 HTTP 標頭時在前端蒐集訊號分辨機器與真人；多數 AI 訓練爬蟲不執行 JavaScript，因此不會出現在這份統計裡">辨識自動化流量</a>。GA4 預設的已知機器人排除與主機名稱篩選器 → <a href="/blog/devops/monitoring/07-security-privacy/client-sdk-authentication/" data-link-title="Client-side SDK 認證的根本限制" data-link-desc="嵌在 client 端的 credential 必然可被提取 — 認清 architecture 天花板後的多層緩解策略，從 origin 驗證到 device attestation">Client-side SDK 認證的根本限制</a>。</p>
]]></content:encoded></item><item><title>Autocapture（自動事件收集）</title><link>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/</link><pubDate>Fri, 23 Oct 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/autocapture/</guid><description>&lt;p>自動事件收集（autocapture）是由追蹤碼自己決定送出哪些事件、網站不必逐一呼叫的做法：script 在頁面上監聽點擊、捲動、表單這類互動，或在頁面載入、工作階段開始這類時點，依 vendor 的規則產生事件並送出。涵蓋哪些互動由 vendor 的規則決定，不是頁面上的每一個互動都會送。相對的做法是手動埋點：開發者在要追蹤的元素或事件處自己寫追蹤程式（標上屬性或呼叫追蹤函式），只有這些互動才會送出。可先對照 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/first-party-cookie/" data-link-title="First-party Cookie（第一方 cookie）" data-link-desc="盤點網站寫下的識別碼 cookie、比對追蹤碼的 cookie 期限，或判斷某個 cookie 受不受瀏覽器的第三方 cookie 限制時">First-party Cookie（第一方 cookie）&lt;/a>（自動事件同樣帶著識別碼 cookie 的值送出）與 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/headless-browser/" data-link-title="Headless Browser（無頭瀏覽器）" data-link-desc="用 Playwright 或 Puppeteer 測追蹤碼、分析報表裡的機器流量，或自建統計與商業追蹤碼的訪問數對不上時">Headless Browser（無頭瀏覽器）&lt;/a>（瀏覽器裡的機器人過濾對自動事件一樣生效）。自建 SDK 在事件送出前遮蔽欄位的做法見 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">Redaction&lt;/a>；商業追蹤碼的自動事件由 vendor 的 script 直接送出，不經過網站自建 SDK 的遮蔽步驟，網站能用的是 vendor 自己提供的設定：GA4 在網頁資料串流上有資料遮蔽（data redaction），在瀏覽器裡、資料送出之前遮掉事件參數裡的 email 與指定的網址查詢參數；Meta Pixel 能做的是關閉自動事件（做法在本卡〈概念位置〉的 Meta Pixel 段）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>自動事件收集決定的是「事件從哪裡來」，位置在事件產生的那一端，比管線上的&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">取樣&lt;/a>與&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">遮蔽&lt;/a>都早：事件的欄位由 vendor 的規則決定，網站要等它送出之後才看得到內容。它與本站自建 SDK 的&lt;a href="https://tarrragon.github.io/blog/devops/monitoring/03-sdk-design/auto-intercept/" data-link-title="自動攔截機制" data-link-desc="JS window.onerror / Flutter FlutterError.onError / Python sys.excepthook — 各平台攔截未捕獲例外的機制和限制">自動攔截機制&lt;/a>（auto-intercept）同樣不需要開發者為每個事件寫程式，分辨兩者的依據是送出規則由誰持有：自動攔截的規則寫在網站自己的 SDK 程式碼裡，自動事件收集的規則由 vendor 決定，網站的原始碼裡看不到。名稱各家不同：Meta 把這類事件叫自動事件（automatic events），GA4 叫自動收集的事件（automatically collected events），本站把兩者統稱為自動事件。兩家的範圍與開關也不同。&lt;/p>
&lt;p>&lt;strong>Meta Pixel&lt;/strong> 的自動事件由 Pixel 的設定檔指定的模組產生：&lt;code>fbevents.js&lt;/code> 載入後會向 Meta 取得這個 Pixel 的設定檔，設定檔決定要載入哪些模組（plugin，見 &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/meta-pixel-conversions-api/" data-link-title="Meta Pixel 與 Conversions API：廣告平台轉換追蹤的瀏覽器端與伺服器端" data-link-desc="Meta Pixel 在頁面上送出的標準事件與它的資料消費者、瀏覽器端事件被攔截的路徑、Conversions API 從伺服器補送同一批事件的必填欄位，以及兩路並送時以 event_id 去重與用 Test Events 驗證的方式">Meta Pixel 與 Conversions API&lt;/a> 的〈Meta Pixel 在瀏覽器裡做的事〉）。實測時每按一次頁面上的按鈕，&lt;code>fbevents.js&lt;/code> 都在網站呼叫的事件之外多送一筆 &lt;code>SubscribedButtonClick&lt;/code>，內容包含按鈕文字（&lt;code>cd[buttonText]&lt;/code>）、按鈕的 DOM 特徵與頁面特徵；設定檔來自 Meta 的伺服器，所以送出哪些自動事件由 Meta 那一端的設定決定，網站的原始碼裡看不到。要關掉 Pixel 依按鈕點擊與頁面中繼資料自動送出的事件，Meta 的開發者文件給的做法是在 Pixel 基本碼裡、&lt;code>fbq('init', …)&lt;/code> 之前加一行 &lt;code>fbq('set', 'autoConfig', false, '&amp;lt;Pixel ID&amp;gt;')&lt;/code>，&lt;code>&amp;lt;Pixel ID&amp;gt;&lt;/code> 換成自己的 Pixel ID。&lt;/p>
&lt;p>&lt;strong>GA4&lt;/strong> 的自動收集事件分成只要裝了 Google 代碼就會送的基本事件，例如 &lt;code>first_visit&lt;/code>、&lt;code>session_start&lt;/code>、&lt;code>user_engagement&lt;/code>，以及由加強型評估（enhanced measurement）控制的事件。加強型評估是網頁資料串流（GA4 資源裡代表一個網站資料來源的設定單位）上的一組開關，涵蓋捲動、外連點擊、站內搜尋、影片互動、檔案下載與表單互動，其中檔案下載會帶連結文字（&lt;code>link_text&lt;/code>）、表單送出會帶送出按鈕的文字。&lt;code>page_view&lt;/code> 也列在加強型評估底下，而它是其中唯一關不掉的一項。這組開關在 GA4 管理介面的資料串流設定裡，需要編輯者以上的權限。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>自動事件在請求裡的樣子與網站自己呼叫的事件相同，差別只在網站的程式碼裡找不到對應的呼叫。Meta 的事件請求送到 &lt;code>www.facebook.com/tr/&lt;/code>，事件名稱在 &lt;code>ev&lt;/code> 參數；GA4 的事件請求送到 Google Analytics 網域下的 &lt;code>g/collect&lt;/code>（在開發者工具的 Network 面板以 &lt;code>collect&lt;/code> 篩選），事件名稱在 &lt;code>en&lt;/code> 參數。一次 Meta Pixel 的實測裡，網站呼叫了 ViewContent 與 Purchase 各一次，擷取結果裡多出兩筆 &lt;code>SubscribedButtonClick&lt;/code>，各自緊跟在一次按鈕點擊之後。&lt;/p>
&lt;h2 id="判讀方式">判讀方式&lt;/h2>
&lt;p>網站原始碼只列得出手動埋點的那一部分，網站實際送出的資料要從送出的請求裡數；按鈕文字、連結文字這類欄位也在送出範圍內，按鈕或連結上顯示了使用者的個人資料時，那段文字會一起送到 vendor。兩種埋點方式的取捨方向相反：手動埋點會漏掉沒有寫追蹤程式的互動，換到的是送出的欄位全部由開發者決定；自動收集不需要逐一標記，而涵蓋哪些互動、送出哪些欄位由 vendor 的規則決定、會隨 vendor 改版變動。vendor 改版不會通知網站，所以送出資料的盤點要定期重做；Meta Pixel 的 &lt;code>fbevents.js&lt;/code> 版本可以在頁面的開發者工具 Console 輸入 &lt;code>fbq.version&lt;/code> 讀出，但自動事件由每個 Pixel 的設定檔決定，設定檔或事件管理工具裡的設定改了，&lt;code>fbq.version&lt;/code> 不會變，所以版本相同不代表送出的內容沒變，盤點仍要看實際送出的請求。&lt;/p>
&lt;h2 id="完整章節">完整章節&lt;/h2>
&lt;p>Meta Pixel 自動加送的事件與它的欄位 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求&lt;/a>的〈各次擷取的結果〉。以 &lt;code>data-track&lt;/code> 屬性手動埋點的感測器設計，與它和自動收集的對照 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/03-sdk-design/frontend-sensor-design/" data-link-title="前端感測器設計" data-link-desc="什麼行為值得埋感測器、每類感測器的實作方式、取樣策略和效能影響 — 和 auto-intercept 的被動攔截互補">前端感測器設計&lt;/a>。設定檔指定的模組怎麼在網站沒呼叫時自己送事件 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/meta-pixel-conversions-api/" data-link-title="Meta Pixel 與 Conversions API：廣告平台轉換追蹤的瀏覽器端與伺服器端" data-link-desc="Meta Pixel 在頁面上送出的標準事件與它的資料消費者、瀏覽器端事件被攔截的路徑、Conversions API 從伺服器補送同一批事件的必填欄位，以及兩路並送時以 event_id 去重與用 Test Events 驗證的方式">Meta Pixel 與 Conversions API&lt;/a> 的〈Meta Pixel 在瀏覽器裡做的事〉；同一類模組依 User-Agent 攔下事件的機制 → &lt;a href="https://tarrragon.github.io/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求&lt;/a>的〈擷取方式〉。&lt;/p></description><content:encoded><![CDATA[<p>自動事件收集（autocapture）是由追蹤碼自己決定送出哪些事件、網站不必逐一呼叫的做法：script 在頁面上監聽點擊、捲動、表單這類互動，或在頁面載入、工作階段開始這類時點，依 vendor 的規則產生事件並送出。涵蓋哪些互動由 vendor 的規則決定，不是頁面上的每一個互動都會送。相對的做法是手動埋點：開發者在要追蹤的元素或事件處自己寫追蹤程式（標上屬性或呼叫追蹤函式），只有這些互動才會送出。可先對照 <a href="/blog/devops/monitoring/knowledge-cards/first-party-cookie/" data-link-title="First-party Cookie（第一方 cookie）" data-link-desc="盤點網站寫下的識別碼 cookie、比對追蹤碼的 cookie 期限，或判斷某個 cookie 受不受瀏覽器的第三方 cookie 限制時">First-party Cookie（第一方 cookie）</a>（自動事件同樣帶著識別碼 cookie 的值送出）與 <a href="/blog/devops/monitoring/knowledge-cards/headless-browser/" data-link-title="Headless Browser（無頭瀏覽器）" data-link-desc="用 Playwright 或 Puppeteer 測追蹤碼、分析報表裡的機器流量，或自建統計與商業追蹤碼的訪問數對不上時">Headless Browser（無頭瀏覽器）</a>（瀏覽器裡的機器人過濾對自動事件一樣生效）。自建 SDK 在事件送出前遮蔽欄位的做法見 <a href="/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">Redaction</a>；商業追蹤碼的自動事件由 vendor 的 script 直接送出，不經過網站自建 SDK 的遮蔽步驟，網站能用的是 vendor 自己提供的設定：GA4 在網頁資料串流上有資料遮蔽（data redaction），在瀏覽器裡、資料送出之前遮掉事件參數裡的 email 與指定的網址查詢參數；Meta Pixel 能做的是關閉自動事件（做法在本卡〈概念位置〉的 Meta Pixel 段）。</p>
<h2 id="概念位置">概念位置</h2>
<p>自動事件收集決定的是「事件從哪裡來」，位置在事件產生的那一端，比管線上的<a href="/blog/devops/monitoring/knowledge-cards/sampling/" data-link-title="Sampling" data-link-desc="在事件產生階段按比例丟棄部分事件降低管線負載 — 分靜態取樣（config 固定比例）和動態取樣（背壓觸發自動降低）">取樣</a>與<a href="/blog/devops/monitoring/knowledge-cards/redaction/" data-link-title="Redaction" data-link-desc="說明在事件資料離開 client 之前把敏感欄位的值替換成遮罩或移除的機制">遮蔽</a>都早：事件的欄位由 vendor 的規則決定，網站要等它送出之後才看得到內容。它與本站自建 SDK 的<a href="/blog/devops/monitoring/03-sdk-design/auto-intercept/" data-link-title="自動攔截機制" data-link-desc="JS window.onerror / Flutter FlutterError.onError / Python sys.excepthook — 各平台攔截未捕獲例外的機制和限制">自動攔截機制</a>（auto-intercept）同樣不需要開發者為每個事件寫程式，分辨兩者的依據是送出規則由誰持有：自動攔截的規則寫在網站自己的 SDK 程式碼裡，自動事件收集的規則由 vendor 決定，網站的原始碼裡看不到。名稱各家不同：Meta 把這類事件叫自動事件（automatic events），GA4 叫自動收集的事件（automatically collected events），本站把兩者統稱為自動事件。兩家的範圍與開關也不同。</p>
<p><strong>Meta Pixel</strong> 的自動事件由 Pixel 的設定檔指定的模組產生：<code>fbevents.js</code> 載入後會向 Meta 取得這個 Pixel 的設定檔，設定檔決定要載入哪些模組（plugin，見 <a href="/blog/devops/monitoring/vendors/meta-pixel-conversions-api/" data-link-title="Meta Pixel 與 Conversions API：廣告平台轉換追蹤的瀏覽器端與伺服器端" data-link-desc="Meta Pixel 在頁面上送出的標準事件與它的資料消費者、瀏覽器端事件被攔截的路徑、Conversions API 從伺服器補送同一批事件的必填欄位，以及兩路並送時以 event_id 去重與用 Test Events 驗證的方式">Meta Pixel 與 Conversions API</a> 的〈Meta Pixel 在瀏覽器裡做的事〉）。實測時每按一次頁面上的按鈕，<code>fbevents.js</code> 都在網站呼叫的事件之外多送一筆 <code>SubscribedButtonClick</code>，內容包含按鈕文字（<code>cd[buttonText]</code>）、按鈕的 DOM 特徵與頁面特徵；設定檔來自 Meta 的伺服器，所以送出哪些自動事件由 Meta 那一端的設定決定，網站的原始碼裡看不到。要關掉 Pixel 依按鈕點擊與頁面中繼資料自動送出的事件，Meta 的開發者文件給的做法是在 Pixel 基本碼裡、<code>fbq('init', …)</code> 之前加一行 <code>fbq('set', 'autoConfig', false, '&lt;Pixel ID&gt;')</code>，<code>&lt;Pixel ID&gt;</code> 換成自己的 Pixel ID。</p>
<p><strong>GA4</strong> 的自動收集事件分成只要裝了 Google 代碼就會送的基本事件，例如 <code>first_visit</code>、<code>session_start</code>、<code>user_engagement</code>，以及由加強型評估（enhanced measurement）控制的事件。加強型評估是網頁資料串流（GA4 資源裡代表一個網站資料來源的設定單位）上的一組開關，涵蓋捲動、外連點擊、站內搜尋、影片互動、檔案下載與表單互動，其中檔案下載會帶連結文字（<code>link_text</code>）、表單送出會帶送出按鈕的文字。<code>page_view</code> 也列在加強型評估底下，而它是其中唯一關不掉的一項。這組開關在 GA4 管理介面的資料串流設定裡，需要編輯者以上的權限。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>自動事件在請求裡的樣子與網站自己呼叫的事件相同，差別只在網站的程式碼裡找不到對應的呼叫。Meta 的事件請求送到 <code>www.facebook.com/tr/</code>，事件名稱在 <code>ev</code> 參數；GA4 的事件請求送到 Google Analytics 網域下的 <code>g/collect</code>（在開發者工具的 Network 面板以 <code>collect</code> 篩選），事件名稱在 <code>en</code> 參數。一次 Meta Pixel 的實測裡，網站呼叫了 ViewContent 與 Purchase 各一次，擷取結果裡多出兩筆 <code>SubscribedButtonClick</code>，各自緊跟在一次按鈕點擊之後。</p>
<h2 id="判讀方式">判讀方式</h2>
<p>網站原始碼只列得出手動埋點的那一部分，網站實際送出的資料要從送出的請求裡數；按鈕文字、連結文字這類欄位也在送出範圍內，按鈕或連結上顯示了使用者的個人資料時，那段文字會一起送到 vendor。兩種埋點方式的取捨方向相反：手動埋點會漏掉沒有寫追蹤程式的互動，換到的是送出的欄位全部由開發者決定；自動收集不需要逐一標記，而涵蓋哪些互動、送出哪些欄位由 vendor 的規則決定、會隨 vendor 改版變動。vendor 改版不會通知網站，所以送出資料的盤點要定期重做；Meta Pixel 的 <code>fbevents.js</code> 版本可以在頁面的開發者工具 Console 輸入 <code>fbq.version</code> 讀出，但自動事件由每個 Pixel 的設定檔決定，設定檔或事件管理工具裡的設定改了，<code>fbq.version</code> 不會變，所以版本相同不代表送出的內容沒變，盤點仍要看實際送出的請求。</p>
<h2 id="完整章節">完整章節</h2>
<p>Meta Pixel 自動加送的事件與它的欄位 → <a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a>的〈各次擷取的結果〉。以 <code>data-track</code> 屬性手動埋點的感測器設計，與它和自動收集的對照 → <a href="/blog/devops/monitoring/03-sdk-design/frontend-sensor-design/" data-link-title="前端感測器設計" data-link-desc="什麼行為值得埋感測器、每類感測器的實作方式、取樣策略和效能影響 — 和 auto-intercept 的被動攔截互補">前端感測器設計</a>。設定檔指定的模組怎麼在網站沒呼叫時自己送事件 → <a href="/blog/devops/monitoring/vendors/meta-pixel-conversions-api/" data-link-title="Meta Pixel 與 Conversions API：廣告平台轉換追蹤的瀏覽器端與伺服器端" data-link-desc="Meta Pixel 在頁面上送出的標準事件與它的資料消費者、瀏覽器端事件被攔截的路徑、Conversions API 從伺服器補送同一批事件的必填欄位，以及兩路並送時以 event_id 去重與用 Test Events 驗證的方式">Meta Pixel 與 Conversions API</a> 的〈Meta Pixel 在瀏覽器裡做的事〉；同一類模組依 User-Agent 攔下事件的機制 → <a href="/blog/devops/monitoring/vendors/tracking-request-capture/" data-link-title="用 Playwright 擷取追蹤碼請求：擷取方式、記錄欄位與各次結果" data-link-desc="以 Playwright 操作 Meta Pixel 與 GTM 實測頁、記錄各家 script 實際送出的請求與 cookie 的方式，結果檔記錄的欄位與它們的用途，擷取用的測試帳號，以及每一次擷取觀察到的事件請求形式、cookie 與請求參數的對應、無頭瀏覽器下的差異與 script 自動送出的事件">用 Playwright 擷取追蹤碼請求</a>的〈擷取方式〉。</p>
]]></content:encoded></item></channel></rss>