| Wybierz platformę: | iOS+ Android Flutter Unity |
Możesz kliknąć problem i uzyskać szczegółowy raport o zdarzeniu na panelu DevOps i zaangażowanie > Crashlytics w Firebase konsoli. Możesz dostosować te raporty, aby lepiej zrozumieć, co dzieje się w Twojej aplikacji, oraz okoliczności zdarzeń zgłaszanych do Crashlytics.
Zaimplementuj w aplikacji rejestrowanie kluczy niestandardowych, niestandardowych komunikatów dziennika i identyfikatorów użytkowników.
Zgłaszaj wyjątki do Crashlytics.
Jeśli Twoja aplikacja korzysta z pakietu Firebase SDK dla Google Analytics, automatycznie otrzymasz dzienniki działań użytkownika. Te dzienniki pokazują działania użytkowników, które doprowadziły do zdarzenia zarejestrowanego przez Crashlytics w Twojej aplikacji.
Wyłącz automatyczne raportowanie awarii i włącz raportowanie, na które użytkownicy muszą wyrazić zgodę. Pamiętaj, że domyślnie Crashlytics automatycznie zbiera raporty o awariach wszystkich użytkowników Twojej aplikacji.
Dodawanie kluczy niestandardowych
Klucze niestandardowe pomagają uzyskać informacje o konkretnym stanie aplikacji, który doprowadził do awarii. Możesz powiązać dowolne pary klucz-wartość z raportami o awariach, a następnie użyć kluczy niestandardowych do wyszukiwania i filtrowania raportów o awariach na panelu DevOps i zaangażowanie > Crashlytics w Firebase konsoli.
Możesz wyszukiwać problemy, które pasują do klucza niestandardowego.
Gdy przeglądasz konkretny problem w konsoli, możesz wyświetlić powiązane z nim klucze niestandardowe dla każdego zdarzenia (podkarta Klucze) oraz filtrować zdarzenia według kluczy niestandardowych (menu Filtr u góry strony).
Aby ustawić pary klucz-wartość, użyj metody setCustomValue. Przykład:
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
Podczas ustawiania liczb całkowitych, wartości logicznych lub liczb zmiennoprzecinkowych umieść wartość w polu @(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"];
Możesz też zmodyfikować wartość istniejącego klucza, wywołując klucz i ustawiając go na inną wartość. Przykład:
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"];
Aby dodać pary klucz-wartość zbiorczo, użyj metody setCustomKeysAndValues z NSDictionary jako jedynym parametrem:
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];
Dodawanie niestandardowych komunikatów dziennika
Aby uzyskać więcej kontekstu dotyczącego zdarzeń prowadzących do awarii, możesz dodać niestandardowe Crashlytics dzienniki do aplikacji. Crashlytics powiąże dzienniki z danymi o awariach i wyświetli je na karcie Dzienniki , gdy wyświetlisz szczegóły problemu (wszystkie problemy znajdziesz na panelu DevOps i zaangażowanie > Crashlytics dashboard w konsoli Firebase).
Swift
Aby pomóc w identyfikowaniu problemów, użyj funkcji log() lub log(format:, arguments:). Jeśli chcesz uzyskać przydatne dane wyjściowe dziennika z komunikatami, obiekt przekazywany do
log() musi być zgodny z
CustomStringConvertible
właściwością. log() zwraca właściwość opisu zdefiniowaną dla obiektu. Przykład:
Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")
.log(format:, arguments:) formatuje wartości zwracane przez wywołanie
getVaList(). Przykład:
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))
Więcej informacji o tym, jak używać funkcji log() lub log(format:, arguments:),
znajdziesz w Crashlytics
dokumentacji referencyjnej.
Objective-C
Aby pomóc w identyfikowaniu problemów, użyj funkcji log lub logWithFormat. Pamiętaj, że jeśli chcesz uzyskać przydatne dane wyjściowe dziennika z komunikatami, obiekt przekazywany do dowolnej z tych metod musi zastępować właściwość instancji description.
Przykład:
[[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];
Więcej informacji o tym, jak używać funkcji log i logWithFormat, znajdziesz w
Crashlytics dokumentacji referencyjnej.
Ustawianie identyfikatorów użytkowników
Aby zdiagnozować problem, często przydatne jest sprawdzenie, który z użytkowników doświadczył danej awarii. Crashlytics zawiera sposób na anonimowe identyfikowanie użytkowników w raportach o awariach.
Aby dodać identyfikatory użytkowników do raportów, przypisz każdemu użytkownikowi unikalny identyfikator w postaci numeru identyfikacyjnego, tokena lub wartości skrótu:
Swift
Crashlytics.crashlytics().setUserID("123456789")
Objective-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
Jeśli kiedykolwiek będziesz musiał wyczyścić identyfikator użytkownika po jego ustawieniu, zresetuj wartość do pustego ciągu znaków. Wyczyszczenie identyfikatora użytkownika nie powoduje usunięcia istniejących Crashlytics rekordów. Jeśli musisz usunąć rekordy powiązane z identyfikatorem użytkownika, skontaktuj się z zespołem pomocy Firebase.
Zgłaszanie wyjątków niekrytycznych
Oprócz automatycznego zgłaszania awarii aplikacji Crashlytics umożliwia rejestrowanie wyjątków niekrytycznych i wysyłanie ich do Ciebie przy następnym uruchomieniu aplikacji.
Wyjątki niekrytyczne możesz rejestrować, zapisując obiekty NSError za pomocą metody recordError. recordError przechwytuje stos wywołań wątku, wywołując [NSThread callStackReturnAddresses].
Swift
Crashlytics.crashlytics().record(error: error)
Objective-C
[[FIRCrashlytics crashlytics] recordError:error];
Podczas korzystania z metody recordError ważne jest, aby zrozumieć strukturę NSError
i sposób, w jaki Crashlytics używa danych do grupowania awarii. Nieprawidłowe
użycie metody recordError może spowodować nieprzewidywalne zachowanie i może
ograniczyć raportowanie zarejestrowanych błędów w aplikacji przez Crashlytics.
Obiekt NSError ma 3 argumenty:
domain: Stringcode: IntuserInfo: [AnyHashable : Any]? = nil
W przeciwieństwie do awarii krytycznych, które są grupowane na podstawie analizy stosu wywołań, zarejestrowane błędy
są grupowane według domain i code. Jest to ważna różnica między awariami krytycznymi a zarejestrowanymi błędami. Przykład:
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];
Gdy zarejestrujesz powyższy błąd, utworzy się nowy problem, który zostanie pogrupowany według NSSomeErrorDomain i -1001. Dodatkowe zarejestrowane błędy, które używają tych samych wartości domeny i kodu, są grupowane w ramach tego samego problemu. Dane zawarte w obiekcie userInfo są konwertowane na pary klucz-wartość i wyświetlane w sekcji kluczy/dzienników w ramach poszczególnych problemów.
Dzienniki i klucze niestandardowe
Podobnie jak w przypadku raportów o awariach, możesz osadzać dzienniki i klucze niestandardowe, aby dodać kontekst do NSError. Istnieje jednak różnica w tym, jakie dzienniki są dołączane do awarii, a jakie do zarejestrowanych błędów. Gdy wystąpi awaria i aplikacja zostanie ponownie uruchomiona,
dzienniki Crashlytics pobiera z dysku, to te, które zostały zapisane do
momentu awarii. Gdy zarejestrujesz NSError, aplikacja nie zostanie natychmiast zamknięta. Ponieważ Crashlytics wysyła raport o zarejestrowanym błędzie dopiero przy następnym uruchomieniu aplikacji i musi ograniczyć ilość miejsca na dysku przeznaczonego na dzienniki, możliwe jest zarejestrowanie wystarczającej ilości danych po zarejestrowaniu NSError aby wszystkie istotne dzienniki zostały usunięte, zanim Crashlytics wyśle raport z urządzenia. Pamiętaj o tym, rejestrując NSErrors i używając dzienników oraz kluczy niestandardowych w aplikacji.
Możliwe spowolnienie działania witryny
Pamiętaj, że rejestrowanie NSError może być dość kosztowne. W momencie wywołania
CrashlyticsCrashlytics przechwytuje stos wywołań bieżącego wątku za pomocą
procesu zwanego rozwijaniem stosu. Proces ten może być intensywny pod względem wykorzystania procesora i operacji wejścia/wyjścia, szczególnie w przypadku architektur obsługujących rozwijanie DWARF (arm64 i x86).
Po zakończeniu rozwijania informacje są zapisywane na dysku synchronicznie.
Zapobiega to utracie danych w przypadku awarii w następnym wierszu.
Chociaż wywoływanie tego interfejsu API w wątku w tle jest bezpieczne, pamiętaj, że wysyłanie tego wywołania do innej kolejki powoduje utratę kontekstu bieżącego stosu wywołań.
A co z NSExceptions?
Crashlytics nie oferuje możliwości bezpośredniego rejestrowania i zapisywania instancji NSException. Ogólnie rzecz biorąc, interfejsy API Cocoa i Cocoa Touch nie są bezpieczne w przypadku wyjątków. Oznacza to, że użycie @catch może mieć bardzo poważne niezamierzone skutki uboczne w Twoim procesie, nawet jeśli używasz go z dużą ostrożnością. W kodzie nigdy nie należy używać instrukcji @catch. Więcej informacji na ten temat znajdziesz w
dokumentacji Apple.
Dostosowywanie stosów wywołań
Jeśli Twoja aplikacja działa w środowisku innym niż natywne (np. C++ lub Unity), możesz użyć interfejsu API modelu wyjątków, aby zgłaszać metadane awarii w natywnym formacie wyjątków aplikacji. Zgłoszone wyjątki są oznaczane jako niekrytyczne.
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];
Niestandardowe ramki stosu można też inicjować tylko za pomocą adresów:
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];
Pobieranie dzienników działań użytkownika
Dzienniki działań użytkownika pozwalają lepiej zrozumieć interakcje użytkownika z aplikacją, które doprowadziły do awarii, wyjątku niekrytycznego lub zdarzenia ANR. Te dzienniki mogą być przydatne podczas próby odtworzenia i debugowania problemu.
Dzienniki działań użytkownika są obsługiwane przez Google Analytics, więc aby je uzyskać, musisz włączyć Google Analytics w projekcie Firebase i dodać do aplikacji pakiet Firebase SDK dla Google Analytics. Gdy te wymagania zostaną spełnione, dzienniki działań użytkownika będą automatycznie dołączane do danych zdarzenia na karcie Dzienniki , gdy wyświetlisz szczegóły problemu (wszystkie problemy znajdziesz na panelu DevOps i zaangażowanie > Crashlytics w konsoli Firebase).
Pakiet Analytics SDK
automatycznie rejestruje zdarzenie screen_view
które umożliwia wyświetlanie w dziennikach działań użytkownika listy ekranów wyświetlanych przed
awarią, wyjątkiem niekrytycznym lub zdarzeniem ANR. Dziennik działań użytkownika screen_view zawiera parametr firebase_screen_class.
Dzienniki działań użytkownika są też wypełniane wszystkimi zdarzeniami niestandardowymi, które ręcznie rejestrujesz w sesji użytkownika , w tym danymi parametrów zdarzenia. Te dane mogą pokazywać serię działań użytkownika, które doprowadziły do awarii, wyjątku niekrytycznego lub zdarzenia ANR.
Pamiętaj, że możesz kontrolować zbieranie i wykorzystywanie danych Google Analytics, w tym danych, które wypełniają dzienniki działań użytkownika.
Włączanie raportowania, na które użytkownicy muszą wyrazić zgodę
Domyślnie Crashlytics automatycznie zbiera raporty o awariach wszystkich użytkowników Twojej aplikacji. Aby dać użytkownikom większą kontrolę nad wysyłanymi danymi, możesz włączyć raportowanie, na które użytkownicy muszą wyrazić zgodę, wyłączając automatyczne raportowanie i wysyłając dane do Crashlytics tylko wtedy, gdy zdecydujesz się na to w kodzie.
Wyłącz automatyczne zbieranie danych, dodając nowy klucz do pliku
Info.plist:- Klucz:
FirebaseCrashlyticsCollectionEnabled - Wartość:
false
- Klucz:
Włącz zbieranie danych dla wybranych użytkowników, wywołując w czasie działania aplikacji Crashlytics zastąpienie zbierania danych przez Crashlytics. Wartość zastąpienia jest zachowywana we wszystkich kolejnych uruchomieniach aplikacji, dzięki czemu Crashlytics może automatycznie zbierać raporty dla tego użytkownika.
Swift
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
Objective-C
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
Jeśli użytkownik później zrezygnuje ze zbierania danych, możesz przekazać wartość
falsejako wartość zastąpienia. Zostanie ona zastosowana przy następnym uruchomieniu aplikacji przez użytkownika i będzie zachowywana we wszystkich kolejnych uruchomieniach.
Zarządzanie danymi statystyk awarii
Statystyki awarii pomagają rozwiązywać problemy, porównując zanonimizowane stosy wywołań z innymi aplikacjami Firebase i informując, czy Twój problem jest częścią większego trendu. W przypadku wielu problemów statystyki awarii udostępniają też zasoby, które pomagają w debugowaniu awarii.
Statystyki awarii używają zagregowanych danych o awariach do identyfikowania typowych trendów stabilności. Jeśli nie chcesz udostępniać danych aplikacji, możesz zrezygnować ze statystyk awarii w menu Statystyki awarii u góry listy problemów na panelu DevOps i zaangażowanie > Crashlytics dashboard w Firebase konsoli.
Dalsze kroki
- Eksportuj dane do BigQuery lub Cloud Logging aby korzystać z zaawansowanych analiz i funkcji, takich jak wysyłanie zapytań o dane, tworzenie niestandardowych paneli i konfigurowanie niestandardowych alertów.