Crashlytics 및 (선택사항) Firebase 세션 데이터를 BigQuery로 내보낸 후 데이터를 사용하여 작업을 시작할 수 있습니다.
SQL 쿼리를 사용하여 데이터 분석하기
Crashlytics 데이터에 대해 쿼리를 실행하여 맞춤 보고서와 요약을 생성할 수 있습니다. 이러한 유형의 맞춤 보고서는 Firebase Console의 Crashlytics 대시보드에서 사용할 수 없으므로 비정상 종료 데이터에 대한 분석 및 이해를 보완할 수 있습니다. 이 페이지의 뒷부분에 있는 쿼리 예시 모음을 참고하세요.여러 데이터 세트의 데이터 결합
예를 들어 Crashlytics 데이터 내보내기를 설정할 때 Firebase 세션 데이터를 내보내도록 선택하면 비정상 종료가 발생하지 않은 사용자 및 비정상 종료가 발생하지 않은 세션에 대한 이해도를 높일 수 있습니다(쿼리 예시 참고). 또한 다양한 Firebase 제품 (예: Performance Monitoring) 또는 Google Analytics에서 데이터를 내보낸 다음 BigQuery에서 Crashlytics 데이터와 함께 해당 데이터를 조인하고 분석할 수 있습니다.뷰 만들기
BigQuery UI를 사용하여 SQL 쿼리로 정의된 가상 테이블인 뷰를 만들 수 있습니다. 다양한 유형의 뷰와 뷰를 만드는 방법에 대한 자세한 내용은 BigQuery 문서를 참조하세요.
데이터 세트 스키마에 대한 자세한 내용은 BigQuery에서 내보낸 데이터의 데이터 세트 스키마를 참고하세요.
BigQuery SQL 알아보기
대화형 쿼리 작업, 일괄 쿼리 작업, 연속 쿼리 작업 등 실행할 수 있는 쿼리 유형에 대해 알아봅니다.
BigQuery에서 지원되는 문 및 SQL 언어에 대해 알아봅니다.
AI 기반 지원 (Gemini)을 사용하여 쿼리를 작성하는 방법을 알아보세요.
Crashlytics 데이터의 쿼리 예시
이 섹션에서는 내보낸 Crashlytics 데이터 및 Firebase 세션 데이터와 함께 BigQuery SQL을 사용하는 방법을 보여주는 몇 가지 예시 상황과 예시 쿼리를 제공합니다.
- Firebase 세션 데이터를 사용하여 비정상 종료가 발생하지 않은 측정항목 계산
- 일별 비정상 종료
- 가장 심각한 비정상 종료 파악
- 비정상 종료가 가장 많이 발생한 상위 10개 기기
- 맞춤 키별 필터링
- 사용자 ID 추출
- 특정 비정상 종료 문제를 경험한 모든 사용자 파악
- 비정상 종료 문제의 영향을 받은 사용자 수(국가별 분류)
- 상위 5개 문제(오늘 기준)
- 상위 5개 문제(DATE~오늘)
예시 1: Firebase 세션 데이터를 사용하여 비정상 종료가 발생하지 않은 측정항목 계산
최신 버전에서는 중요한 사용자 여정에서 발생하는 비정상 종료를 해결하기 위해 앱을 대대적으로 개편했습니다. 사용자로부터 좋은 리뷰를 받았지만 앱이 이전보다 더 안정적이라는 정량적 증거가 필요합니다.
비정상 종료가 발생하지 않은 측정항목을 사용하면 이 정보를 제공할 수 있습니다. 이러한 측정항목은 앱의 전반적인 상태를 파악하는 데 도움이 되는 중요한 측정값입니다. Firebase 세션 데이터와 Crashlytics 이벤트를 사용하면 기본 쿼리로 이러한 측정항목을 계산할 수 있습니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
특정 버전의 비정상 종료가 발생하지 않은 사용자:
SELECT TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date, (1 - (COUNT (DISTINCT installation_uuid) / COUNT (DISTINCT instance_id))) AS CFU FROM `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions LEFT JOIN `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics ON TIMESTAMP_TRUNC(sessions.event_timestamp,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) WHERE crashlytics.error_type="FATAL" AND crashlytics.application.display_version="APP_VERSION" AND sessions.application.display_version = "APP_VERSION" GROUP BY event_date ORDER BY event_date
지난 1주일(지난 168시간) 동안 비정상 종료가 발생하지 않은 세션:
SELECT TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) AS event_date, (1 - (COUNT (DISTINCT crashlytics.firebase_session_id) / COUNT (DISTINCT sessions.session_id))) AS CFS FROM `PROJECT_ID.firebase_sessions.PACKAGE_NAME_ANDROID` AS sessions LEFT JOIN `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` AS crashlytics ON TIMESTAMP_TRUNC(sessions.event_timestamp,DAY) = TIMESTAMP_TRUNC(crashlytics.event_timestamp,DAY) WHERE crashlytics.error_type="FATAL" AND _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR) AND _PARTITIONTIME < CURRENT_TIMESTAMP() GROUP BY event_date ORDER BY event_date
예시 2: 날짜별 비정상 종료
버그를 최대한 해결한 후 드디어 팀이 신규 사진 공유 앱을 출시할 준비가 되었다고 생각합니다. 출시 전에 팀은 지난 달의 일일 비정상 종료 횟수를 확인하여, 그 동안 진행한 버그 수정 작업을 통해 앱이 얼마나 더 안정화되었는지 알아보려고 합니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT COUNT(DISTINCT event_id) AS number_of_crashes, FORMAT_TIMESTAMP("%F", event_timestamp) AS date_of_crashes FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` GROUP BY date_of_crashes ORDER BY date_of_crashes DESC LIMIT 30;
예시 3: 가장 심각한 비정상 종료 파악
프로덕션 계획의 우선순위를 적절하게 설정하기 위해 앱에서 가장 심각한 비정상 종료 중 상위 10개를 찾으려고 합니다. 관련 데이터 포인트를 제공하는 쿼리를 생성합니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT DISTINCT issue_id, COUNT(DISTINCT event_id) AS number_of_crashes, COUNT(DISTINCT installation_uuid) AS number_of_impacted_user, blame_frame.file, blame_frame.line FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` WHERE event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(),INTERVAL 168 HOUR) AND event_timestamp < CURRENT_TIMESTAMP() GROUP BY issue_id, blame_frame.file, blame_frame.line ORDER BY number_of_crashes DESC LIMIT 10;
예시 4: 비정상 종료가 가장 많이 발생한 상위 10개 기기
가을은 신규 스마트폰이 출시되는 시기입니다. 귀사는 이 시기가 기기별로 새로운 문제가 발견되는 시기이기도 하다는 것을 알고 있습니다. 특히 Android의 경우 그렇습니다. 앞으로 발생할 호환성 문제를 성공적으로 해결하기 위해, 지난 일주일(168시간) 동안 비정상 종료가 가장 많이 발생했던 10대의 기기를 식별하는 쿼리를 작성합니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT device.model, COUNT(DISTINCT event_id) AS number_of_crashes FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` WHERE event_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 168 HOUR) AND event_timestamp < CURRENT_TIMESTAMP() GROUP BY device.model ORDER BY number_of_crashes DESC LIMIT 10;
예시 5: 커스텀 키별 필터링
여러분은 게임 개발자로, 게임의 어느 레벨에서 비정상 종료가 가장 많이 발생하는지 알고 싶어 합니다.
이 통계를 추적하는 데 도움이 되도록 current_level이라는 커스텀 Crashlytics 키(iOS+ | Android | Flutter | Unity)를 설정하고 사용자가 새 레벨에 도달할 때마다 업데이트합니다.
Swift
Crashlytics.sharedInstance().setIntValue(3, forKey: "current_level");
Objective-C
CrashlyticsKit setIntValue:3 forKey:@"current_level";
자바
Crashlytics.setInt("current_level", 3);
BigQuery로 내보낼 때 이 키를 사용하면 각 비정상 종료 이벤트와 연결된 current_level 값의 분산을 보고하는 쿼리를 작성할 수 있습니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT
COUNT(DISTINCT event_id) AS num_of_crashes,
value
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
UNNEST(custom_keys)
WHERE
key = "current_level"
GROUP BY
key,
value
ORDER BY
num_of_crashes DESC예 6: 사용자 ID 추출
사전 체험판 Android 앱을 하나 갖고 있습니다. 사용자 대부분은 이 앱을 좋아하지만 세 명의 사용자에게는 이례적으로 자주 비정상 종료가 발생했습니다. 문제의 원인을 파악하기 위해, 팀은 사용자 ID를 사용하여 사용자에게 발생하는 모든 비정상 종료 이벤트를 가져오는 쿼리를 작성합니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT *
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
user.id IN ("USER_ID_1", "USER_ID_2", "USER_ID_3")
ORDER BY
user.id
예시 7: 특정 비정상 종료 문제를 경험한 모든 사용자 파악
팀에서 실수로 베타 테스터 그룹을 대상으로 심각한 버그를 배포했습니다. 팀은 위의 '가장 심각한 비정상 종료 파악' 예시의 쿼리를 사용하여 특정 비정상 종료 문제 ID를 파악할 수 있었습니다. 이제 이들은 이 비정상 종료의 영향을 받은 앱 사용자 목록을 추출하는 다음과 같은 쿼리를 실행합니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT user.id as user_id
FROM
`PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`
WHERE
issue_id = "ISSUE_ID"
AND application.display_version = "APP_VERSION"
AND user.id != ""
ORDER BY
user.id;예시 8: 비정상 종료 문제의 영향을 받은 사용자 수(국가별 분류)
팀에서 새 버전 출시 중 심각한 버그를 탐지했습니다. 위의 '가장 심각한 비정상 종료 파악' 예시의 쿼리를 사용하여 특정 비정상 종료 문제 ID를 파악할 수 있었습니다. 이제 이 비정상 종료가 전 세계 여러 국가의 사용자에게 확산되는지 여부를 관찰하려고 합니다.
이 쿼리를 작성하려면 팀에서 다음을 수행해야 합니다.
Google Analytics 데이터를 BigQuery로 내보내도록 사용 설정합니다. BigQuery에 프로젝트 데이터 내보내기를 참조하세요.
사용자 ID가 Google Analytics SDK 및 Crashlytics SDK에 모두 전달되도록 앱을 업데이트합니다.
Swift
Crashlytics.sharedInstance().setUserIdentifier("123456789"); Analytics.setUserID("123456789");Objective-C
CrashlyticsKit setUserIdentifier:@"123456789"; FIRAnalytics setUserID:@"12345678 9";자바
Crashlytics.setUserIdentifier("123456789"); mFirebaseAnalytics.setUserId("123456789");사용자 ID 필드를 사용하여 Google Analytics 데이터 세트의 이벤트를 Crashlytics 데이터 세트의 비정상 종료와 조인하는 쿼리를 작성합니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과
ANDROID대신 번들 ID와IOS를 사용하세요.SELECT DISTINCT c.issue_id, a.geo.country, COUNT(DISTINCT c.user.id) as num_users_impacted FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID` c INNER JOIN `PROJECT_ID.analytics_TABLE_NAME.events_*` a on c.user.id = a.user_id WHERE c.issue_id = "ISSUE_ID" AND a._TABLE_SUFFIX BETWEEN '20190101' AND '20200101' GROUP BY c.issue_id, a.geo.country, c.user.id
예시 9: 상위 5개 문제(오늘 기준)
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT issue_id, COUNT(DISTINCT event_id) AS events FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME` WHERE DATE(event_timestamp) = CURRENT_DATE() GROUP BY issue_id ORDER BY events DESC LIMIT 5;
예시 10: 상위 5개 문제(DATE~오늘)
배치 테이블과 실시간 테이블을 스티칭 쿼리와 결합하여 안정적인 일괄 데이터에 실시간 정보를 추가할 수도 있습니다. event_id는 기본 키이므로 DISTINCT event_id를 사용하여 두 테이블에서 공통 이벤트를 중복 삭제할 수 있습니다.
다음은 Android 앱의 쿼리 예시입니다. iOS 앱의 경우 패키지 이름과 ANDROID 대신 번들 ID와 IOS를 사용하세요.
SELECT issue_id, COUNT(DISTINCT event_id) AS events FROM ( SELECT issue_id, event_id, event_timestamp FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID_REALTIME` UNION ALL SELECT issue_id, event_id, event_timestamp FROM `PROJECT_ID.firebase_crashlytics.PACKAGE_NAME_ANDROID`) WHERE event_timestamp >= PARSE_TIMESTAMP("%Y_%m_%d", "YYYY_MM_DD") GROUP BY issue_id ORDER BY events DESC LIMIT 5;
다음 단계
내보낸 데이터와 Looker Studio와 같은 다양한 Google Cloud 서비스를 사용하여 맞춤 대시보드를 빌드합니다.
내보낸 데이터의 데이터 세트 스키마에 대해 알아봅니다.