<?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>Session-Replay on Tarragon</title><link>https://tarrragon.github.io/blog/tags/session-replay/</link><description>Recent content in Session-Replay 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/session-replay/index.xml" rel="self" type="application/rss+xml"/><item><title>Sentry 深入</title><link>https://tarrragon.github.io/blog/monitoring/06-commercial-comparison/sentry-deep-dive/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/monitoring/06-commercial-comparison/sentry-deep-dive/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>跟 Backend 04 的分工&lt;/strong>：本文從 client-side 使用角度說明 Sentry 的 error tracking、performance monitoring 與 session replay — SDK 怎麼埋、error 怎麼分群、release 怎麼追蹤。Server-side 平台治理（告警路由整合、SLI 指標設計、self-hosted vs SaaS 成本治理、跟 OTel 的整合）見 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/sentry/" data-link-title="Sentry" data-link-desc="Error tracking 主流、APM / Profiling / Session Replay 擴展">Backend 04 Sentry vendor page&lt;/a>。&lt;/p>&lt;/blockquote>
&lt;p>Sentry 的核心是 error tracking — 自動捕獲未處理的例外、提供 stack trace、自動分群（grouping）相同 root cause 的 error。在 error tracking 的基礎上，Sentry 擴展了 performance monitoring（transaction / span）和 session replay（重播使用者操作）。&lt;/p>
&lt;h2 id="error-tracking">Error tracking&lt;/h2>
&lt;p>Sentry 的 error tracking 架構有三個層次：SDK 端的自動捕獲、server 端的 issue grouping 和 UI 端的 issue management。&lt;/p>
&lt;h3 id="自動捕獲">自動捕獲&lt;/h3>
&lt;p>Sentry SDK 在各平台註冊全域錯誤處理器（和&lt;a href="https://tarrragon.github.io/blog/monitoring/03-sdk-design/auto-intercept/" data-link-title="自動攔截機制" data-link-desc="JS window.onerror / Flutter FlutterError.onError / Python sys.excepthook — 各平台攔截未捕獲例外的機制和限制">模組三 自動攔截&lt;/a>的機制相同）。捕獲到例外後，SDK 收集 stack trace、breadcrumbs（最近的使用者操作）、device context（OS / browser / device model）和自訂 tags，打包成 event 送到 Sentry server。&lt;/p>
&lt;h3 id="issue-grouping">Issue grouping&lt;/h3>
&lt;p>Sentry server 收到 error event 後，用 fingerprinting 演算法判斷這個 error 是否和已有的 issue 相同。預設的 fingerprinting 基於 stack trace 的 frame — 如果兩個 error 的 stack trace 指向同一個位置，歸入同一個 issue。&lt;/p>
&lt;p>自訂 fingerprint 讓開發者控制 grouping 邏輯。例如：不同使用者觸發的同一個 API error 可能有不同的 stack trace（因為 call site 不同），但 root cause 相同 — 自訂 fingerprint 把它們歸入同一個 issue。&lt;/p>
&lt;h3 id="issue-management">Issue management&lt;/h3>
&lt;p>每個 issue 有狀態（unresolved / resolved / ignored）、指派（誰負責修復）、趨勢（這個 issue 的發生頻率是上升還是下降）。Sentry 的 UI 提供 issue 列表、趨勢圖、影響範圍（影響多少使用者）。&lt;/p>
&lt;h2 id="performance-monitoring">Performance monitoring&lt;/h2>
&lt;p>Sentry 的 performance monitoring 用 transaction 和 span 模型（和 OpenTelemetry 的 trace / span 概念相同）。&lt;/p>
&lt;p>Transaction 代表一個完整的操作（頁面載入、API 請求處理）。Span 是 transaction 內的子操作（database query、外部 API 呼叫）。Transaction 和 span 的 duration 構成操作的時間分佈。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p><strong>跟 Backend 04 的分工</strong>：本文從 client-side 使用角度說明 Sentry 的 error tracking、performance monitoring 與 session replay — SDK 怎麼埋、error 怎麼分群、release 怎麼追蹤。Server-side 平台治理（告警路由整合、SLI 指標設計、self-hosted vs SaaS 成本治理、跟 OTel 的整合）見 <a href="/blog/backend/04-observability/vendors/sentry/" data-link-title="Sentry" data-link-desc="Error tracking 主流、APM / Profiling / Session Replay 擴展">Backend 04 Sentry vendor page</a>。</p></blockquote>
<p>Sentry 的核心是 error tracking — 自動捕獲未處理的例外、提供 stack trace、自動分群（grouping）相同 root cause 的 error。在 error tracking 的基礎上，Sentry 擴展了 performance monitoring（transaction / span）和 session replay（重播使用者操作）。</p>
<h2 id="error-tracking">Error tracking</h2>
<p>Sentry 的 error tracking 架構有三個層次：SDK 端的自動捕獲、server 端的 issue grouping 和 UI 端的 issue management。</p>
<h3 id="自動捕獲">自動捕獲</h3>
<p>Sentry SDK 在各平台註冊全域錯誤處理器（和<a href="/blog/monitoring/03-sdk-design/auto-intercept/" data-link-title="自動攔截機制" data-link-desc="JS window.onerror / Flutter FlutterError.onError / Python sys.excepthook — 各平台攔截未捕獲例外的機制和限制">模組三 自動攔截</a>的機制相同）。捕獲到例外後，SDK 收集 stack trace、breadcrumbs（最近的使用者操作）、device context（OS / browser / device model）和自訂 tags，打包成 event 送到 Sentry server。</p>
<h3 id="issue-grouping">Issue grouping</h3>
<p>Sentry server 收到 error event 後，用 fingerprinting 演算法判斷這個 error 是否和已有的 issue 相同。預設的 fingerprinting 基於 stack trace 的 frame — 如果兩個 error 的 stack trace 指向同一個位置，歸入同一個 issue。</p>
<p>自訂 fingerprint 讓開發者控制 grouping 邏輯。例如：不同使用者觸發的同一個 API error 可能有不同的 stack trace（因為 call site 不同），但 root cause 相同 — 自訂 fingerprint 把它們歸入同一個 issue。</p>
<h3 id="issue-management">Issue management</h3>
<p>每個 issue 有狀態（unresolved / resolved / ignored）、指派（誰負責修復）、趨勢（這個 issue 的發生頻率是上升還是下降）。Sentry 的 UI 提供 issue 列表、趨勢圖、影響範圍（影響多少使用者）。</p>
<h2 id="performance-monitoring">Performance monitoring</h2>
<p>Sentry 的 performance monitoring 用 transaction 和 span 模型（和 OpenTelemetry 的 trace / span 概念相同）。</p>
<p>Transaction 代表一個完整的操作（頁面載入、API 請求處理）。Span 是 transaction 內的子操作（database query、外部 API 呼叫）。Transaction 和 span 的 duration 構成操作的時間分佈。</p>
<p>Performance monitoring 的價值是發現「慢」的問題 — P95 回應時間超過閾值、特定 span 佔了 transaction 80% 的時間。和 error tracking 互補：error 告訴你「什麼壞了」，performance 告訴你「什麼慢了」。</p>
<h2 id="session-replay">Session replay</h2>
<p>Session replay 錄製使用者的操作過程 — DOM 變化、滑鼠移動、點擊事件 — 在 Sentry UI 中重播。開發者可以看到「使用者在觸發 error 之前做了什麼操作」。</p>
<p>Session replay 的實作是 DOM snapshot + mutation recording。記錄的是 DOM 結構的變化（非螢幕錄影），在重播時重建 DOM。資料量比錄影小很多，但仍然是所有 Sentry 功能中資料量最大的。</p>
<p>隱私考量：session replay 會看到使用者輸入的內容（除非做 masking）。Sentry 提供 privacy configuration 控制哪些元素被 mask（輸入框、敏感資料區域）。</p>
<h2 id="自架方案和-sentry-的差距">自架方案和 Sentry 的差距</h2>
<table>
  <thead>
      <tr>
          <th>功能</th>
          <th>自架方案</th>
          <th>Sentry</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Error 捕獲</td>
          <td>SDK 自動攔截</td>
          <td>SDK 自動攔截（相同）</td>
      </tr>
      <tr>
          <td>Issue grouping</td>
          <td>手動 grep 分群</td>
          <td>自動 fingerprinting + 自訂規則</td>
      </tr>
      <tr>
          <td>趨勢分析</td>
          <td>手動計數</td>
          <td>自動趨勢圖 + 告警</td>
      </tr>
      <tr>
          <td>Performance</td>
          <td>metric 事件 + 手動分析</td>
          <td>Transaction / span + 自動 P95</td>
      </tr>
      <tr>
          <td>Session replay</td>
          <td>無</td>
          <td>DOM recording + 重播 UI</td>
      </tr>
  </tbody>
</table>
<p>Sentry 的核心價值在 issue grouping 和趨勢分析 — 把大量 error event 歸類成可管理的 issue 列表，自動追蹤每個 issue 的趨勢。自架方案用 grep 做不到自動 grouping。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>Firebase 的整合方案 → <a href="/blog/monitoring/06-commercial-comparison/firebase-suite/" data-link-title="Firebase 套件" data-link-desc="Crashlytics &#43; Analytics &#43; Remote Config 的整合 — Firebase 把 error tracking 和行為分析拆成獨立產品的設計取捨">Firebase 套件</a></li>
<li>Datadog 的全棧 APM → <a href="/blog/monitoring/06-commercial-comparison/datadog-rum/" data-link-title="Datadog RUM" data-link-desc="全棧 APM 的 client-side 觀點 — client action 到 server trace 的完整鏈路追蹤">Datadog RUM</a></li>
<li>自架 vs 商業的判斷 → <a href="/blog/monitoring/06-commercial-comparison/self-hosted-vs-commercial/" data-link-title="自架 vs 商業的判斷決策表" data-link-desc="使用者數、網路範圍、功能需求、合規要求四個維度判斷該自架還是用商業方案">自架 vs 商業的判斷決策表</a></li>
<li>自架方案的 error fingerprint 實作 → <a href="/blog/monitoring/04-collector/error-fingerprint/" data-link-title="Error Fingerprint 與去重分群" data-link-desc="把大量 error 事件歸組成可管理的 issue 列表 — fingerprint 演算法、message normalization、error_groups 表設計、自架方案的務實邊界">Error Fingerprint 與去重分群</a></li>
</ul>
]]></content:encoded></item><item><title>Sentry Release Tracking 與 Session Replay</title><link>https://tarrragon.github.io/blog/backend/04-observability/vendors/sentry/release-tracking-session-replay/</link><pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/04-observability/vendors/sentry/release-tracking-session-replay/</guid><description>&lt;blockquote>
&lt;p>本文是 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/sentry/" data-link-title="Sentry" data-link-desc="Error tracking 主流、APM / Profiling / Session Replay 擴展">Sentry&lt;/a> 的 vendor deep article，深化 overview「Release / source map」跟「Session Replay」段。初次接觸 Sentry 的讀者建議先讀 &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/vendors/sentry/" data-link-title="Sentry" data-link-desc="Error tracking 主流、APM / Profiling / Session Replay 擴展">Sentry 服務頁&lt;/a>。&lt;/p>&lt;/blockquote>
&lt;h2 id="問題情境">問題情境&lt;/h2>
&lt;p>Release tracking 讓 Sentry 從「error 收集器」升級成「部署品質追蹤器」。每次部署標記一個 release，Sentry 自動計算 crash-free sessions、regressed errors 跟 release health。Session Replay 進一步把 error 的觸發脈絡從 stack trace 擴展到使用者操作錄影。兩者搭配使用時，團隊能看到「這個版本部署後、哪些使用者遇到什麼操作導致什麼錯誤」的完整鏈路。&lt;/p>
&lt;h2 id="release-health">Release Health&lt;/h2>
&lt;h3 id="核心概念">核心概念&lt;/h3>
&lt;p>Release health 追蹤每個版本的使用者體驗品質。核心指標：&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>Crash-free sessions&lt;/td>
 &lt;td>沒有 unhandled error 的 session 百分比&lt;/td>
 &lt;td>99.5% 以上&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Crash-free users&lt;/td>
 &lt;td>沒有遇到 unhandled error 的使用者百分比&lt;/td>
 &lt;td>99.5% 以上&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Adoption rate&lt;/td>
 &lt;td>使用此版本的 session 佔比&lt;/td>
 &lt;td>依 rollout 策略&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Error count&lt;/td>
 &lt;td>此版本的 error event 數量&lt;/td>
 &lt;td>不應比前一版高&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Crash-free sessions 跟 crash-free users 的差異：sessions 是頻率加權（一個使用者一天開 10 次 app，10 次都算），users 是去重的。Mobile app 通常看 crash-free users（使用者感知），web 通常看 crash-free sessions（頻率反映服務品質）。&lt;/p>
&lt;h3 id="release-標記">Release 標記&lt;/h3>
&lt;p>在 SDK 初始化時傳入 release 標記：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="n">sentry_sdk&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">init&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> &lt;span class="n">dsn&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> &lt;span class="n">release&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;checkout-api@1.2.3&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> &lt;span class="n">environment&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;production&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Release 命名慣例：&lt;code>&amp;lt;service&amp;gt;@&amp;lt;version&amp;gt;&lt;/code> 或 git SHA。用語意版本方便比較，用 git SHA 方便對應 commit。CI/CD pipeline 在 deploy step 自動設定。&lt;/p>
&lt;h3 id="deploy-標記">Deploy 標記&lt;/h3>
&lt;p>Release 建立後，用 Sentry CLI 或 API 標記 deploy：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">sentry-cli releases deploys checkout-api@1.2.3 new &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --env production &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --started &lt;span class="k">$(&lt;/span>date -u +%s&lt;span class="k">)&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="se">&lt;/span> --finished &lt;span class="k">$(&lt;/span>date -u +%s&lt;span class="k">)&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Deploy 標記讓 Sentry 知道某個 release 何時部署到哪個環境。issue list 的 &amp;ldquo;First seen in release&amp;rdquo; 跟 &amp;ldquo;Regressed in release&amp;rdquo; 依賴這個資訊。&lt;/p>
&lt;h3 id="regressed-error-偵測">Regressed Error 偵測&lt;/h3>
&lt;p>Sentry 會追蹤已 resolve 的 issue。如果新 release 重新觸發了已 resolve 的 issue，Sentry 標記為 regression。這比人工追蹤有效 — 團隊不需要記住哪些 bug 修過，Sentry 自動偵測回歸。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是 <a href="/blog/backend/04-observability/vendors/sentry/" data-link-title="Sentry" data-link-desc="Error tracking 主流、APM / Profiling / Session Replay 擴展">Sentry</a> 的 vendor deep article，深化 overview「Release / source map」跟「Session Replay」段。初次接觸 Sentry 的讀者建議先讀 <a href="/blog/backend/04-observability/vendors/sentry/" data-link-title="Sentry" data-link-desc="Error tracking 主流、APM / Profiling / Session Replay 擴展">Sentry 服務頁</a>。</p></blockquote>
<h2 id="問題情境">問題情境</h2>
<p>Release tracking 讓 Sentry 從「error 收集器」升級成「部署品質追蹤器」。每次部署標記一個 release，Sentry 自動計算 crash-free sessions、regressed errors 跟 release health。Session Replay 進一步把 error 的觸發脈絡從 stack trace 擴展到使用者操作錄影。兩者搭配使用時，團隊能看到「這個版本部署後、哪些使用者遇到什麼操作導致什麼錯誤」的完整鏈路。</p>
<h2 id="release-health">Release Health</h2>
<h3 id="核心概念">核心概念</h3>
<p>Release health 追蹤每個版本的使用者體驗品質。核心指標：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>定義</th>
          <th>健康閾值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Crash-free sessions</td>
          <td>沒有 unhandled error 的 session 百分比</td>
          <td>99.5% 以上</td>
      </tr>
      <tr>
          <td>Crash-free users</td>
          <td>沒有遇到 unhandled error 的使用者百分比</td>
          <td>99.5% 以上</td>
      </tr>
      <tr>
          <td>Adoption rate</td>
          <td>使用此版本的 session 佔比</td>
          <td>依 rollout 策略</td>
      </tr>
      <tr>
          <td>Error count</td>
          <td>此版本的 error event 數量</td>
          <td>不應比前一版高</td>
      </tr>
  </tbody>
</table>
<p>Crash-free sessions 跟 crash-free users 的差異：sessions 是頻率加權（一個使用者一天開 10 次 app，10 次都算），users 是去重的。Mobile app 通常看 crash-free users（使用者感知），web 通常看 crash-free sessions（頻率反映服務品質）。</p>
<h3 id="release-標記">Release 標記</h3>
<p>在 SDK 初始化時傳入 release 標記：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="ln">1</span><span class="cl"><span class="n">sentry_sdk</span><span class="o">.</span><span class="n">init</span><span class="p">(</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="n">dsn</span><span class="o">=</span><span class="s2">&#34;...&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    <span class="n">release</span><span class="o">=</span><span class="s2">&#34;checkout-api@1.2.3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="n">environment</span><span class="o">=</span><span class="s2">&#34;production&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="p">)</span></span></span></code></pre></div><p>Release 命名慣例：<code>&lt;service&gt;@&lt;version&gt;</code> 或 git SHA。用語意版本方便比較，用 git SHA 方便對應 commit。CI/CD pipeline 在 deploy step 自動設定。</p>
<h3 id="deploy-標記">Deploy 標記</h3>
<p>Release 建立後，用 Sentry CLI 或 API 標記 deploy：</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">sentry-cli releases deploys checkout-api@1.2.3 new <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --env production <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --started <span class="k">$(</span>date -u +%s<span class="k">)</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="se"></span>  --finished <span class="k">$(</span>date -u +%s<span class="k">)</span></span></span></code></pre></div><p>Deploy 標記讓 Sentry 知道某個 release 何時部署到哪個環境。issue list 的 &ldquo;First seen in release&rdquo; 跟 &ldquo;Regressed in release&rdquo; 依賴這個資訊。</p>
<h3 id="regressed-error-偵測">Regressed Error 偵測</h3>
<p>Sentry 會追蹤已 resolve 的 issue。如果新 release 重新觸發了已 resolve 的 issue，Sentry 標記為 regression。這比人工追蹤有效 — 團隊不需要記住哪些 bug 修過，Sentry 自動偵測回歸。</p>
<p>Regression 通知的準確度取決於 grouping 品質。如果 grouping 不準（見 <a href="../error-grouping-fingerprinting/">Error Grouping 與 Fingerprinting</a>），regression 偵測也會不準 — 不同 bug 被合成同一 issue 時，resolve 一個 bug 後另一個觸發會被誤判為 regression。</p>
<h3 id="source-map-上傳">Source map 上傳</h3>
<p>前端 minified code 的 stack trace 不可讀。上傳 source map 讓 Sentry 還原原始 source code 位置：</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">sentry-cli releases files checkout-api@1.2.3 upload-sourcemaps <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --url-prefix <span class="s1">&#39;~/static/js&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  ./build/static/js</span></span></code></pre></div><p>Source map 上傳必須在 deploy 前完成，且 release 版本跟前端 build 版本一致。版本不一致時，Sentry 找不到對應的 source map，stack trace 仍然是 minified。</p>
<p>CI/CD 整合：在 build step 之後、deploy step 之前上傳 source map。多數框架（Next.js、Vite、Webpack）有 Sentry plugin 自動處理。</p>
<h2 id="session-replay">Session Replay</h2>
<h3 id="核心能力">核心能力</h3>
<p>Session Replay 錄製使用者在網頁上的操作。Sentry 記錄的是 DOM mutation 跟使用者事件的結構化資料，播放時 replay DOM 變化，效果類似影片但資料量遠小於螢幕錄影。</p>
<p>replay 跟 error 關聯：Sentry 在 error event 中附帶 replay ID，讓工程師從 issue detail 直接跳到 error 發生前後的使用者操作。</p>
<h3 id="隱私設定">隱私設定</h3>
<p>Session Replay 預設會遮罩敏感資訊：</p>
<table>
  <thead>
      <tr>
          <th>遮罩類型</th>
          <th>預設行為</th>
          <th>自訂方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>文字內容</td>
          <td>所有文字替換成 <code>*</code></td>
          <td><code>maskAllText: false</code> 關閉、或用 CSS class <code>sentry-mask</code> 指定</td>
      </tr>
      <tr>
          <td>輸入框</td>
          <td>所有 input value 遮罩</td>
          <td><code>maskAllInputs: false</code> 關閉（注意 PII 風險）</td>
      </tr>
      <tr>
          <td>圖片</td>
          <td>不遮罩（但 <code>&lt;img&gt;</code> 從原始 URL 載入）</td>
          <td><code>blockAllMedia: true</code> 遮蔽所有媒體</td>
      </tr>
      <tr>
          <td>特定元素</td>
          <td>不遮罩</td>
          <td>加 <code>data-sentry-block</code> attribute 完全隱藏</td>
      </tr>
  </tbody>
</table>
<p>PII 合規考量：</p>
<ul>
<li>預設 <code>maskAllText: true</code> + <code>maskAllInputs: true</code> 是安全起點</li>
<li>GDPR / CCPA 場景需要額外確認：replay 資料存在 Sentry SaaS（美國資料中心），跨境傳輸需要評估</li>
<li>Self-hosted Sentry 可以把 replay 資料留在自己的基礎設施</li>
</ul>
<h3 id="sampling-策略">Sampling 策略</h3>
<p>Session Replay 會增加前端 SDK 的 payload 大小跟 Sentry 的 event quota。用 sampling rate 控制：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">Sentry</span><span class="p">.</span><span class="nx">init</span><span class="p">({</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">  <span class="nx">dsn</span><span class="o">:</span> <span class="s2">&#34;...&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">  <span class="nx">replaysSessionSampleRate</span><span class="o">:</span> <span class="mf">0.1</span><span class="p">,</span>  <span class="c1">// 10% 的 session 錄影
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span>  <span class="nx">replaysOnErrorSampleRate</span><span class="o">:</span> <span class="mf">1.0</span><span class="p">,</span>  <span class="c1">// error 發生時 100% 錄影
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="p">});</span></span></span></code></pre></div><p>推薦策略：<code>replaysSessionSampleRate</code> 用低值（1-10%），<code>replaysOnErrorSampleRate</code> 用 100%。目的是確保每個 error 都有 replay 可看，但不錄所有正常 session。</p>
<p>高流量網站（每日百萬 session 以上）可能需要把 <code>replaysSessionSampleRate</code> 設到 0，只在 error 時才錄。session replay 的 quota 消耗速度可以在 Sentry Usage Stats 頁面監控。</p>
<h2 id="performance-monitoring">Performance Monitoring</h2>
<h3 id="transaction-based-tracing">Transaction-based tracing</h3>
<p>Sentry 的 performance monitoring 用 transaction / span 結構（跟 OpenTelemetry 的 trace / span 概念對齊）。每個 HTTP request、page load 或自訂操作是一個 transaction，transaction 內的子操作是 span。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">with</span> <span class="n">sentry_sdk</span><span class="o">.</span><span class="n">start_transaction</span><span class="p">(</span><span class="n">op</span><span class="o">=</span><span class="s2">&#34;checkout&#34;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&#34;POST /api/checkout&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">with</span> <span class="n">sentry_sdk</span><span class="o">.</span><span class="n">start_span</span><span class="p">(</span><span class="n">op</span><span class="o">=</span><span class="s2">&#34;db&#34;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s2">&#34;insert order&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">        <span class="c1"># DB operation</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">        <span class="k">pass</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">    <span class="k">with</span> <span class="n">sentry_sdk</span><span class="o">.</span><span class="n">start_span</span><span class="p">(</span><span class="n">op</span><span class="o">=</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s2">&#34;payment gateway&#34;</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">        <span class="c1"># External API call</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">        <span class="k">pass</span></span></span></code></pre></div><p>自動 instrumentation 會自動建立 transaction 跟 span（HTTP framework、DB driver、HTTP client）。手動 span 用在自訂業務邏輯或自動 instrumentation 沒覆蓋的路徑。</p>
<h3 id="otel-context-整合">OTel context 整合</h3>
<p>Sentry SDK 支援 OTel context propagation — 如果 upstream service 用 OTel SDK 產生 trace，Sentry SDK 會接受 <code>traceparent</code> header 中的 trace_id 跟 parent_span_id，把自己的 transaction 接到同一條 trace。</p>
<p>整合方式：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>設定</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Sentry SDK 接收 OTel context</td>
          <td>預設支援 W3C Trace Context、不需額外設定</td>
      </tr>
      <tr>
          <td>Sentry 資料送到 OTel backend</td>
          <td>用 Sentry 的 OTel exporter（experimental）</td>
      </tr>
      <tr>
          <td>OTel SDK 送資料到 Sentry</td>
          <td>OTel SDK → OTLP exporter → Sentry（Sentry 支援 OTLP ingestion）</td>
      </tr>
  </tbody>
</table>
<p>常見架構：backend service 用 OTel SDK + Collector，frontend 用 Sentry SDK（前端 error tracking 跟 session replay 是 Sentry 的強項）。兩者透過 trace_id 關聯，在 Sentry 看 frontend error + replay，在 OTel backend 看 backend trace。</p>
<h3 id="web-vitals">Web Vitals</h3>
<p>前端 SDK 自動收集 Core Web Vitals（LCP、FID / INP、CLS）跟 TTFB。這些指標跟 error 在同一個 dashboard，讓團隊在 release 後同時看 error regression 跟效能 regression。</p>
<p>Web Vitals 的觀測不需要額外設定 — 前端 SDK 自動收集。但 sampling rate 會影響資料量 — <code>tracesSampleRate</code> 設太低時，Web Vitals 的 sample 數量可能不夠做統計比較。</p>
<h2 id="self-hosted-vs-saas">Self-hosted vs SaaS</h2>
<h3 id="決策維度">決策維度</h3>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>SaaS（sentry.io）</th>
          <th>Self-hosted</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>維運</td>
          <td>Sentry 負責</td>
          <td>自己維運（docker-compose、20+ 容器）</td>
      </tr>
      <tr>
          <td>資料位置</td>
          <td>Sentry 資料中心（美國為主）</td>
          <td>自己的基礎設施</td>
      </tr>
      <tr>
          <td>功能完整度</td>
          <td>全功能</td>
          <td>社群版功能略少（部分企業功能不含）</td>
      </tr>
      <tr>
          <td>升級</td>
          <td>自動</td>
          <td>手動（每月有新版、升級需要停機）</td>
      </tr>
      <tr>
          <td>成本模型</td>
          <td>Event-based pricing</td>
          <td>基礎設施 + 人力成本</td>
      </tr>
      <tr>
          <td>Replay / Profiling</td>
          <td>含</td>
          <td>含（但 storage 自負）</td>
      </tr>
  </tbody>
</table>
<h3 id="何時選-self-hosted">何時選 self-hosted</h3>
<p>資料必須留在特定地理區域（GDPR / 特定產業法規）、或企業 security policy 不允許 error data 送到第三方 — 這是 self-hosted 的核心理由。</p>
<p>Self-hosted Sentry 的維運成本常被低估：20+ 個容器（Kafka、ClickHouse、PostgreSQL、Redis、Snuba、Relay 等）、升級可能需要資料庫 migration、troubleshooting 時沒有 vendor 支援。中小團隊通常 SaaS 的 event pricing 比 self-hosted 的人力成本低。</p>
<h3 id="混合模式">混合模式</h3>
<p>部分團隊用混合模式：production error 送 Sentry SaaS（低維運），但 audit-sensitive 的資料（PII-heavy environment）走 self-hosted。兩套 Sentry instance 各自獨立，不共享 issue。</p>
<h2 id="整合與下一步">整合與下一步</h2>
<ul>
<li>Error grouping 策略：在 issue 數量失控前建立 fingerprint rule，見 <a href="../error-grouping-fingerprinting/">Error Grouping 與 Fingerprinting</a></li>
<li>觀測證據整合：把 Sentry issue link 放進 evidence package，見 <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>Client-side monitoring：Sentry 的前端 SDK 跟 RUM 的定位互補，見 <a href="/blog/backend/04-observability/client-side-monitoring/" data-link-title="4.10 Client-side / Synthetic / RUM" data-link-desc="補 server-side 看不到的 user perceived 訊號">4.10 Client-side Monitoring</a></li>
<li>事故響應整合：Sentry alert → PagerDuty / incident.io，見 <a href="/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">08 Incident Response 模組</a></li>
</ul>
]]></content:encoded></item></channel></rss>