mcpField
S
suppressing-noisy-errors

suppressing-noisy-errors

github.com/posthog開発76317 回インストール今日更新
リポジトリ

suppressing-noisy-errors について

suppressing-noisy-errorsは、PostHogのエラートラッキング抑制ルールを評価するスキルです。ノイズのパターンを検証して条件を絞り、影響を事前確認したうえで、イベント取り込み時に破棄する前の承認を求めます。

主な機能

  1. 01頻度が高くユーザー数の少ないエラーを特定
  2. 02サンプル例外イベントを調査
  3. 03範囲を絞った条件を作成
  4. 04対象イシューと影響範囲を事前確認
  5. 05既存ルールを確認して承認を依頼

活用シーン

  1. 01ブラウザー拡張機能や外部サービスのエラーを抑制
  2. 02ボットやクローラー由来のエラーを減らす
  3. 03高頻度エラーをサンプリングして可視性を維持

MCP 対応

PostHogのMCPツールを使い、イシューと例外イベントの調査、抑制ルールの一覧・作成、ライブデータに対する条件のプレビューを行います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/posthog/skills --skill suppressing-noisy-errors

インストール後、Claude Code で/suppressing-noisy-errorsを入力して読み込まれたか確認します。

詳細

ノイズの多いエラーを抑制する

抑制は本質的に破壊的です。一致したイベントは取り込み時に破棄され、イシューになりません。誤ったルールを設定すると、実際のバグが気づかれないまま破棄されます。このスキルは、抑制が本当に対処不能なパターンにのみ適用され、関係のないエラーを巻き込まないよう十分に絞り込まれたフィルターが使われるようにするためのものです。

抑制が適切な場合

次のようなエラーには、抑制が適切です。

  • 自分のコードでは対処不能 — ブラウザー拡張機能、サードパーティーのスクリプト、広告ブロッカー、ページ遷移後に発生するネットワークビーコンなどです。自分で書いたものではないため、修正できません。
  • ブラウザーエンジンの特有の動作 — ResizeObserver loop limit exceeded、Script error.、ペイロードが空の Non-Error promise rejection captured などです。
  • ボットまたはクローラーのトラフィック — ヘッドレスブラウザーまたは既知のクローラーのユーザーエージェントからのみ発生するエラーです。
  • サンプリングで十分な場合 — 発生量は多くても実際のエラーである場合は、完全に抑制するのではなく、sampling_rate で発生頻度を抑えます。全額分のコストをかけずに、状況を把握し続けられます。

次の場合、抑制は適切ではありません。

  • 現時点では対処不能でも、修正後には対処可能になる可能性があるエラー — イシューのステータスを archived または resolved にして、再発したときに検出できるようにします。
  • 通知だけをミュートしたい場合 — イシューをユーザーに割り当てる、ステータスを変更する、または通知ルールを使います。
  • 別のエラーと重複している場合 — マージするか、グルーピングルール(grouping-noisy-errors)を作成します。

利用可能なツール

ツール目的
posthog:query-error-tracking-issues-list発生量と影響度を基に抑制候補を見つけます。filterGroup で候補フィルターをドライランします
posthog:query-error-tracking-issue-eventsサンプリングされた $exception イベントを調べ、パターンを確認します
posthog:execute-sqlOR グループまたは filterGroup の許可リスト外の演算子が必要なフィルターをドライランするための代替手段です
posthog:error-tracking-suppression-rules-list既存の抑制ルールを確認します
posthog:error-tracking-suppression-rules-create抑制ルールを作成します
posthog:error-tracking-issues-partial-update取り込み時にイベントを破棄せず、イシューのステータスで過去のデータを非表示にします

ワークフロー

ステップ 1 — 候補を特定する

発生数が多く、個別ユーザー数が少ない場合は、最も強いノイズの兆候です。1 人のユーザー(または 1 つのボット)が大量のイベントを発生させています。

posthog:query-error-tracking-issues-list
{
  "status": "active",
  "orderBy": "occurrences",
  "orderDirection": "DESC",
  "dateRange": { "date_from": "-7d" },
  "limit": 30,
  "volumeResolution": 0
}

次の点を確認します。

  • occurrences が多く、users との比率が低い(例:50,000 件の発生に対し 3 人のユーザー → ボットまたは拡張機能のループの可能性が高い)
  • 既知のノイズパターンに一致する例外メッセージ:ResizeObserver loop、Script error.、拡張機能の名前空間(chrome-extension://、moz-extension://、safari-extension://)
  • ユーザーが管理していないサードパーティードメインが大半を占めるスタックトレース
ステップ 2 — パターンを確認する

候補ごとに、$exception イベントのサンプルを取得し、抑制する対象として意図したパターンと一致することを確認します。

posthog:query-error-tracking-issue-events
{
  "issueId": "<candidate_issue_id>",
  "limit": 10,
  "include": ["exception", "stacktrace", "environment", "navigation"]
}

onlyAppFrames のデフォルトは true ですが、ノイズを調査するときは通常、サードパーティのフレームを表示したいはずです。onlyAppFrames: false を渡すと、スタックに拡張機能の URL やベンダーのドメインが表示されます。

次の点を確認します。

  • サンプル全体で例外の型またはメッセージテキストに一貫性がある
  • URL/ユーザーエージェント/ブラウザーに、ノイズに混じって実際のユーザートラフィックが含まれていない
  • このパターンを抑制しても、同じ型を持つ将来の実際のバグが隠れない

サンプルのいずれかが一致しない場合は、フィルターを絞り込むか、その候補を見送ってください。

ステップ 3 — フィルターの範囲を厳密にする

抑制ルールは、グルーピングルールと同じフィルター形式で設定します。error-tracking-suppression-rules-create ツールの説明では、全件に一致するルールや、範囲が広すぎるルールを作成しないよう明記されています。可能な限り具体的なプロパティの組み合わせで照合してください。

ノイズのパターン推奨フィルター
Chrome 拡張機能のエラー$exception_sources icontains "chrome-extension://"
Firefox 拡張機能のエラー$exception_sources icontains "moz-extension://"
Safari 拡張機能のエラー$exception_sources icontains "safari-extension://"
ResizeObserver ループ$exception_values icontains "ResizeObserver loop"(メッセージが具体的なため、型フィルターは任意です)
クロスオリジンの「Script error.」$exception_values icontains "Script error." AND $exception_types exact "Error"
ボットのユーザーエージェント単一の語句には $raw_user_agent regex "(?i)bot" を使用します。1 つのルールで複数のボット/クローラーの目印に一致させる場合は、以下の選択パターンを参照してください
サードパーティのネットワークビーコンの失敗$exception_sources icontains "<vendor-domain>" AND 型フィルター(例:$exception_types exact "TypeError")

標準的な例外プロパティ($exception_types、$exception_values、 $exception_sources、$exception_functions)は、イベントのキャプチャ時に配列として記録されます。 PostHog のプロパティフィルターではこれらが特別に処理され、各フィルターは個々の配列要素と照合されます。そのため、すべての標準演算子(exact、 is_not、icontains、not_icontains、regex、not_regex)は、値をそのまま指定して機能します。exact "TypeError" のように指定し、exact '["TypeError"]' や regex '"TypeError"' のようには指定しないでください。

単数形のプロパティ($exception_type、$exception_message)と $exception_stack_trace_raw は、イベントの 1%未満にしか記録されません。これらを使ってフィルタリングすると、ルールが一致しないままになることがあります。

抑制ルールおよびグルーピングルールの regex 演算子は、HogVM の Operation::Regex にコンパイルされるため、大文字と小文字を区別します。大文字と小文字を区別しない照合には、インラインフラグ (?i) を使用してください(例:(?i)headlesschrome)。

複数のボットまたはクローラーの語句に一致させるには、選択のためのパイプをそのまま使用します。API を呼び出す際は、これを regex フィルターの value フィールドに渡してください(パーサーによってクローラーの目印が正規化されて消えることがあるため、$user_agent を解析した値より $raw_user_agent の方が信頼性が高いです)。

(?i)(HeadlessChrome|bot|crawler|spider)

可能な限り、2 つ以上の条件を AND で組み合わせてください。たとえば、型とメッセージ、またはメッセージと URL パターンを組み合わせることで、実際のノイズに対して具体的なルールになります。

ステップ 4 — 抑制するか、サンプリングするかを決める

ある程度の可視性を保ちたい場合は、sampling_rate に 0 から 1 の値を指定します。

  • sampling_rate: 1 — 該当するものをすべて破棄します(完全に抑制)。
  • sampling_rate: 0.95 — 該当イベントの 95% を破棄し、5% をセンチネルデータとして残します。
  • sampling_rate: 0.5 — 半分の割合で残します。大量に発生するものの、実際のエラーである場合に役立ちます。

パターンが純粋なノイズだと確信できない場合は、デフォルトでサンプリング率を 1.0 未満にしてください。データからルールが実際の問題を捕捉していないと分かった後で、1.0 に引き上げられます。

ステップ 5 — ライブデータにフィルターを試しに適用する

確認を求める前に、候補のフィルターをイシュー一覧に対して実行し、過去 7 日間にルールが捕捉するイシューを正確に確認できるようにします。query-error-tracking-issues-list は filterGroup パラメーターを通じて、抑制ルールと同じプロパティフィルター形式を受け付けます。そのため、一般的な AND のみのルールでは、ルールのリーフフィルターをそのまま渡せます。HogQL への変換は不要です。

posthog:query-error-tracking-issues-list
{
  "filterGroup": [
    { "type": "event", "key": "$exception_types", "operator": "exact", "value": "Error" },
    { "type": "event", "key": "$exception_values", "operator": "icontains", "value": "ResizeObserver loop" }
  ],
  "dateRange": { "date_from": "-7d" },
  "status": "all",
  "filterTestAccounts": false,
  "orderBy": "occurrences",
  "limit": 25
}

抑制プレビューでは、次のデフォルト値を必ず上書きしてください。

  • status: "all" — 抑制はイシューのステータスにかかわらず適用されるため、デフォルトの active フィルターによって、すでにアーカイブされたノイズが隠れないようにします。
  • filterTestAccounts: false — 取り込み時にルールはテストアカウントの切り替え設定を参照しません。プレビューも本番環境の実態に合わせる必要があります。

各行は、ルールが捕捉するイシューを 1 件ずつ示します。name(例外の種類)、description(サンプルメッセージ)、source、library に加えて、aggregations.occurrences と aggregations.users が含まれます。イシュー一覧そのものがイシューごとの内訳です。すべての行を確認してください。

最も重要な安全確認事項:結果を調べ、name/description/source が、ノイズではなくチームが修正したい実際のバグに見えるイシューがないか確認してください。メッセージテキストだけで絞り込んだフィルターは、同じフレーズを含む無関係なイシューにも定期的に一致します。ルールが有効になった後、この失敗によって実際のデータが気付かれないまま失われます。疑わしいものが見つかった場合は、フィルターを絞り込み(ステップ 3)、本物のノイズパターンだけが一覧に残るまでこのステップを再実行してください。

ステップ 6 でユーザーに提示する影響範囲の合計値を算出するため、各行の aggregations.occurrences と aggregations.users を合計してください。limit を超えるイシューを含む正確な合計が必要な場合は、offset を使ってページネーションするか、このステップの最後にある HogQL の集計に切り替えてください。

完全なスタックトレース付きの具体的なサンプルイベントを 1 件か 2 件確認するには、最も疑わしいイシューについて query-error-tracking-issue-events を実行してください。

posthog:query-error-tracking-issue-events
{
  "issueId": "<id from the list>",
  "limit": 3,
  "include": ["exception", "stacktrace", "environment", "navigation"],
  "onlyAppFrames": false
}
execute-sql に切り替える必要がある場合

filterGroup はフラットな AND 条件のみをサポートします。次の場合は HogQL を使ってください。

  • 外側のグループまたはネストされた OR のいずれかで、ルールが type: "OR" を使う場合。
  • ルールが filterGroup でサポートされていない演算子(例:between、in、semver_*)を使う場合。
  • イシューごとの集計ではなく、イベント単位の正確な件数が必要な場合。

HogQL の形式は、抑制ルールのバイトコードがコンパイルされる形式に対応しています。マテリアライズされたプロパティ列は NULL 許容のため、coalesce(..., '[]') のラッパーが必要です。これがないと、ClickHouse はクエリを「Nested type Array(String) cannot be inside Nullable type」というエラーで拒否します。

SELECT
  count() AS matched,
  count(DISTINCT distinct_id) AS users,
  count(DISTINCT properties.$exception_issue_id) AS issues
FROM events
WHERE event = '$exception'
  AND timestamp > now() - INTERVAL 7 DAY
  AND arrayExists(
    v -> ifNull(ilike(v, '<pattern>'), 0),
    JSONExtract(coalesce(properties.$exception_values, '[]'), 'Array(String)')
  )

icontains には ilike、exact には通常の等価比較、regex には match(v, '<pattern>') を使ってください。ルールの regex は大文字と小文字を区別します。必要に応じてインラインで (?i) を追加してください。

ステップ 6 — 作成前にユーザーの確認を得る

API では destructive: false とされていますが、抑制は実質的に破壊的な操作です。作成前に、ユーザーに次の内容を提示してください。

  1. 送信するフィルターの正確な内容
  2. ステップ 5 のイシュー一覧と、それぞれの occurrences および users、さらに集計値。実際のバグに見える行があれば明示します。
  3. 既存の抑制ルールと重複するかどうか(最初に posthog:error-tracking-suppression-rules-list を実行します)

明示的な確認を待ってから作成してください。

posthog:error-tracking-suppression-rules-create
{
  "filters": {
    "type": "AND",
    "values": [
      {
        "type": "event",
        "key": "$exception_types",
        "operator": "exact",
        "value": "Error"
      },
      {
        "type": "event",
        "key": "$exception_values",
        "operator": "icontains",
        "value": "ResizeObserver loop"
      }
    ]
  },
  "sampling_rate": 0.95
}

まずは 0.95(95% を破棄し、5% をセンチネルデータとして残す)に設定し、1.0 に引き上げる前に、ルールが実際のエラーを捕捉していないことを確認できるようにします。

ステップ 7 — ルールを 24~48 時間監視する

ルールを作成したら、次のことを行います。

  • ルール作成後の短い期間に対象を絞り、同じフィルターを実行して、一致するイベントが収集されなくなったことを確認します (例:1 時間が経過した時点で WHERE timestamp > now() - INTERVAL 1 HOUR を使用します)。 ステップ 5 の 7 日間の推定を再実行しないでください。抑制が適用されるのは新しいイベントのみなので、期間内の過去のイベントは引き続き残り、件数は減りません。
  • 作成後の期間中に、関連するアクティブなイシューを監視します。関連しないイシューの件数が安定している一方で、関連するイシューの件数が減少すれば、ルールの適用範囲は適切です。
  • 関連する実際のイシューの件数も減少する場合(誤検知)は、ユーザーに直ちに Project settings → Error tracking → Suppression rules からルールを無効にするよう依頼し、フィルターを絞り込んでから再作成してください。ルールの編集または削除を行う MCP ツール(error-tracking-suppression-rules-partial-update、-destroy)は有効になっていないため、エージェントがプログラムから復旧する方法はありません。

ルール作成と同時に実際のイシューが発生しなくなるなど、誤検知の兆候が見られる場合は、ルールを削除するよりも無効にすることを優先してください。そうすれば、フォレンジックレビュー用にルールの設定を保持できます。

ヒント

  • Project settings → Error tracking → Suppression rules には同じデータが表示されます。ユーザーから UI 上でルールがどこにあるか尋ねられた場合は、この場所を案内してください。
  • 抑制は取り込み時に適用されます。過去のイベントから作成された既存のイシューのデータは保持され、新しいイベントのみが破棄されます。
  • ステータスのみを変更する場合(データは破棄せず、アクティブリストから非表示にするだけの場合)は、抑制ルールよりも status: "suppressed" を指定した error-tracking-issues-partial-update を優先してください。
  • スキーマでは、すべてに一致するルールを作成しないようモデルに明示的に警告しています。ユーザーから「拡張機能からのすべてを抑制して」と依頼されても、スタックトレースまたは URL で範囲を絞り込んでください。filters を空のままにしないでください。
  • 絞り込みすぎた抑制ルールは無害です(多少のノイズが漏れます)。広すぎるルールは実際のデータを気付かれないまま破棄します。狭く設定する方を優先してください。

関連スキル

  • grouping-noisy-errors — イベントに有用な情報が残っている場合は、破棄するのではなくマージまたは再グループ化します
  • triaging-error-issues — ノイズを抑えた後に残るイシューの優先順位を付けます

コメント