In dieser Anleitung wird beschrieben, wie Sie Ihre Absturzberichte mithilfe des Firebase Crashlytics SDK anpassen. Standardmäßig sammelt Crashlytics automatisch Absturzberichte für alle Benutzer Ihrer App (Sie können die automatische Absturzberichterstattung deaktivieren und stattdessen die Opt-in-Berichterstattung für Ihre Benutzer aktivieren ). Crashlytics bietet standardmäßig vier Protokollierungsmechanismen: benutzerdefinierte Schlüssel , benutzerdefinierte Protokolle , Benutzerkennungen und abgefangene Ausnahmen .
Fügen Sie benutzerdefinierte Schlüssel hinzu
Mit benutzerdefinierten Schlüsseln können Sie den spezifischen Status Ihrer App ermitteln, der zu einem Absturz geführt hat. Sie können Ihren Absturzberichten beliebige Schlüssel/Wert-Paare zuordnen und dann die benutzerdefinierten Schlüssel zum Suchen und Filtern von Absturzberichten in der Firebase-Konsole verwenden.
- Im Crashlytics-Dashboard können Sie nach Problemen suchen, die einem benutzerdefinierten Schlüssel entsprechen.
- Wenn Sie ein bestimmtes Problem in der Konsole überprüfen, können Sie die zugehörigen benutzerdefinierten Schlüssel für jedes Ereignis anzeigen (Unterregisterkarte „Schlüssel “) und die Ereignisse sogar nach benutzerdefinierten Schlüsseln filtern (Menü „Filter“ oben auf der Seite).
Verwenden Sie die Methode setCustomValue
, um Schlüssel/Wert-Paare festzulegen. Zum Beispiel:
Schnell
// Set int_key to 100. Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key") // Set str_key to "hello". Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")
Ziel c
Wenn Sie Ganzzahlen, boolesche Werte oder Gleitkommazahlen festlegen, rahmen Sie den Wert als @( value )
ein.
// Set int_key to 100. [[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"]; // Set str_key to "hello". [[FIRCrashlytics crashlytics] setCustomValue:@"hello" forKey:@"str_key"];
Sie können den Wert eines vorhandenen Schlüssels auch ändern, indem Sie den Schlüssel aufrufen und auf einen anderen Wert festlegen. Zum Beispiel:
Schnell
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key") // Set int_key to 50 from 100. Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")
Ziel c
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"]; // Set int_key to 50 from 100. [[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];
Fügen Sie Schlüssel/Wert-Paare in großen Mengen hinzu, indem Sie die Methode setCustomKeysAndValues
mit einem NSDictionary als einzigem Parameter verwenden:
Schnell
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)
Ziel 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];
Fügen Sie benutzerdefinierte Protokollnachrichten hinzu
Um mehr Kontext für die Ereignisse zu erhalten, die zu einem Absturz geführt haben, können Sie Ihrer App benutzerdefinierte Crashlytics-Protokolle hinzufügen. Crashlytics verknüpft die Protokolle mit Ihren Absturzdaten und zeigt sie auf der Crashlytics-Seite der Firebase-Konsole unter der Registerkarte „Protokolle“ an.
Schnell
Verwenden Sie log()
oder log(format:, arguments:)
, um Probleme zu lokalisieren. Wenn Sie eine nützliche Protokollausgabe mit Meldungen erhalten möchten, muss das Objekt, das Sie an log()
übergeben, der Eigenschaft CustomStringConvertible
entsprechen. log()
gibt die Beschreibungseigenschaft zurück, die Sie für das Objekt definieren. Zum Beispiel:
Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")
.log(format:, arguments:)
formatiert Werte, die vom Aufruf getVaList()
zurückgegeben werden. Zum Beispiel:
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))
Weitere Einzelheiten zur Verwendung von log()
oder log(format:, arguments:)
finden Sie in der Crashlytics- Referenzdokumentation .
Ziel c
Verwenden Sie log
oder logWithFormat
, um Probleme zu lokalisieren. Beachten Sie, dass das Objekt, das Sie an eine der beiden Methoden übergeben, die description
überschreiben muss, wenn Sie eine nützliche Protokollausgabe mit Meldungen erhalten möchten. Zum Beispiel:
[[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];
Weitere Einzelheiten zur Verwendung von log
und logWithFormat
finden Sie in der Crashlytics- Referenzdokumentation .
Legen Sie Benutzerkennungen fest
Um ein Problem zu diagnostizieren, ist es oft hilfreich zu wissen, bei welchem Ihrer Benutzer ein bestimmter Absturz aufgetreten ist. Crashlytics bietet eine Möglichkeit, Benutzer in Ihren Absturzberichten anonym zu identifizieren.
Um Ihren Berichten Benutzer-IDs hinzuzufügen, weisen Sie jedem Benutzer eine eindeutige Kennung in Form einer ID-Nummer, eines Tokens oder eines Hash-Werts zu:
Schnell
Crashlytics.crashlytics().setUserID("123456789")
Ziel c
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
Wenn Sie jemals eine Benutzerkennung löschen müssen, nachdem Sie sie festgelegt haben, setzen Sie den Wert auf eine leere Zeichenfolge zurück. Durch das Löschen einer Benutzerkennung werden vorhandene Crashlytics-Datensätze nicht entfernt. Wenn Sie mit einer Benutzer-ID verknüpfte Datensätze löschen müssen, wenden Sie sich an den Firebase-Support .
Melden Sie nicht schwerwiegende Ausnahmen
Zusätzlich zur automatischen Meldung der Abstürze Ihrer App können Sie mit Crashlytics nicht schwerwiegende Ausnahmen aufzeichnen und diese beim nächsten Start Ihrer App an Sie senden.
Sie können nicht schwerwiegende Ausnahmen aufzeichnen, indem Sie NSError
Objekte mit der Methode recordError
aufzeichnen. recordError
erfasst den Aufrufstapel des Threads durch Aufrufen von [NSThread callStackReturnAddresses]
.
Schnell
Crashlytics.crashlytics().record(error: error)
Ziel c
[[FIRCrashlytics crashlytics] recordError:error];
Bei Verwendung der Methode recordError
ist es wichtig, die NSError
Struktur zu verstehen und zu verstehen, wie Crashlytics die Daten zum Gruppieren von Abstürzen verwendet. Eine falsche Verwendung der Methode recordError
kann zu unvorhersehbarem Verhalten führen und dazu führen, dass Crashlytics die Meldung protokollierter Fehler für Ihre App einschränkt.
Ein NSError
Objekt hat drei Argumente:
-
domain: String
-
code: Int
-
userInfo: [AnyHashable : Any]? = nil
Im Gegensatz zu schwerwiegenden Abstürzen, die über die Stack-Trace-Analyse gruppiert werden, werden protokollierte Fehler nach domain
und code
gruppiert. Dies ist ein wichtiger Unterschied zwischen schwerwiegenden Abstürzen und protokollierten Fehlern. Zum Beispiel:
Schnell
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)
Ziel 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];
Wenn Sie den oben genannten Fehler protokollieren, entsteht ein neues Problem, das nach NSSomeErrorDomain
und -1001
gruppiert ist. Weitere protokollierte Fehler, die dieselben Domänen- und Codewerte verwenden, werden unter demselben Problem gruppiert. Die im userInfo
Objekt enthaltenen Daten werden in Schlüssel-Wert-Paare umgewandelt und im Abschnitt „Schlüssel/Protokolle“ innerhalb eines einzelnen Problems angezeigt.
Protokolle und benutzerdefinierte Schlüssel
Genau wie Absturzberichte können Sie Protokolle und benutzerdefinierte Schlüssel einbetten, um dem NSError
Kontext hinzuzufügen. Es gibt jedoch einen Unterschied darin, welche Protokolle an Abstürze und protokollierte Fehler angehängt werden. Wenn ein Absturz auftritt und die App neu gestartet wird, sind die Protokolle, die Crashlytics von der Festplatte abruft, diejenigen, die bis zum Zeitpunkt des Absturzes geschrieben wurden. Wenn Sie einen NSError
protokollieren, wird die App nicht sofort beendet. Da Crashlytics den protokollierten Fehlerbericht erst beim nächsten App-Start sendet und den für Protokolle zugewiesenen Speicherplatz auf der Festplatte begrenzen muss, ist es möglich, nach der Aufzeichnung eines NSError
genügend Protokolle zu erstellen, sodass alle relevanten Protokolle zum Zeitpunkt des Sendens durch Crashlytics rotiert werden den Bericht vom Gerät. Beachten Sie dieses Gleichgewicht, wenn Sie NSErrors
protokollieren und Protokolle und benutzerdefinierte Schlüssel in Ihrer App verwenden.
Leistungsüberlegungen
Bedenken Sie, dass die Protokollierung eines NSError
ziemlich teuer sein kann. Wenn Sie den Aufruf tätigen, erfasst Crashlytics den Aufrufstapel des aktuellen Threads mithilfe eines Prozesses namens „Stack-Unwinding“. Dieser Prozess kann CPU- und E/A-intensiv sein, insbesondere auf Architekturen, die das DWARF-Abwickeln unterstützen (arm64 und x86). Nachdem die Abwicklung abgeschlossen ist, werden die Informationen synchron auf die Festplatte geschrieben. Dadurch wird ein Datenverlust verhindert, wenn die nächste Zeile abstürzt.
Obwohl es sicher ist, diese API in einem Hintergrundthread aufzurufen, denken Sie daran, dass durch die Weiterleitung dieses Aufrufs an eine andere Warteschlange der Kontext des aktuellen Stack-Trace verloren geht.
Was ist mit NSExceptions?
Crashlytics bietet keine Möglichkeit, NSException
Instanzen direkt zu protokollieren und aufzuzeichnen. Im Allgemeinen sind die APIs Cocoa und Cocoa Touch nicht ausnahmesicher. Das bedeutet, dass die Verwendung von @catch
selbst bei äußerster Vorsicht sehr schwerwiegende unbeabsichtigte Nebenwirkungen in Ihrem Prozess haben kann. Sie sollten in Ihrem Code niemals @catch
Anweisungen verwenden. Weitere Informationen finden Sie in der Dokumentation von Apple zu diesem Thema.
Passen Sie Stack-Traces an
Wenn Ihre App in einer nicht nativen Umgebung (z. B. C++ oder Unity) ausgeführt wird, können Sie die Ausnahmemodell-API verwenden, um Absturzmetadaten im nativen Ausnahmeformat Ihrer App zu melden. Gemeldete Ausnahmen werden als nicht schwerwiegend gekennzeichnet.
Schnell
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)
Ziel 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];
Benutzerdefinierte Stack-Frames können auch nur mit Adressen initialisiert werden:
Schnell
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)
Ziel 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];
Aktivieren Sie die Opt-in-Berichterstellung
Standardmäßig sammelt Crashlytics automatisch Absturzberichte für alle Benutzer Ihrer App. Um Benutzern mehr Kontrolle über die von ihnen gesendeten Daten zu geben, können Sie die Opt-in-Berichterstellung aktivieren, indem Sie die automatische Berichterstellung deaktivieren und Daten nur dann an Crashlytics senden, wenn Sie dies in Ihrem Code festlegen:
Deaktivieren Sie die automatische Erfassung, indem Sie Ihrer
Info.plist
Datei einen neuen Schlüssel hinzufügen:- Schlüssel:
FirebaseCrashlyticsCollectionEnabled
- Wert:
false
- Schlüssel:
Aktivieren Sie die Erfassung für ausgewählte Benutzer, indem Sie zur Laufzeit die Crashlytics-Datenerfassungsüberschreibung aufrufen. Der Überschreibungswert bleibt über alle Starts Ihrer App hinweg bestehen, sodass Crashlytics automatisch Berichte sammeln kann.
Um die automatische Absturzberichterstattung zu deaktivieren, übergeben Sie
false
als Überschreibungswert. Bei Festlegung auffalse
wird der neue Wert erst bei der nächsten Ausführung der App angewendet.Schnell
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
Ziel c
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
Verwalten Sie Crash Insights-Daten
Crash Insights hilft Ihnen bei der Lösung von Problemen, indem es Ihre anonymisierten Stack-Traces mit Traces von anderen Firebase-Apps vergleicht und Sie darüber informiert, ob Ihr Problem Teil eines größeren Trends ist. Für viele Probleme stellt Crash Insights sogar Ressourcen zur Verfügung, die Sie beim Debuggen des Absturzes unterstützen.
Crash Insights verwendet aggregierte Absturzdaten, um allgemeine Stabilitätstrends zu identifizieren. Wenn Sie die Daten Ihrer App nicht weitergeben möchten, können Sie Crash Insights über das Crash Insights- Menü oben in Ihrer Crashlytics-Problemliste in der Firebase-Konsole deaktivieren.