✍️ 필사 모드: フロントエンドモニタリング·エラートラッキング 2025 — Sentry·Datadog RUM·PostHog·LogRocket·Session Replay·Source Map·AI異常検知 (シーズン6 第8回)
日本語プロローグ — 「ローカルでは動くのに」
日曜22時、デプロイ後にSlackに「決済できません」の通報。ローカルもステージングもOKで本番だけ失敗。どのブラウザ?どのOS?どのA/B?ログがない。分からない。
2025年、モニタリングなしのデプロイは目隠し運転。バックエンドはAPM·ログ·メトリクス三拍子が20年前から標準、フロントエンドはここ5年でようやく真のRUMを得た。
2025年の4変化:
- RUMの大衆化 — Sentry·Datadog·Vercel Speed Insights·PostHogがリーズナブル価格でRUM提供。スタートアップもCrUX以上の粒度。
- Session Replayの倫理が結晶化 — 2024年パスワード·クレカ流出事件でGDPR罰金、業界ガイドラインが整備。
- AI異常検知 — 閾値アラートを超え、LLMでグルーピング·根本原因·アラートノイズ削減。
- プライバシー規制 — GDPR·CCPA·日韓個人情報法がフロントログの範囲·保管期間を直接規制。
本稿は全レイヤーのマッピング。
1章. 何を観測するか — 4軸
バックエンド観測性は Logs + Metrics + Traces。フロントエンドはユーザーが加わり4軸。
| 軸 | 問い | ツール |
|---|---|---|
| Errors | 何が壊れた? | Sentry、Bugsnag、Rollbar |
| Performance (RUM) | どれだけ遅い? | Datadog RUM、Vercel Speed Insights、SpeedCurve |
| User Behavior | ユーザーは何を? | PostHog、Mixpanel、Amplitude、Heap |
| Session Replay | どう体験した? | LogRocket、Clarity、PostHog、FullStory |
単一ツールで統一する強迫は誤り。2025スタートアップ事実上標準: Sentry (エラー) + PostHog (行動+Replay) + Vercel Speed Insights (RUM)。
一貫した distinctId、user_id、release を3ツールに注入することが最重要基礎作業。
2章. Sentry — エラートラッキングのデファクト
Next.jsインストール:
npx @sentry/wizard@latest -i nextjs
最小初期化:
import * as Sentry from '@sentry/nextjs'
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NEXT_PUBLIC_ENV,
release: process.env.NEXT_PUBLIC_BUILD_ID,
tracesSampleRate: 0.1,
replaysSessionSampleRate: 0.05,
replaysOnErrorSampleRate: 1.0,
integrations: [Sentry.replayIntegration({ maskAllText: true, blockAllMedia: true })],
})
User + Context + Breadcrumb:
Sentry.setUser({ id: user.id, segment: user.plan })
Sentry.setTag('feature_flag_checkout_v2', 'enabled')
Sentry.addBreadcrumb({ category: 'purchase', message: 'クーポン適用', level: 'info' })
Release Tracking — コミットとエラーをつなぐ:
sentry-cli releases new $VERSION
sentry-cli releases set-commits $VERSION --auto
sentry-cli releases finalize $VERSION
3章. Source Map — デコーダ
本番バンドルはminify済み。Source Map (.map) が難読化フレームを元行に戻す。
.map をCDNに公開しない
ソースが外部公開される。代わりに:
.mapはSentryにのみアップロード。- バンドルから
sourceMappingURLを除去または内部化。 - Sentryがサーバ側でスタック復元。
sentry-cli sourcemaps upload \
--release $VERSION \
--url-prefix '~/_next' \
.next/static
Next.js: withSentryConfig({ widenClientFileUpload: true, hideSourceMaps: true })。
Before: TypeError: n is undefined at t.default (main.a3f2.js:1:4829)
After: TypeError: user is undefined at CheckoutForm.tsx:42:16
4章. Datadog RUM — エンタープライズ統合観測
import { datadogRum } from '@datadog/browser-rum'
datadogRum.init({
applicationId: process.env.NEXT_PUBLIC_DD_APP_ID,
clientToken: process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN,
site: 'datadoghq.com',
service: 'web-app',
env: 'prod',
version: process.env.NEXT_PUBLIC_BUILD_ID,
sessionSampleRate: 100,
sessionReplaySampleRate: 20,
trackUserInteractions: true,
trackResources: true,
trackLongTasks: true,
defaultPrivacyLevel: 'mask-user-input',
})
datadogRum.startSessionReplayRecording()
強み: Trace → Session リンク。バックエンドtrace IDを自動注入、DatadogUIで「このAPI呼び出しはこのセッション」を即探索。
注意: Datadog RUMはエンタープライズ価格。大規模は sessionSampleRate を10–30%に。
5章. PostHog — 分析+Replay+フラグ+実験
オープンソース Amplitude + LogRocket + LaunchDarkly。
import posthog from 'posthog-js'
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
api_host: 'https://app.posthog.com',
session_recording: { maskAllInputs: true, maskTextSelector: '[data-private]' },
autocapture: true,
})
posthog.capture('checkout_started', { cart_total: cart.total, items: cart.items.length })
posthog.identify(user.id, { email: user.email, plan: user.plan })
if (posthog.isFeatureEnabled('checkout-v2')) return <CheckoutV2 />
2025年追加: SQL Insights (ClickHouse)、LLM Observability (OpenAI·Anthropic自動計装)、Data Warehouse 同期。
6章. Session Replay 専門ツール
- LogRocket — JS + ネットワーク + Redux + コンソール。1.5分以上セッション分析が強み。10k/月無料、以降急騰。
- Microsoft Clarity — 無料·無制限。ヒートマップ·Rage/Dead Click。MSにデータ共有同意が条件。中小に圧倒的コスパ。
- FullStory — エンタープライズ、プライバシー制御最強。
Session Replayの価値: 再現不能バグ解消、UX洞察 (Rage Click·離脱)、ファネル補完 (「なぜ」が見える)。
7章. Session Replay の倫理 — Privacy by Design
2024年事件: パスワード·クレカ番号が録画され、GDPR罰金。
3層防御
1層: 安全側デフォルト
Sentry.replayIntegration({ maskAllText: true, maskAllInputs: true, blockAllMedia: true })
2層: マークアップ統制
<input type="password" data-private />
<div data-private>{creditCard}</div>
<span class="ph-no-capture">マイナンバー</span>
3層: 送信前サニタイズ
posthog.capture('form_submit', {
email: user.email.replace(/(.{2}).+(@.+)/, '$1***$2'),
})
GDPR Art. 6/7
- 明示的同意 — クッキーバナーで「セッション録画」を別項目。
- 目的制限 — UX改善以外禁止。
- 保管期間 — 30–90日。
- DSAR — ユーザーが自分の録画削除リクエスト可能。
8章. フロントエンドのエラー種類
JSランタイムエラー
TypeError: Cannot read property 'x' of undefined。対応: TS strict + null guard。
Unhandled Promise Rejection
window.addEventListener('unhandledrejection', (e) => Sentry.captureException(e.reason))
ChunkLoadError — デプロイ時の定番
ユーザーがタブを開いたままデプロイ、古いchunkがCDNから消失。
window.addEventListener('error', (e) => {
if (e.message.includes('ChunkLoadError') || e.message.includes('Loading chunk')) {
window.location.reload()
}
})
またはlong-term cache + hash invalidation。
Hydration Mismatch
SSRとクライアントで異なる値 (Date、Math.random、localStorage)。
const [now, setNow] = useState('')
useEffect(() => { setNow(new Date().toLocaleString()) }, [])
return <div suppressHydrationWarning>{now}</div>
CORS·CSPエラー
CSP Report-Only → 段階的強化。nonce使用。
サードパーティスクリプトエラー
「Script error.」スタックなし = クロスオリジンブロック。対応: <script crossorigin="anonymous"> + CORSヘッダ + Sentry.ignoreErrors。
9章. Core Web Vitals — RUMループ
web-vitals ライブラリ
import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals'
function send(metric) {
navigator.sendBeacon('/api/vitals', JSON.stringify({
name: metric.name, value: metric.value, id: metric.id,
rating: metric.rating, delta: metric.delta, navigationType: metric.navigationType,
}))
}
onCLS(send); onINP(send); onLCP(send)
Vercel Speed Insights
Vercelで <SpeedInsights /> 一行。CrUX風RUMを無料枠で即活用。
ダッシュボード規律
- 百分位 — p75/p90/p95、平均でなく。
- セグメント — デバイス·ルート·バージョン·地域。
- 回帰検知 — デプロイ前後diff。
10章. Alert Fatigue — 真の敵
Slackに1日50件のアラート → 誰も見なくなる → 重要アラートがノイズに埋もれる。
SLO基盤アラート (Google SRE式)
「エラー1件発生」でなく「バーンレート」でアラート:
slo:
name: checkout-success-rate
target: 99.9%
window: 30d
alert:
- burn_rate: 14.4 # 2%予算を1時間で消費
duration: 5m
severity: critical
- burn_rate: 6 # 5%予算を6時間で消費
duration: 30m
severity: warning
グルーピング
Sentryがスタックパターン自動グルーピング。新種issueやP95の3倍トラフィックでアラート。
優先順位3段
- Critical — ページダウン、決済障害。ページング。
- Warning — 部分障害、パフォ劣化。営業時間内。
- Info — トレンド観察、ダッシュボードのみ。
11章. AI異常検知 + 根本原因
静的閾値は季節性を見落とす。2024–2025 Datadog Watchdog、Sentry Insights、PostHog AI、Dynatrace Davis がLLM·時系列機能出荷。
機能:
- 変曲点検知 (先週同時間帯比3σ)。
- エラースパイクと変更 (デプロイ·フラグ·外部依存) を自動相関、RCA提案。
- LLMがスタック·ログを自然言語要約「この機能のこのフローで失敗」。
- ビジネス影響ランキング (トラフィック × 決済ページ)。
注意: 相関 ≠ 因果。AIは探索範囲を絞る助手、最終判断は人間。
12章. ユーザーフィードバックループ
数値は「どれだけ」、フィードバックは「なぜ」に答える。
- NPS/CSAT — Delighted、Wootric、Typeform。
- インアプリフィードバック — Canny、UserVoice、Feedback Fish。
- セッション + コメント — LogRocket/PostHog「録画共有」。
- Sentry User Feedback — エラー時にユーザー説明を求める:
Sentry.showReportDialog({ user: { email: user.email, name: user.name } })
13章. チェックリスト + アンチパターン
14項目チェックリスト
- Sentry (または同等) でエラー収集。
- Source MapはSentryへのみ、公開禁止。
- Release Tracking — コミット·ビルド·エラーの連鎖。
- User Context注入。
- RUMデプロイ (Vercel Speed Insights / Datadog / PostHog)。
- CWV収集 + デプロイ前後diff。
- Session Replay with マスクデフォルト +
data-private。 - ChunkLoadError自動リトライ。
- Hydration Mismatch監視。
unhandledrejectionグローバルハンドラ。- SLO基盤バーンレートアラート。
- 3段優先順位。
- GDPR·日韓個人情報法対応 (同意·保管期間·DSAR)。
- ダッシュボードをデバイス·ルート·バージョンでセグメント。
TOP 10 モニタリングアンチパターン
console.errorのみ、サーバ収集なし。- マスクなしでSentryにPII送信。
.mapをCDN公開。- 全エラーをCriticalアラート。
- Dev·Staging·Prod混在 (environmentタグなし)。
- サンプルレート100% (コスト爆発)。
data-privateなしのSession Replay。- Release Tracking なし (「いつから?」不明)。
- Hydration Mismatch放置。
- 定量·定性データを別保管 (分断)。
次回予告
シーズン6 第9回: フロントエンドセキュリティ 2025 — XSS、CSRF、CSP v3、Trusted Types、JWT、OAuth + PKCE、Passkey、サプライチェーン、SRI。
「モニタリングはデプロイ後の別のプロダクト。エラー·パフォーマンス·行動·感情を計測するが、ユーザーのプライバシーを侵害しない設計が2025年の品質」
— フロントエンドモニタリング·エラートラッキング編、完。
현재 단락 (1/177)
日曜22時、デプロイ後にSlackに「決済できません」の通報。ローカルもステージングもOKで本番だけ失敗。どのブラウザ?どのOS?どのA/B?**ログがない。分からない。**