Firebase Crashlytics 비정상 종료 보고서 맞춤설정


Crashlytics 대시보드에서 문제를 클릭하여 세부정보를 확인할 수 있습니다. 이벤트 보고서 이러한 보고서를 맞춤설정하면 보고되는 이벤트와 관련된 상황, 그리고 앱에서 발생하는 상황 Crashlytics

  • 앱에서 Google Analytics용 Firebase SDK 이러한 로그를 사용하면 앱에서 Crashlytics 수집 이벤트로 이어지는 사용자 작업

  • 자동 비정상 종료 보고를 사용 중지하고 사용자에 대해 보고 선택 옵션을 사용 설정합니다. 참고로 기본적으로 Crashlytics에서 모든 캠페인의 비정상 종료 보고서를 자동으로 수집합니다. 확인할 수 있습니다.

커스텀 키 추가

커스텀 키를 사용하면 비정상 종료로 이어지는 앱의 구체적인 상태를 확인할 수 있습니다. 임의의 키-값 쌍을 비정상 종료 보고서에 연결한 다음 커스텀 키를 사용하여 Firebase 콘솔에서 비정상 종료 보고서를 검색하고 필터링합니다.

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

setCustomValue 메서드를 사용하여 키-값 쌍을 설정합니다. 예를 들면 다음과 같습니다.

Swift

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

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

Objective-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"];

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

Swift

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

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

Objective-C

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

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

setCustomKeysAndValues 메서드에 NSDictionary를 유일한 매개변수로 사용하여 키-값 쌍을 일괄 추가합니다.

Swift

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)

Objective-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는 로그를 연결합니다. 데이터를 가져와 Crashlytics 페이지에 표시합니다. Firebase 콘솔로그 탭 아래

Swift

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 참고 참조 문서를 확인하세요.

Objective-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 번호, 토큰 또는 해시 값 형식으로 고유 식별자를 할당합니다.

Swift

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

Objective-C

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

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

심각하지 않은 예외 보고

앱의 비정상 종료를 자동으로 보고하는 것 외에도 Crashlytics를 사용하면 심각하지 않은 예외를 기록하고 다음 번에 앱이 있습니다.

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

Swift

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

Objective-C

[[FIRCrashlytics crashlytics] recordError:error];

recordError 메서드를 사용할 때는 NSError Crashlytics가 데이터를 사용하여 비정상 종료를 그룹화하는 방법을 알아봅니다. 틀림 recordError 메서드를 사용하면 예기치 않은 동작이 발생할 수 있으며 Crashlytics가 앱에 로깅된 오류의 보고를 제한하도록 합니다.

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

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

스택 트레이스 분석을 통해 그룹화되는 심각한 비정상 종료와는 달리 로깅된 오류는 domaincode로 그룹화됩니다. 이 점이 심각한 비정상 종료와 로깅된 오류의 중요한 차이점입니다. 예를 들면 다음과 같습니다.

Swift

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)

Objective-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 문서 자세히 알아볼 수 있습니다

스택 트레이스 맞춤설정

앱을 네이티브가 아닌 환경(예: C++ 또는 Unity)에서 실행하는 경우 Exception Model API를 사용하여 앱의 네이티브 예외 형식으로 비정상 종료 메타데이터를 보고할 수 있습니다. 보고된 예외는 심각하지 않은 예외로 표시됩니다.

Swift

var  ex = ExceptionModel(name:"FooException", reason:"There was a foo.")
ex.stackTrace = [
  StackFrame(symbol:"makeError", file:"handler.js", line:495),
  StackFrame(symbol:"then", file:"routes.js", line:102),
  StackFrame(symbol:"main", file:"app.js", line:12),
]

crashlytics.record(exceptionModel:ex)

Objective-C

FIRExceptionModel *model =
    [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."];
model.stackTrace = @[
  [FIRStackFrame stackFrameWithSymbol:@"makeError" file:@"handler.js" line:495],
  [FIRStackFrame stackFrameWithSymbol:@"then" file:@"routes.js" line:102],
  [FIRStackFrame stackFrameWithSymbol:@"main" file:@"app.js" line:12],
];

[[FIRCrashlytics crashlytics] recordExceptionModel:model];

주소만을 사용하여 커스텀 스택 프레임을 초기화할 수도 있습니다.

Swift

var  ex = ExceptionModel.init(name:"FooException", reason:"There was a foo.")
ex.stackTrace = [
  StackFrame(address:0xfa12123),
  StackFrame(address:12412412),
  StackFrame(address:194129124),
]

crashlytics.record(exceptionModel:ex)

Objective-C

FIRExceptionModel *model =
    [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."];
model.stackTrace = @[
  [FIRStackFrame stackFrameWithAddress:0xfa12123],
  [FIRStackFrame stackFrameWithAddress:12412412],
  [FIRStackFrame stackFrameWithAddress:194129124],
];


[[FIRCrashlytics crashlytics] recordExceptionModel:model];

탐색경로 로그 가져오기

탐색경로 로그를 사용하면 사용자와의 상호작용을 더 잘 이해할 수 있습니다. 앱에서 비정상 종료, 심각하지 않은 문제, ANR 이벤트로 이어지는 경우가 있습니다. 이러한 로그는 도움이 될 수 있습니다

탐색경로 로그는 Google 애널리틱스를 기반으로 하므로 탐색경로 로그를 얻으려면 ~해야 해 Google 애널리틱스 사용 설정 설정되고 Google Analytics용 Firebase SDK 추가 해야 합니다. 이러한 요구사항이 충족되면 탐색경로 로그가 자동으로 세부정보를 볼 때 로그 탭 내의 이벤트 데이터에 포함됨 문제를 일으킬 수 있습니다

Analytics SDK screen_view 이벤트를 자동으로 로깅 그러면 탐색경로 로그에 광고가 표시되기 전에 조회된 화면 목록이 ANR 이벤트 등이 있습니다 screen_view 탐색경로 로그에는 firebase_screen_class 매개변수

탐색경로 로그에는 맞춤 이벤트를 기록하며, 사용자는 이 이벤트를 세션(이벤트의 매개변수 데이터 포함) 이 데이터를 통해 비정상 종료, 심각하지 않은 문제, ANR 이벤트로 이어지는 사용자 작업의 비율

참고: Google Analytics 데이터 수집 및 사용 제어 여기에는 탐색경로 로그를 채우는 데이터도 포함됩니다.

보고 선택 옵션 사용 설정

기본적으로 Crashlytics에서는 확인할 수 있습니다. 사용자가 자신이 전송하는 데이터를 더 세부적으로 관리할 수 있도록 하려면 자동 보고를 사용 중지하고 Crashlytics는 코드에서 다음과 같이 선택할 때 사용됩니다.

  1. Info.plist 파일에 새 키를 추가하여 자동 수집을 사용 중지합니다.

    • 키: FirebaseCrashlyticsCollectionEnabled
    • 값: false
  2. Crashlytics 데이터를 호출하여 일부 사용자에 대해 수집을 사용 설정합니다. 컬렉션을 재정의해야 합니다. 재정의 값은 Crashlytics에서 자동으로 보고서를 수집할 수 있습니다.

    자동 비정상 종료 보고를 선택 해제하려면 false를 재정의 값으로 전달합니다. false로 설정하면 앱이 다음 번 실행될 때까지 새 값이 적용되지 않습니다.

    Swift

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    Objective-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

비정상 종료 통계 데이터 관리

비정상 종료 통계는 익명화된 스택 트레이스를 다른 Firebase 앱의 트레이스와 비교하여 문제가 더 큰 트렌드에 속하는지 여부를 파악함으로써 문제를 해결하는 데 도움을 줍니다. 비정상 종료 통계가 디버깅에 도움이 되는 경우도 많습니다.

비정상 종료 통계에서는 비정상 종료 집계 데이터를 사용하여 공통적인 안정성 트렌드를 파악합니다. 앱 데이터를 공유하지 않으려면 비정상 종료 통계를 선택 해제하면 됩니다. Crashlytics 문제 목록 상단의 비정상 종료 통계 메뉴에서 (Firebase 콘솔에서 확인)