クラッシュレポート

ドラフトコミュニティグループレポート,

このバージョン:
https://wicg.github.io/crash-reporting/
バージョン履歴:
https://github.com/WICG/crash-reporting/commits/gh-pages
編集者:
(Google Inc.)
参加:
課題を提出 (未解決の課題)
テストスイート:
https://wpt.fyi/results/reporting/

概要

この文書は、Reporting API を使用してブラウザーのクラッシュをサイト所有者に 報告するための仕組みを定義します。

この文書のステータス

この仕様は、Web Platform Incubator Community Group によって公開されました。 これは W3C 標準ではなく、W3C 標準化過程上のものでもありません。 なお、 W3C Community Contributor License Agreement (CLA) の下では、限定的なオプトアウトおよびその他の条件が適用されます。 詳細は W3C Community and Business Groups を参照してください。

1. はじめに

[はじめにがここに入ります]

1.1.

Unstable, Inc. は、そのウェブサイトが実際の環境でどの程度の頻度でクラッシュしているかを よりよく把握したいと考えている。これは、次のヘッダーを配信して デフォルトの報告エンドポイントを定義し、クラッシュレポートをそこに送ることで実現できる:
Reporting-Endpoints: default="https://example.com/reports"

2. 概念

2.1. クラッシュ

2.2. メモリ不足

2.3. 応答なし

3. クラッシュレポート

クラッシュレポートは、 ブラウザー(またはページに必要なそのプロセスのいずれか)が クラッシュしたため、ユーザーがそのページを使い続けられなかったことを示す。 セキュリティ上の理由により、クラッシュについては一意の識別子 (ブラウザーベンダーが解釈できるもの)と、任意でクラッシュの理由 ("oom" など)を除き、詳細は伝達されない。

クラッシュレポートは、report の一種である。

クラッシュレポートは、report type "crash" を持つ。

dictionary CrashReportBody : ReportBody {
  DOMString reason;
  DOMString stack;
  boolean is_top_level;
  DocumentVisibilityState visibility_state;
  object crash_report_api;
};

クラッシュレポートbody は、JavaScript では CrashReportBody によって表され、次のフィールドを含む:

理由 説明
oom ページがメモリ不足になった。
unresponsive ページが応答しないため強制終了された。

注: クラッシュレポートは JavaScript から観測できない。 定義上、それらを受け取るはずのページが受け取ることができないためである。 CrashReportBody の IDL 記述は、帯域外レポートに埋め込むことができる JSON シリアライズ可能なインターフェイスを提供するために、この仕様内に存在する。

3.1. クラッシュ レポートの配信優先度

crash-reporting endpoint が指定されている場合、クラッシュレポートはそこへ配信される。

そうでなく、default endpoint が指定されている場合、クラッシュレポートはそこへ配信される。

どちらの endpoint も指定されていない場合、クラッシュレポートは配信されない。

Reporting-Endpoints: crash-reporting="https://example.com/reports"

4. CrashReportContext インターフェイス

partial interface Window {
  readonly attribute CrashReportContext crashReport;
};

Window オブジェクトは、関連付けられた crashReport を持つ。これは CrashReportContext インスタンスであり、Window と同時に作成される。

crashReport getter の手順は次のとおりである:
  1. thisrelevant global objectassociated Documentfully active でない場合、null を返す。

  2. thisrelevant global objectcrashReport オブジェクトを返す。

[Exposed=Window]
interface CrashReportContext {
    Promise<undefined> initialize(unsigned long long length);
    undefined set(DOMString key, DOMString value);
    undefined delete(DOMString key);
};

CrashReportContext オブジェクトは、関連付けられた internal map を持つ。 これは map であり、その keysvalues はどちらも DOMString である。

user agent は、関連付けられた crash report buffers を持つ。これは map であり、その keysunique internal values、その valuesimplementation-defined 値である。

注: internal map は、 最終的にクラッシュレポートに現れるデータのマップ表現であり、このデータを map セマンティクスを介して扱いやすくするために存在する。ただし、この仕様の実装、 とくにサイト分離をサポートする実装は、最終的にはその内容全体を、 user agentcrash report buffers マップによって追跡される、裏側の共有メモリバッファへシリアライズする可能性が高い。 その マップの values は、ウェブプロセスと、 ウェブプロセスがクラッシュしたときにクラッシュレポートの送信を担当する OS プロセスとにまたがる メモリバッファになることが期待され、その時点では internal map はもはや読み取れない。

CrashReportContext オブジェクトは、関連付けられた backing buffer ID を持つ。これは null または unique internal value であり、初期値は null である。

CrashReportContext オブジェクトは、関連付けられた is buffer initialized boolean を持ち、初期値は false である。

注: このメンバーは、 thisbacking buffer ID に関連付けられた 裏側のメモリバッファが初期化されると、非同期的に true に設定される。

CrashReportContext オブジェクトは、関連付けられた unsigned long long buffer length を持ち、初期値は 0 である。

注: これは initialize() で一度だけ代入され、set() のどの呼び出しでも internal map を裏付けるメモリへ書き込める 最大バイト数を追跡する。

internal map は、 開発者へ CrashReportBody として提供されるすべてのキー/値を保持するために使用される。 サイト分離を備えたブラウザーでは、このデータへ書き込む物理プロセスは、 そこから読み取り クラッシュレポートを送信するプロセスとは異なる。 したがって、実装はこのマップを 2 つのプロセスにまたがる共有メモリ バッファとして維持することが期待される。これは、この API の Chromium 実装が行っていることである。

initialize(length) メソッドの手順は 次のとおりである:
  1. thisrelevant global objectassociated Documentfully active でない場合、throw a new "InvalidStateError" DOMException する。

    注: これは拒否された Promise を通じてユーザーに表面化する。

  2. thisbacking buffer ID が非 null である場合、 throw a new "InvalidStateError" DOMException する。

  3. length が 5 * 1024 * 1024 より大きい場合、throw a new "NotAllowedError" DOMException する。

    注: クラッシュレポート用メモリ バッファの上限は 5 メガバイトである。

  4. thisbuffer lengthlength に設定する。

  5. thisbacking buffer ID を、creating a new unique internal value の結果に設定する。

  6. cachedThisthis とする。

  7. promisea new promise とする。

  8. これらの手順を in parallel に実行する:

    1. backing buffer IDcachedThisbacking buffer ID とする。

    2. length バイトの裏側のメモリストアを作成して初期化するため、 implementation-defined 手順を実行する。

    3. そのようなバッファが作成された場合:

      1. user agentcrash report buffers[backing buffer ID] をその buffer に設定する。

      2. cachedThisis buffer initialized を true に設定する。

    4. cachedThisrelevant global object を指定して、 DOM manipulation task source 上の Queue a global task を行い、 promiseundefinedresolve する。

  9. promise を返す。

set(key, value) メソッドの手順は 次のとおりである:
  1. thisrelevant global objectassociated Documentfully active でない場合、throw a new "InvalidStateError" DOMException する。

  2. thisis buffer initialized が false である場合、 throw a new "InvalidStateError" DOMException する。

    注: これは initialize() が呼び出される前にも、 呼び出された で返された Promise が解決される前にも false である。これは、 set() が、backing buffer ID によって識別される 裏側のバッファが完全に初期化された場合にのみ機能することを保証する。

  3. Set thisinternal map[key] を value に設定する。

  4. serialization を、 thisinternal map を指定して、 serializing a JavaScript value to JSON bytes を行った結果とする。

  5. serializationsizethisbuffer length より大きい場合:

    1. Remove thisinternal map[key]。

    2. Throw a new "NotAllowedError" DOMException する。

  6. backing buffer IDthisbacking buffer ID とする。

  7. serializationuser agentcrash report buffers[backing buffer ID] に書き込む。

delete(key) メソッドの手順は次のとおりである:
  1. thisrelevant global objectassociated Documentfully active でない場合、throw a new "InvalidStateError" DOMException する。

  2. thisis buffer initialized が false である場合、 throw a new "InvalidStateError" DOMException する。

  3. Remove thisinternal map[key]。

  4. serialization を、 thisinternal map を指定して、 serializing a JavaScript value to JSON bytes を行った結果とする。

  5. backing buffer IDthisbacking buffer ID とする。

  6. serializationuser agentcrash report buffers[backing buffer ID] に書き込む。

5. Document Policy との統合

サイト作成者は、一部のレポートについて JavaScript コールスタックの記録を オプトインできる。

この仕様は、名前 include-js-call-stacks-in-crash-reports を持つ configuration point を定義する。その型は boolean であり、デフォルト 値は false である。クラッシュ 報告が有効な Documenttrue として構成されている場合、これによりクラッシュ時点の JavaScript コールスタックの文字列表現がクラッシュレポートに含まれる。

Document-Policy: include-js-call-stacks-in-crash-reports

6. 実装上の考慮事項

6.1. 配信

[REPORTING] は、 この仕様が依存するフレームワークを定義し、 高々ベストエフォートの配信機構を提供する。これはクラッシュの報告に関して とくに当てはまる。おそらく常に、単に報告できない特定の クラッシュ条件が存在する(たとえば、ユーザーエージェントのクラッシュ監視コード内で クラッシュが発生した場合や、ユーザーエージェントをホストしているコンピューターが突然 存在しなくなった場合など)。しかし、多くのクラッシュは 最新のブラウザーによって観測でき、その直接の原因を推測できる。

クラッシュレポートを実装するユーザーエージェントは、その文書を担当するプロセスが クラッシュしたり、オペレーティングシステムによって終了されたりした場合でも機能し続ける 方法で、文書のクラッシュを監視するよう試みるべきである。

このようなモニターを実装する方法は複数あり、特定のクラッシュ原因に対する 信頼性および堅牢性の水準はさまざまである。この仕様は、そのような特定の方法を 規定しようとはしない。

7. サンプルレポート

POST /reports HTTP/1.1
Host: example.com
...
Content-Type: application/reports+json

[{
  "type": "crash",
  "age": 42,
  "url": "https://example.com/",
  "user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0",
  "body": {
    "reason": "oom"
  }
}]

8. セキュリティ上の考慮事項

一般的な帯域外報告に関するセキュリティ上の考慮事項についての議論は、 Reporting API § 8 Security Considerations を参照。

この節の残りの部分では、クラッシュ 報告に固有のセキュリティ上の考慮事項を議論する。

9. プライバシー上の考慮事項

一般的な帯域外報告に関するプライバシー上の考慮事項についての議論は、 Reporting API § 9 Privacy Considerations を参照。

この節の残りの部分では、クラッシュ 報告に固有のプライバシー上の考慮事項を議論する。

9.1. プロセス間の混入

索引

この仕様で定義される 用語

参照により 定義される用語

参考文献

規範的参考文献

[DOCUMENT-POLICY]
Document Policy。ドラフトコミュニティグループ レポート。URL: https://wicg.github.io/document-policy/
[DOM]
Anne van Kesteren。DOM Standard。リビングスタンダード。 URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard。 リビングスタンダード。URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola。Infra Standard。リビングスタンダード。URL: https://infra.spec.whatwg.org/
[REPORTING]
Douglas Creager; Ian Clelland; Mike West。Reporting API。URL: https://w3c.github.io/reporting/
[WEBIDL]
Edgar Chen; Timothy Gu。Web IDL Standard。リビング スタンダード。URL: https://webidl.spec.whatwg.org/

IDL 索引

dictionary CrashReportBody : ReportBody {
  DOMString reason;
  DOMString stack;
  boolean is_top_level;
  DocumentVisibilityState visibility_state;
  object crash_report_api;
};

partial interface Window {
  readonly attribute CrashReportContext crashReport;
};

[Exposed=Window]
interface CrashReportContext {
    Promise<undefined> initialize(unsigned long long length);
    undefined set(DOMString key, DOMString value);
    undefined delete(DOMString key);
};