크래시 보고

커뮤니티 그룹 보고서 초안,

이번 버전:
https://wicg.github.io/crash-reporting/
버전 이력:
https://github.com/WICG/crash-reporting/commits/gh-pages
편집자:
(Google Inc.)
참여:
이슈 제출 (열린 이슈)
테스트 모음:
https://wpt.fyi/results/reporting/

초록

이 문서는 Reporting API를 사용하여 브라우저 크래시를 사이트 소유자에게 보고하기 위한 메커니즘을 정의한다.

이 문서의 상태

이 명세는 웹 플랫폼 인큐베이터 커뮤니티 그룹에서 발행했다. 이는 W3C 표준이 아니며 W3C 표준화 과정에 포함되어 있지도 않다. 다음 사항에 유의하라. W3C 커뮤니티 기여자 라이선스 계약 (CLA)에 따라 제한적인 거부권 및 기타 조건이 적용된다. 자세한 내용은 W3C 커뮤니티 및 비즈니스 그룹을 참조하라.

1. 소개

[소개가 여기에 들어감]

1.1. 예제

Unstable, Inc.는 실제 환경에서 자사 웹사이트가 얼마나 자주 크래시되는지 더 잘 이해하고자 한다. 다음 헤더를 전달하여 기본 보고 엔드포인트를 정의하면 이를 수행할 수 있으며, 크래시 보고는 해당 위치로 전달된다:
Reporting-Endpoints: default="https://example.com/reports"

2. 개념

2.1. 크래시

2.2. 메모리 부족

2.3. 응답 없음

3. 크래시 보고

크래시 보고는 브라우저(또는 페이지에 필요한 브라우저 프로세스 중 하나)가 크래시되어 사용자가 페이지를 계속 사용할 수 없었음을 나타낸다. 보안상의 이유로, 브라우저 공급업체가 해석할 수 있는 고유 식별자와, 선택적으로 크래시 이유(예: "oom")를 제외하고는 크래시에 대한 세부 정보가 전달되지 않는다.

크래시 보고보고의 한 유형이다.

크래시 보고보고 유형은 "crash"이다.

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

크래시 보고body는 JavaScript에서 CrashReportBody로 표현되며, 다음 필드를 포함한다:

Reason 설명
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. this관련 전역 객체연관 Document완전히 활성 상태가 아니면 null을 반환한다.

  2. this관련 전역 객체crashReport 객체를 반환한다.

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

CrashReportContext 객체에는 연결된 internal map이 있으며, 이는 으로, 그 은 모두 DOMString이다.

사용자 에이전트에는 연결된 crash report buffers가 있으며, 이는 으로, 그 고유한 내부 값이고, 그 구현 정의 값이다.

참고: internal map은 최종적으로 크래시 보고에 나타날 데이터의 맵 표현이며, 의미 체계를 통해 이 데이터와 인체공학적으로 상호작용하기 위해 존재한다. 그러나 이 명세의 구현, 특히 사이트 격리를 지원하는 구현은 결국 그 전체 내용을 사용자 에이전트crash report buffers 맵이 추적하는 backing shared memory buffer로 직렬화할 가능성이 높다. 해당 맵의 은 웹 프로세스와, 웹 프로세스가 크래시될 때 크래시 보고 전송을 담당하는 OS 프로세스 사이에 걸쳐 있는 메모리 버퍼일 것으로 예상되며, 그 internal map은 더 이상 읽을 수 없게 된다.

CrashReportContext 객체에는 연결된 backing buffer ID가 있으며, 이는 null 또는 고유한 내부 값이다. 초기값은 null이다.

CrashReportContext 객체에는 연결된 is buffer initialized boolean이 있으며, 초기값은 false이다.

참고: 이 멤버는 thisbacking buffer ID와 연결된 backing memory buffer가 초기화되면 비동기적으로 true로 설정된다.

CrashReportContext 객체에는 연결된 unsigned long long buffer length가 있으며, 초기값은 0이다.

참고: 이는 initialize()에서 한 번 할당되며, set() 호출이 internal map을 backing하는 메모리에 쓸 수 있는 최대 바이트 수를 추적한다.

internal map은 개발자에게 CrashReportBody를 통해 제공될 모든 키/값을 보관하는 데 사용된다. 사이트 격리가 있는 브라우저에서는 이 데이터에 쓰는 물리적 프로세스가 이를 읽고 크래시 보고를 보내는 프로세스와 다르다. 따라서 구현은 이 맵을 두 프로세스에 걸쳐 있는 공유 메모리 버퍼로 유지할 것으로 예상된다. Chromium의 이 API 구현은 이렇게 동작한다.

initialize(length) 메서드 단계는 다음과 같다:
  1. this관련 전역 객체연관 Document완전히 활성 상태가 아니면, throw a new "InvalidStateError" DOMException을 throw한다.

    참고: 이는 거부된 Promise를 통해 사용자에게 드러난다.

  2. thisbacking buffer ID가 null이 아니면, throw a new "InvalidStateError" DOMException을 throw한다.

  3. length가 5 * 1024 * 1024보다 크면, throw a new "NotAllowedError" DOMException을 throw한다.

    참고: 크래시 보고 메모리 버퍼의 제한은 5메가바이트이다.

  4. thisbuffer lengthlength로 설정한다.

  5. thisbacking buffer ID새 고유 내부 값 생성의 결과로 설정한다.

  6. cachedThisthis로 둔다.

  7. promise새 promise로 둔다.

  8. 다음 단계를 병렬로 실행한다:

    1. backing buffer IDcachedThisbacking buffer ID로 둔다.

    2. length 바이트의 backing memory store를 생성하고 초기화하기 위해 구현 정의 단계를 실행한다.

    3. 그러한 버퍼가 생성되었다면:

      1. 사용자 에이전트crash report buffers[backing buffer ID]를 해당 버퍼로 설정한다.

      2. cachedThisis buffer initialized를 true로 설정한다.

    4. cachedThis관련 전역 객체가 주어졌을 때, promiseundefinedresolve하도록, DOM 조작 태스크 소스전역 태스크를 큐에 넣는다.

  9. promise를 반환한다.

set(key, value) 메서드 단계는 다음과 같다:
  1. this관련 전역 객체연관 Document완전히 활성 상태가 아니면, throw a new "InvalidStateError" DOMException을 throw한다.

  2. thisis buffer initialized가 false이면, throw a new "InvalidStateError" DOMException을 throw한다.

    참고: 이는 initialize()가 호출되기 전과, 호출된 지만 반환된 Promise가 resolve되기 전 모두에서 false이다. 이는 set()backing buffer ID로 식별되는 backing buffer가 완전히 초기화되었을 때만 동작하도록 보장한다.

  3. Set thisinternal map[key]를 value로 설정한다.

  4. serializationthisinternal map이 주어졌을 때 JavaScript 값을 JSON 바이트로 직렬화한 결과로 둔다.

  5. serialization크기thisbuffer length보다 크면:

    1. Remove thisinternal map[key]를 제거한다.

    2. Throw a new "NotAllowedError" DOMException을 throw한다.

  6. backing buffer IDthisbacking buffer ID로 둔다.

  7. serialization사용자 에이전트crash report buffers[backing buffer ID]에 쓴다.

delete(key) 메서드 단계는 다음과 같다:
  1. this관련 전역 객체연관 Document완전히 활성 상태가 아니면, throw a new "InvalidStateError" DOMException을 throw한다.

  2. thisis buffer initialized가 false이면, throw a new "InvalidStateError" DOMException을 throw한다.

  3. Remove thisinternal map[key]를 제거한다.

  4. serializationthisinternal map이 주어졌을 때 JavaScript 값을 JSON 바이트로 직렬화한 결과로 둔다.

  5. backing buffer IDthisbacking buffer ID로 둔다.

  6. serialization사용자 에이전트crash report buffers[backing buffer ID]에 쓴다.

5. Document Policy 통합

사이트 작성자는 일부 보고에 JavaScript 호출 스택 기록을 포함하도록 선택할 수 있다.

이 명세는 이름이 include-js-call-stacks-in-crash-reportsconfiguration point를 정의한다. 그 유형은 boolean이고 기본 값은 false이다. 크래시 보고가 활성화된 Document에서 true로 구성되면, 크래시 당시의 JavaScript 호출 스택 문자열 표현이 크래시 보고에 포함된다.

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

6. 구현 고려 사항

6.1. 전달

이 명세가 의존하는 프레임워크를 정의하는 [REPORTING]은 많아야 최선 노력 방식의 전달 메커니즘을 제공한다. 크래시 보고의 경우에는 특히 그렇다. 보고할 수 없는 특정 크래시 조건은 아마도 항상 존재할 것이다. 예를 들어, 크래시가 사용자 에이전트의 크래시 모니터링 코드 내에서 발생하거나, 사용자 에이전트를 호스트하는 컴퓨터가 갑자기 존재하지 않게 되는 경우가 그렇다. 그러나 많은 크래시는 현대 브라우저에서 관찰될 수 있으며, 그 직접적인 원인을 추론할 수 있다.

크래시 보고를 구현하는 사용자 에이전트는 해당 문서를 담당하는 프로세스가 크래시되거나 운영 체제에 의해 종료되더라도 계속 동작할 수 있는 방식으로 문서의 크래시를 모니터링하려고 시도해야 한다(SHOULD).

이러한 모니터를 구현하는 방법은 여러 가지가 있으며, 특정 크래시 원인에 대한 신뢰성과 견고성 수준도 다양하다. 이 명세는 그러한 특정 방법을 규정하려고 하지 않는다.

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 보안 고려 사항을 참조하라.

이 섹션의 나머지 부분에서는 특히 크래시 보고에 대한 보안 고려 사항을 논의한다.

9. 개인정보 보호 고려 사항

대역 외 보고 전반을 둘러싼 개인정보 보호 고려 사항에 대한 논의는 Reporting API § 9 개인정보 보호 고려 사항을 참조하라.

이 섹션의 나머지 부분에서는 특히 크래시 보고에 대한 개인정보 보호 고려 사항을 논의한다.

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);
};