Crashlytics 에 안 잡힌 크래시: 넣은 버전부터만 보인다
앱 21개에 Firebase Crashlytics 를 넣고 사흘 뒤, 사용자가 겪은 크래시를 Play Console 에서 먼저 발견했습니다. Crashlytics 는 SDK 를 넣은 빌드부터만 보고하고, 사용자 폰에 남아 있는 옛 버전의 크래시는 Play vitals 에만 쌓입니다. 21앱 전수 결과와 지금 쓰는 확인 순서를 정리합니다.
크래시 메일이 조용했다
9월 18일 빌드부터 운영 중인 앱 21개에 Firebase Crashlytics 를 넣었습니다. 크래시가 나면 메일이 오고, 첫날 들어온 크래시 5건은 그날 고쳤습니다. 그 뒤로는 메일이 거의 없어서 「크래시가 별로 없다」 고 여기고 있었습니다.
9월 21일, 마크다운 뷰어 앱의 크래시가 Play Console 에서 발견됐습니다. 사용자 4명이 파일을 만들다 IOException 으로 앱이 꺼진 건이었고, 버전은 1.0.22 와 그 이전이었습니다. Crashlytics 에는 한 줄도 없었습니다.
왜 안 보였나
Crashlytics 는 SDK 가 들어간 빌드에서 난 크래시만 보고합니다. 당연한 얘기지만, 실제로는 이 점이 크게 작용합니다.
- 새 버전을 올려도 모든 사용자가 바로 업데이트하지 않습니다. 자동 업데이트를 꺼 둔 폰, 오래 안 켠 폰에는 몇 주 전 버전이 그대로 돌아갑니다.
- 그 옛 버전에는 Crashlytics 가 없으니, 거기서 나는 크래시는 Firebase 로 가지 않습니다.
- 대신 Google Play 는 SDK 와 상관없이 기기에서 크래시를 모읍니다. Play Console 의 「Android vitals → 비정상 종료 및 ANR」 에 버전별로 쌓입니다.
그러니까 Crashlytics 를 넣은 직후의 「메일이 조용하다」 는 「크래시가 없다」 가 아니라 「새 버전 사용자가 아직 적다」 는 뜻이었습니다.
21앱 전수: 8개 앱에 크래시가 있었다
9월 22일, Play Console 에서 21개 앱의 vitals 를 하나씩 열었습니다. 기간은 지난 28일, 그리고 화면에 기본으로 걸려 있는 「사용자 인식」 필터를 지우고 봤습니다. 이 필터가 걸려 있으면 사용자가 직접 겪은 것으로 분류된 크래시만 보입니다.
- 결과 없음: 13개 앱
- 크래시가 있음: 8개 앱
가장 큰 건 TV 리모컨 앱 세 개에 공통으로 있던 크래시였습니다.
java.lang.SecurityException: Need android.permission.BLUETOOTH_CONNECT permission
at ...ble.HidPeripheral.start
블루투스 연결 권한을 허용하지 않은 상태에서 블루투스 리모컨 모드를 시작하면 앱이 꺼졌습니다. 주 클러스터 기준으로 사용자 수는 세 앱 합쳐 25명(10 · 9 · 6), 버전은 1.2.2 부터 그때 라이브였던 1.2.10 까지 전부였습니다. 그중 Crashlytics 메일로 들어온 건 Crashlytics 가 들어간 1.2.10 의 1건뿐이었습니다.
다른 앱도 비슷했습니다.
- 진드기 촬영 앱: TensorFlow Lite 인터프리터를 닫을 때 나는 네이티브 크래시(
SIGSEGV,TfLiteXNNPackDelegateDelete)가 약 20명. 1.1.12·1.1.13 에만 있었고, 9월 6일 추론(run)과 해제(close)를 같은 잠금으로 묶어 추론 중에는 닫지 않게 한 뒤 버전에는 없었습니다. 고친 뒤에도 옛 버전 사용자 폰에서 계속 나고 있던 겁니다. - QR 스캐너 앱: 문서 모드의 네이티브 크래시(
SIGABRT, onnxruntime)가 1.1.14 에 남아 있었습니다. 1.1.16 에서 고친 문제입니다.
고친 것
리모컨 세 앱(같은 코드인 앱까지 네 앱)은 9월 22일 1.2.12 에서 세 군데를 막았습니다.
- 블루투스 모드를 시작하는 입구(
startHid)에서 권한이 없으면 시작하지 않고 권한을 요청한다. HidPeripheral.start·ClassicHid.start안에서도 권한을 다시 확인한다. 입구를 거치지 않는 경로가 있어도 크래시 대신 그냥 돌아간다.- 페어링 안내 화면에서 블루투스 광고를 켜기 전에
BLUETOOTH_ADVERTISE권한을 확인한다. vitals 에 이 경로의 크래시가 1건 따로 있었습니다.
지금 확인하는 순서
- 당일 크래시는 Crashlytics. 메일과 콘솔은 거의 실시간입니다.
- 라이브 전체는 Play vitals. 「사용자 인식」 필터를 지우고, 버전 열을 봅니다. 고친 크래시가 옛 버전에서만 나고 있으면 업데이트 비율이 올라가며 줄어듭니다. 지금 라이브 버전에 있으면 새로 고쳐야 합니다.
- vitals 는 API 로도 읽습니다. Play Developer Reporting API 의
errorReports:search를 부르면 스택 전문(reportText)까지 나옵니다. 다만 vitals 는 하루쯤 늦게 들어와서, 오늘 난 크래시는 아직 없습니다. - 주간 보고의 크래시 숫자는 0 이 아니면 그 자리에서 클러스터를 엽니다. 이번 일 전에도 주간 보고에 앱별 크래시 수는 찍혀 있었습니다. 숫자를 옮겨 적기만 하고 열어 보지 않은 게 진짜 원인이었습니다.
정리
- Crashlytics 는 넣은 빌드부터만 보입니다. 넣은 직후 메일이 조용한 건 정상입니다.
- 사용자 폰에는 옛 버전이 몇 주씩 남습니다. 그 크래시는 Play vitals 에만 있습니다.
- vitals 는 기본 필터를 지우고, 버전 열까지 봅니다. 「고친 버그인데 아직 나는 것」 과 「지금 버전의 새 버그」 가 거기서 갈립니다.
- 보고서의 숫자는 확인이 아닙니다. 0 이 아니면 열어 봅니다.
이 글에 나온 앱 중 하나는 지니 TV 리모컨(Google Play) 입니다.