Menyesuaikan laporan error Firebase Crashlytics

ios
android
unity [beta]

Firebase Crashlytics dapat berfungsi hanya dengan melakukan penyiapan secara minimal. Segera setelah Anda menambahkan SDK, Crashlytics akan mulai mengirimkan laporan kerusakan ke Firebase console.

Untuk memberi Anda lebih banyak insight tentang laporan kerusakan, Firebase Crashlytics menyediakan empat mekanisme logging secara langsung tanpa perlu penyiapan apa pun: tombol kustom, log kustom, ID pengguna, dan pengecualian yang tertangkap.

Menambahkan tombol kustom

Tombol kustom membantu Anda mendapatkan status tertentu aplikasi yang mengarah ke error. Anda dapat mengaitkan key-value pair apa saja dengan laporan kerusakan, dan melihatnya di Firebase console.

ios

Mulai dengan [CrashlyticsKit setObjectValue:forKey:] atau dengan salah satu metode terkait:

- (void)setObjectValue:(id)value forKey:(NSString *)key;

// calls -description on value, perfect for NSStrings!
- (void)setIntValue:(int)value forKey:(NSString *)key;

- (void)setBoolValue:(BOOL)value forKey:(NSString *)key;

- (void)setFloatValue:(float)value forKey:(NSString *)key;

Terkadang Anda perlu mengubah nilai kunci yang ada. Panggil kunci yang sama, tapi ganti nilainya, misalnya:

Objective-C
[CrashlyticsKit setIntValue:3 forKey:@"current_level"];
[CrashlyticsKit setObjectValue:@"logged_in" forKey:@"last_UI_action"];
Swift
Crashlytics.sharedInstance().setIntValue(42, forKey: "MeaningOfLife")
Crashlytics.sharedInstance().setObjectValue("Test value", forKey: "last_UI_action")
android

Ada lima metode untuk menetapkan kunci. Masing-masing metode menangani jenis data yang berbeda:

Java
Android

Crashlytics.setString(key, "foo" /* string value */);

Crashlytics.setBool(key, true /* boolean value */);

Crashlytics.setDouble(key, 1.0 /* double value */);

Crashlytics.setFloat(key, 1.0f /* float value */);

Crashlytics.setInt(key, 1 /* int value */);

Kotlin
Android

Crashlytics.setString(key, "foo" /* string value */)

Crashlytics.setBool(key, true /* boolean value */)

Crashlytics.setDouble(key, 1.0 /* double value */)

Crashlytics.setFloat(key, 1.0f /* float value */)

Crashlytics.setInt(key, 1 /* int value */)

Menyetel ulang kunci akan memperbarui nilainya, misalnya:

Java
Android

Crashlytics.setInt("current_level", 3);
Crashlytics.setString("last_UI_action", "logged_in");

Kotlin
Android

Crashlytics.setInt("current_level", 3)
Crashlytics.setString("last_UI_action", "logged_in")
unity [beta]

Ketika dipanggil beberapa kali, nilai baru untuk kunci yang ada akan menggantikan nilai ini, dan hanya nilai terbaru yang direkam saat error dicatat.

Crashlytics.SetCustomKey(string key, string value);

Menambahkan pesan log kustom

Untuk memberikan laporan yang lebih banyak mengenai peristiwa yang mengarah ke error, Anda dapat menambahkan log Crashlytics kustom ke aplikasi. Crashlytics mengaitkan log dengan data error dan menampilkannya di Firebase console.

ios
Objective-C

Di Objective-C, gunakan CLS_LOG untuk membantu menentukan masalah. Ini secara otomatis mencakup informasi tentang kelas, metode, dan nomor baris Objective-C yang terkait dengan log.

Perilaku CLS_LOG berubah tergantung pada apakah pencatatan log-nya untuk build debug atau rilis:

  • Build debug: CLS_LOG diteruskan ke NSLog sehingga Anda dapat melihat output-nya di Xcode dan di perangkat atau simulator.
  • Build rilis: Untuk meningkatkan performa, CLS_LOG menonaktifkan semua output lainnya dan tidak diteruskan melalui NSLog.

Gunakan CLS_LOG(format, ...) untuk mencatat log dengan CLS_LOG. Misalnya:

CLS_LOG(@"Higgs-Boson detected! Bailing out... %@", attributesDict);

Cari file header Crashlytics/Crashlytics.h untuk detail lebih lanjut tentang cara menggunakan CLS_LOG.

Swift

Di Swift, gunakan CLSLogv atau CLSNSLogv untuk membantu menentukan masalah.

Ada dua hal yang perlu diingat saat melakukan pencatatan log dengan CLSLogv dan CLSNSLogv:

  • Argumen format Anda harus berupa string konstan waktu kompilasi. Hal ini diberlakukan oleh compiler di Objective-C, namun perlindungan ini tidak ada saat terhubung ke Swift.
  • Simpan nilai log dalam array, dan panggil getVaList pada array itu untuk mengambilnya kembali.

Misalnya:

func write(string: String) {
    CLSLogv("%@", getVaList([string]))
}
Interpolasi string Swift tidak akan menghasilkan string konstan waktu kompilasi. Sama seperti dengan printf dan NSLog, menggunakan string non-konstan dengan CLSLog dapat mengakibatkan error.

Lanjutan

Untuk kontrol lebih lanjut, Anda bisa langsung memanfaatkan CLSLog(format, ...) dan CLSNSLog(format, ...). Yang terakhir, meneruskan ke NSLog sehingga Anda bisa melihat output di Xcode atau pada perangkat atau simulator. CLSLog(format, ...) dan CLSNSLog(format, ...) aman untuk thread. CLSLog dimaksudkan untuk informasi pencatatan log yang penting untuk menyelesaikan error. Ini tidak boleh digunakan untuk melacak peristiwa dalam aplikasi.

android

Di Android, gunakan Crashlytics.log untuk membantu menentukan masalah.

Crashlytics.log dapat menulis log ke laporan kerusakan bersama dengan Log.println() atau hanya ke laporan kerusakan berikutnya:

  • Laporan kerusakan dan Log.println:

    Java
    Android

    Crashlytics.log(Log.DEBUG, "tag", "message");

    Kotlin
    Android

    Crashlytics.log(Log.DEBUG, "tag", "message")
  • Laporan kerusakan saja:

    Java
    Android

    Crashlytics.log("message");

    Kotlin
    Android

    Crashlytics.log("message")
unity [beta]

Pesan yang dicatat dalam log dikaitkan dengan data error dan terlihat di dasbor Firebase Crashlytics saat Anda menampilkan error tertentu.

Crashlytics.Log(string message);

Menetapkan ID pengguna

Untuk mendiagnosis masalah, mengetahui pengguna mana yang mengalami error akan sangat membantu. Crashlytics menyertakan cara mengidentifikasi pengguna secara anonim dalam laporan kerusakan Anda.

ios

Untuk menambahkan ID pengguna ke laporan, tetapkan pengenal unik untuk masing-masing pengguna dalam bentuk nomor ID, token, atau nilai hash:

Objective-C
[CrashlyticsKit setUserIdentifier:@"123456789"];
Swift
Crashlytics.sharedInstance().setUserIdentifier("123456789")

Jika Anda perlu menghapus ID pengguna setelah menyetelnya, setel ulang nilai ke string kosong. Menghapus ID pengguna tidak menghapus catatan Crashlytics yang ada. Jika ingin menghapus catatan yang terkait dengan ID pengguna, hubungi dukungan Firebase.

android

Untuk menambahkan ID pengguna ke laporan, tetapkan pengenal unik untuk masing-masing pengguna dalam bentuk nomor ID, token, atau nilai hash:

Java
Android

Crashlytics.setUserIdentifier("user123456789");

Kotlin
Android

Crashlytics.setUserIdentifier("user123456789")

Jika Anda perlu menghapus ID pengguna setelah menyetelnya, setel ulang nilai ke string kosong. Menghapus ID pengguna tidak menghapus catatan Crashlytics yang ada. Jika ingin menghapus catatan yang terkait dengan ID pengguna, hubungi dukungan Firebase.

unity [beta]

Anda dapat menggunakan nomor ID, token, atau nilai yang di-hash untuk mengidentifikasi pengguna akhir aplikasi secara unik, tanpa mengungkapkan atau mengirimkan informasi pribadi mereka. Anda juga dapat menghapus nilai ini dengan menetapkannya ke string kosong. Nilai ini ditampilkan di dasbor Firebase Crashlytics saat Anda menampilkan error tertentu.

Crashlytics.SetUserId(string identifier);

Mencatat log pengecualian tidak fatal

Selain melaporkan kerusakan aplikasi secara otomatis, Crashlytics memungkinkan Anda mencatat log pengecualian tidak fatal.

ios

Di iOS, Anda dapat melakukannya dengan mencatat objek NSError, di mana Crashlytics melaporkan dan mengelompokkan error yang serupa:

Objective-C
[CrashlyticsKit recordError:error];
Swift
Crashlytics.sharedInstance().recordError(error)

Saat menggunakan metode recordError, penting untuk memahami struktur NSError dan cara Crashlytics menggunakan data untuk mengelompokkan error. Penggunaan metode RecordError yang salah dapat menyebabkan perilaku yang tidak dapat diprediksi dan mungkin akan menyebabkan Crashlytics perlu membatasi pelaporan error yang dicatat untuk aplikasi Anda.

Objek NSError memiliki tiga argumen: domain: String, code: Int, dan userInfo: [AnyHashable : Any]? = nil

Tidak seperti error fatal, yang dikelompokkan melalui analisis pelacakan tumpukan, error yang dicatat dikelompokkan oleh domain dan code NSError. Ini adalah perbedaan penting antara error fatal dan error yang dicatat. Misalnya, pencatatan error seperti:

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";
    UserID: @"Jane Smith"
};

NSError *error = [NSError domain:NSSomeErrorDomain
                          code:-1001
                          userInfo:userInfo];

Membuat masalah baru yang dikelompokkan oleh NSSomeErrorDomain dan -1001. Error lainnya yang dicatat yang menggunakan nilai domain dan kode yang sama akan dikelompokkan dalam masalah ini.

Hindari penggunaan nilai unik, seperti ID pengguna, ID produk, dan stempel waktu di kolom domain dan kode. Menggunakan nilai unik di kolom ini menyebabkan kardinalitas masalah yang tinggi dan dapat menyebabkan Crashlytics perlu membatasi pelaporan error yang dicatat di aplikasi Anda. Nilai unik seharusnya ditambahkan ke objek Dictionary userInfo.

Data yang terdapat dalam objek userInfo dikonversi menjadi key-value pair dan ditampilkan di kolom key/log dalam satu masalah.

Crashlytics hanya menyimpan 8 pengecualian terbaru dalam sesi aplikasi tertentu. Jika aplikasi Anda megirimkan lebih dari 8 pengecualian dalam satu sesi, pengecualian yang lebih lama akan hilang.

Pencatatan log dan tombol kustom

Sama seperti laporan kerusakan, Anda bisa menyematkan log dan kunci kustom untuk menambahkan konteks ke NSError. Namun, ada perbedaan dalam log yang dilampirkan pada error dengan error yang dicatat. Saat terjadi error lalu aplikasi diluncurkan kembali, log yang diambil Crashlytics dari disk adalah log yang ditulis hingga saat error terjadi. Saat Anda mencatat NSError, aplikasi tidak segera dihentikan. Karena Crashlytics hanya mengirimkan laporan kerusakan yang dicatat pada peluncuran aplikasi berikutnya, dan karena Crashlytics harus membatasi jumlah ruang yang dialokasikan untuk log pada disk, pencatatan log dapat dilakukan setelah NSError dicatat, sehingga semua log yang relevan dirotasi pada saat Crashlytics mengirimkan laporan dari perangkat. Jaga keseimbangan ini saat mencatat log pada NSErrors dan saat menggunakan CLSLog dan kunci kustom di aplikasi Anda.

Pertimbangan performa

Perlu diingat bahwa pencatatan log NSError bisa jadi cukup mahal. Pada saat Anda melakukan panggilan, Crashlytics menangkap tumpukan panggilan thread saat ini dengan menggunakan proses yang disebut pelepasan tumpukan. Proses ini memerlukan CPU dan I/O secara intensif, terutama pada arsitektur yang mendukung pelepasan DWARF (arm64 dan x86). Setelah proses pelepasan selesai, informasinya ditulis ke disk secara bersamaan. Ini untuk mencegah hilangnya data jika baris berikutnya mengalami error.

Meskipun aman untuk memanggil API ini di thread background, ingat bahwa mengirimkan panggilan ini ke antrean lainnya akan menyebabkan hilangnya konteks pelacakan tumpukan saat ini.

Bagaimana dengan NSExceptions?

Crashlytics tidak menawarkan fasilitas untuk pencatatan log/pencatatan instance NSException secara langsung. Secara umum, API Cocoa and Cocoa Touch tidak benar-benar aman dari pengecualian. Itu berarti penggunaan @catch memiliki efek samping sangat serius yang tidak diinginkan dalam proses Anda, bahkan jika digunakan dengan sangat hati-hati. Jangan pernah menggunakan pernyataan @catch dalam kode Anda. Lihat dokumentasi Apple untuk topik ini.

android

Di Android, itu berarti Anda dapat mencatat pengecualian yang tertangkap di blok catch aplikasi Anda ke dalam log:

Java
Android

try {
    methodThatThrows();
} catch (Exception e) {
    Crashlytics.logException(e);
    // handle your exception here
}

Kotlin
Android

try {
    methodThatThrows()
} catch (e: Exception) {
    Crashlytics.logException(e)
    // handle your exception here
}

Semua pengecualian yang dicatat ke dalam log muncul sebagai masalah tidak fatal di Firebase console. Ringkasan masalah berisi semua informasi status yang biasanya Anda dapatkan dari laporan kerusakan, bersama dengan perincian error berdasarkan versi Android dan perangkat hardware.

Crashlytics memproses pengecualian pada thread background khusus, sehingga meminimalkan dampak performa pada aplikasi Anda. Untuk mengurangi traffic jaringan pengguna Anda, Crashlytics mengelompokkan pengecualian yang dicatat dan mengirimkannya saat aplikasi diluncurkan berikutnya.

Crashlytics hanya menyimpan 8 pengecualian terbaru dalam sesi aplikasi tertentu. Jika aplikasi Anda megirimkan lebih dari 8 pengecualian dalam satu sesi, pengecualian yang lebih lama akan hilang.
unity [beta]

Catat pengecualian kustom pada C# ke dalam log menggunakan metode berikut:

Crashlytics.LogException(Exception ex);

Pengecualian kustom dapat dimasukkan ke dalam blok try/catch pada aplikasi Anda:

try {
    myMethodThatThrows();
} catch (Exception e) {
   Crashlytics.LogException(e);
   // handle your exception here!
}

Mengaktifkan pelaporan keikutsertaan

Secara default, Firebase Crashlytics mengumpulkan laporan kerusakan secara otomatis untuk semua pengguna aplikasi Anda. Untuk memberikan pengguna kontrol yang lebih besar terhadap data yang mereka kirim, Anda dapat mengaktifkan pelaporan keikutsertaan sebagai gantinya.

Untuk melakukan hal tersebut, Anda harus menonaktifkan pengumpulan otomatis dan menginisialisasi Crashlytics hanya untuk pengguna yang memilih ikut serta.

ios
  1. Nonaktifkan pengumpulan otomatis menggunakan kunci baru ke file Info.plist Anda:
    • Kunci: firebase_crashlytics_collection_enabled
    • Nilai: false
  2. Aktifkan pengumpulan untuk pengguna yang dipilih dengan menginisialisasi Crashlytics saat runtime:
    Objective-C
    [Fabric with:@[[Crashlytics class]]];
    Swift
    Fabric.with([Crashlytics.self])
android
  1. Nonaktifkan pengumpulan otomatis menggunakan tag meta-data di file AndroidManifest.xml:
    <meta-data
        android:name="firebase_crashlytics_collection_enabled"
        android:value="false" />
    
  2. Aktifkan pengumpulan untuk pengguna yang dipilih dengan menginisialisasi Crashlytics dari salah satu aktivitas aplikasi Anda:

    Java
    Android

    Fabric.with(this, new Crashlytics());

    Kotlin
    Android

    Fabric.with(this, Crashlytics())
Catatan: Anda tidak dapat menghentikan pelaporan Crashlytics setelah menginisialisasinya dalam sesi aplikasi. Untuk tidak diikutsertakan dalam pelaporan setelah Anda mengaktifkan Crashlytics, pengguna harus memulai ulang aplikasi Anda.
unity [beta]
Crashlytics.IsCrashlyticsCollectionEnabled = false;

Cara menambahkannya ke elemen UI ditunjukkan pada contoh berikut:

public class DataCollectionToggleScript : MonoBehaviour {

  public Toggle DataCollectionToggle;

  void Start () {
    Toggle toggle = DataCollectionToggle.GetComponent<Toggle>();
    toggle.isOn = Crashlytics.IsCrashlyticsCollectionEnabled;
    toggle.onValueChanged.AddListener(delegate {
      ToggleValueChanged(toggle);
    });
  }

  void ToggleValueChanged(Toggle toggle){
    Crashlytics.IsCrashlyticsCollectionEnabled = toggle.isOn;
  }
}

Tidak melihat kode yang mirip dari Fabric Crashlytics? Lihat halaman perubahan Unity API untuk mempelajari perkembangan Crashlytics dari Fabric Crashlytics menjadi Firebase Crashlytics.

Mengelola data Crash Insights

Crash Insights membantu Anda mengatasi masalah dengan membandingkan jejak tumpukan anonim dengan jejak dari aplikasi Firebase lain, serta memberitahukan apakah masalah Anda adalah bagian dari tren yang lebih besar. Untuk banyak masalah, Crash Insights bahkan menyediakan resource untuk membantu Anda men-debug error.

Crash Insights menggunakan data error gabungan untuk mengidentifikasi tren stabilitas umum. Jika tidak ingin membagikan data aplikasi, Anda dapat menonaktifkan Crash Insights dari menu Crash Insights di bagian atas daftar masalah Crashlytics pada Firebase console.

Kirim masukan tentang...

Butuh bantuan? Kunjungi halaman dukungan kami.