Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

Firebase Crashlytics 오류 보고서 맞춤설정

이 가이드에서는 Firebase Crashlytics SDK를 사용하여 오류 보고서를 맞춤설정하는 방법을 설명합니다. 기본적으로 Crashlytics는 앱의 모든 사용자에 대한 충돌 보고서를 자동으로 수집합니다(대신 자동 충돌 보고를 끄고 사용자에 대한 보고 선택을 활성화 할 수 있음). Crashlytics는 기본적으로 사용자 정의 키 , 사용자 정의 로그 , 사용자 식별자catch된 예외 의 네 가지 로깅 메커니즘을 제공합니다.

사용자 지정 키 추가

사용자 지정 키는 충돌로 이어지는 앱의 특정 상태를 얻는 데 도움이 됩니다. 임의의 키/값 쌍을 충돌 보고서와 연결한 다음 맞춤 키를 사용하여 Firebase 콘솔에서 충돌 보고서를 검색하고 필터링할 수 있습니다.

  • Crashlytics 대시보드 에서 맞춤 키와 일치하는 문제를 검색할 수 있습니다.
  • 콘솔에서 특정 문제를 검토할 때 각 이벤트에 연결된 사용자 지정 키( 하위 탭)를 보고 사용자 지정 키로 이벤트를 필터링할 수도 있습니다( 페이지 상단의 필터 메뉴).

setCustomValue 메서드를 사용하여 키/값 쌍을 설정합니다. 예를 들어:

빠른

// Set int_key to 100.
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set str_key to "hello".
Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")

오브젝티브-C

정수, 부울 또는 부동 소수점을 설정할 때 값을 @( value ) 로 상자에 넣습니다.

// Set int_key to 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set str_key to "hello".
[[FIRCrashlytics crashlytics] setCustomValue:@"hello" forKey:@"str_key"];

키를 호출하고 다른 값으로 설정하여 기존 키의 값을 수정할 수도 있습니다. 예를 들어:

빠른

Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set int_key to 50 from 100.
Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")

오브젝티브-C

[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set int_key to 50 from 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];

NSDictionary가 유일한 매개변수인 setCustomKeysAndValues ​​메서드를 사용하여 키/값 쌍을 대량으로 추가합니다.

빠른

let keysAndValues = [
                 "string key" : "string value",
                 "string key 2" : "string value 2",
                 "boolean key" : true,
                 "boolean key 2" : false,
                 "float key" : 1.01,
                 "float key 2" : 2.02
                ] as [String : Any]

Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)

오브젝티브-C

NSDictionary *keysAndValues =
    @{@"string key" : @"string value",
      @"string key 2" : @"string value 2",
      @"boolean key" : @(YES),
      @"boolean key 2" : @(NO),
      @"float key" : @(1.01),
      @"float key 2" : @(2.02)};

[[FIRCrashlytics crashlytics] setCustomKeysAndValues: keysAndValues];

사용자 정의 로그 메시지 추가

충돌로 이어지는 이벤트에 대한 더 많은 컨텍스트를 제공하기 위해 사용자 지정 Crashlytics 로그를 앱에 추가할 수 있습니다. Crashlytics는 로그를 비정상 종료 데이터와 연결하고 Firebase 콘솔 의 Crashlytics 페이지에 있는 로그 탭에 표시합니다.

빠른

log() 또는 log(format:, arguments:) 를 사용하여 문제를 정확히 찾아내십시오. 메시지와 함께 유용한 로그 출력을 얻으려면 log() 에 전달하는 객체가 CustomStringConvertible 속성을 준수해야 합니다. log() 는 객체에 대해 정의한 설명 속성을 반환합니다. 예를 들어:

Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")

.log(format:, arguments:)getVaList() 호출에서 반환된 값의 형식을 지정합니다. 예를 들어:

Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))

log() 또는 log(format:, arguments:) 를 사용하는 방법에 대한 자세한 내용은 Crashlytics 참조 문서 를 참조하세요.

오브젝티브-C

log 또는 logWithFormat 을 사용하여 문제를 정확히 찾아내십시오. 메시지와 함께 유용한 로그 출력을 얻으려면 두 메서드 중 하나에 전달하는 개체가 description 인스턴스 속성을 재정의해야 합니다. 예를 들어:

[[FIRCrashlytics crashlytics] log:@"Simple string message"];

[[FIRCrashlytics crashlytics] logWithFormat:@"Higgs-Boson detected! Bailing out... %@", attributesDict];

[[FIRCrashlytics crashlytics] logWithFormat:@"Logging a variable argument list %@" arguments:va_list_arg];

loglogWithFormat 사용 방법에 대한 자세한 내용은 Crashlytics 참조 문서 를 참조하십시오.

사용자 식별자 설정

문제를 진단하려면 특정 충돌을 경험한 사용자를 아는 것이 도움이 되는 경우가 많습니다. Crashlytics에는 충돌 보고서에서 익명으로 사용자를 식별하는 방법이 포함되어 있습니다.

보고서에 사용자 ID를 추가하려면 각 사용자에게 ID 번호, 토큰 또는 해시 값 형식의 고유 식별자를 할당하십시오.

빠른

Crashlytics.crashlytics().setUserID("123456789")

오브젝티브-C

[[FIRCrashlytics crashlytics] setUserID:@"123456789"];

사용자 식별자를 설정한 후 지워야 하는 경우 값을 빈 문자열로 재설정하십시오. 사용자 식별자를 지워도 기존 Crashlytics 레코드는 제거되지 않습니다. 사용자 ID와 연결된 레코드를 삭제해야 하는 경우 Firebase 지원에 문의하세요 .

치명적이지 않은 예외 보고

앱의 비정상 종료를 자동으로 보고하는 것 외에도 Crashlytics를 사용하면 치명적이지 않은 예외를 기록하고 다음에 앱을 시작할 때 이를 보낼 수 있습니다.

recordError 메소드로 NSError 객체를 기록하여 치명적이지 않은 예외를 기록할 수 있습니다. recordError[NSThread callStackReturnAddresses] 를 호출하여 스레드의 호출 스택을 캡처합니다.

빠른

Crashlytics.crashlytics().record(error: error)

오브젝티브-C

[[FIRCrashlytics crashlytics] recordError:error];

recordError 메서드를 사용할 때 NSError 구조와 Crashlytics가 데이터를 사용하여 충돌을 그룹화하는 방법을 이해하는 것이 중요합니다. recordError 메서드를 잘못 사용하면 예측할 수 없는 동작이 발생할 수 있으며 Crashlytics가 앱에 대해 기록된 오류 보고를 제한할 수 있습니다.

NSError 객체에는 세 가지 인수가 있습니다.

  • domain: String
  • code: Int
  • userInfo: [AnyHashable : Any]? = nil

스택 추적 분석을 통해 그룹화되는 치명적인 충돌과 달리 기록된 오류는 domaincode 별로 그룹화됩니다. 이것은 치명적인 충돌과 기록된 오류를 구분하는 중요한 차이점입니다. 예를 들어:

빠른

let userInfo = [
  NSLocalizedDescriptionKey: NSLocalizedString("The request failed.", comment: ""),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString("The response returned a 404.", comment: ""),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString("Does this page exist?", comment: ""),
  "ProductID": "123456",
  "View": "MainView"
]

let error = NSError.init(domain: NSCocoaErrorDomain,
                         code: -1001,
                         userInfo: userInfo)

오브젝티브-C

NSDictionary *userInfo = @{
  NSLocalizedDescriptionKey: NSLocalizedString(@"The request failed.", nil),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The response returned a 404.", nil),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Does this page exist?", nil),
  @"ProductID": @"123456",
  @"View": @"MainView",
};

NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                     code:-1001
                                 userInfo:userInfo];

위의 오류를 기록하면 NSSomeErrorDomain-1001 로 그룹화된 새로운 문제가 생성됩니다. 동일한 도메인 및 코드 값을 사용하는 추가로 기록된 오류는 동일한 문제로 그룹화됩니다. userInfo 개체에 포함된 데이터는 키-값 쌍으로 변환되고 개별 문제 내의 키/로그 섹션에 표시됩니다.

로그 및 사용자 지정 키

충돌 보고서와 마찬가지로 로그 및 사용자 지정 키를 포함하여 NSError 에 컨텍스트를 추가할 수 있습니다. 그러나 충돌에 첨부되는 로그와 기록된 오류에는 차이가 있습니다. 충돌이 발생하고 앱이 다시 실행되면 Crashlytics가 디스크에서 검색하는 로그는 충돌이 발생하기 직전에 작성된 로그입니다. NSError 를 기록하면 앱이 즉시 종료되지 않습니다. Crashlytics는 다음 앱 실행 시에만 기록된 오류 보고서를 보내고 디스크의 로그에 할당된 공간을 제한해야 하기 때문에 NSError 가 기록된 후 충분히 기록할 수 있으므로 Crashlytics가 보내는 시간까지 모든 관련 로그가 순환됩니다. 장치에서 보고합니다. NSErrors 를 기록하고 앱에서 로그 및 사용자 정의 키를 사용할 때 이 균형을 염두에 두십시오.

성능 고려 사항

NSError 를 기록하는 것은 상당히 비용이 많이 들 수 있음을 명심하십시오. 호출할 때 Crashlytics는 스택 해제라는 프로세스를 사용하여 현재 스레드의 호출 스택을 캡처합니다. 이 프로세스는 특히 DWARF 해제(arm64 및 x86)를 지원하는 아키텍처에서 CPU 및 I/O 집약적일 수 있습니다. 해제가 완료되면 정보가 동기적으로 디스크에 기록됩니다. 이렇게 하면 다음 줄이 충돌하는 경우 데이터 손실을 방지할 수 있습니다.

백그라운드 스레드에서 이 API를 호출하는 것이 안전하지만 이 호출을 다른 큐에 전달하면 현재 스택 추적의 컨텍스트가 손실된다는 점을 기억하십시오.

NSException은 어떻습니까?

Crashlytics는 NSException 인스턴스를 직접 로깅하고 기록하는 기능을 제공하지 않습니다. 일반적으로 Cocoa 및 Cocoa Touch API는 예외로부터 안전하지 않습니다. 즉, @catch 를 사용하면 극도의 주의를 기울여 사용하더라도 프로세스에서 의도하지 않은 매우 심각한 부작용이 발생할 수 있습니다. 코드에서 @catch 문을 사용하면 안 됩니다. 주제에 대한 Apple의 문서 를 참조하십시오.

옵트인 보고 활성화

기본적으로 Crashlytics는 앱의 모든 사용자에 대한 오류 보고서를 자동으로 수집합니다. 사용자가 전송하는 데이터를 더 잘 제어할 수 있도록 자동 보고를 비활성화하고 코드에서 선택한 경우에만 Crashlytics에 데이터를 전송하여 보고 선택을 활성화할 수 있습니다.

  1. Info.plist 파일에 새 키를 추가하여 자동 수집을 끕니다.

    • 키: FirebaseCrashlyticsCollectionEnabled
    • 값: false
  2. 런타임 시 Crashlytics 데이터 수집 재정의를 호출하여 선택한 사용자에 대한 수집을 활성화합니다. 재정의 값은 앱이 실행되는 동안 지속되므로 Crashlytics에서 자동으로 보고서를 수집할 수 있습니다.

    자동 충돌 보고를 선택 해제하려면 재정의 값으로 false 를 전달합니다. false 로 설정하면 앱을 다음에 실행할 때까지 새 값이 적용되지 않습니다.

    빠른

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    오브젝티브-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

Crash Insights 데이터 관리

Crash Insights는 익명화된 스택 추적을 다른 Firebase 앱의 추적과 비교하고 문제가 더 큰 추세의 일부인지 알려줌으로써 문제를 해결하는 데 도움이 됩니다. 많은 문제에 대해 Crash Insights는 충돌을 디버그하는 데 도움이 되는 리소스도 제공합니다.

Crash Insights는 집계된 충돌 데이터를 사용하여 일반적인 안정성 추세를 식별합니다. 앱 데이터를 공유하지 않으려면 Firebase 콘솔 의 Crashlytics 문제 목록 상단에 있는 Crash Insights 메뉴에서 Crash Insights를 선택 해제할 수 있습니다.