Dans le tableau de bord Crashlytics, vous pouvez cliquer sur un problème pour obtenir un rapport d'événement détaillé. Vous pouvez personnaliser ces rapports pour mieux comprendre ce qui se passe dans votre application et les circonstances des événements signalés à Crashlytics.
Instrumentez votre application pour enregistrer des clés personnalisées, des messages de journal personnalisés et des identifiants utilisateur.
Signalez les exceptions à Crashlytics.
Obtenez automatiquement des journaux de fil d'Ariane si votre application utilise le SDK Firebase pour Google Analytics. Ces journaux vous permettent de voir les actions des utilisateurs qui ont déclenché un événement collecté par Crashlytics dans votre application.
Désactivez les rapports d'erreur automatiques et activez les rapports avec option d'activation pour vos utilisateurs. Notez que, par défaut, Crashlytics collecte automatiquement les rapports d'erreur pour tous les utilisateurs de votre application.
Ajouter des clés personnalisées
Les clés personnalisées vous permettent de connaître l'état spécifique de votre application pouvant entraîner un plantage. Vous pouvez associer des paires clé/valeur arbitraires à vos rapports d'erreur, puis utiliser les clés personnalisées pour rechercher et filtrer les rapports d'erreur dans la console Firebase.
- Dans le tableau de bord Crashlytics, vous pouvez rechercher les problèmes qui correspondent à une clé personnalisée.
- Lorsque vous examinez un problème spécifique dans la console, vous pouvez afficher les clés personnalisées associées à chaque événement (sous-onglet Clés) et même filtrer les événements par clés personnalisées (menu Filtrer en haut de la page).
Utilisez la méthode setCustomValue
pour définir des paires clé/valeur. Exemple :
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
Lorsque vous définissez des entiers, des valeurs booléennes ou des nombres à virgule flottante, mettez la valeur entre crochets : @(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"];
Vous pouvez également modifier la valeur d'une clé existante en appelant la clé et en définissant une autre valeur. Exemple :
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"];
Ajoutez des paires clé/valeur de manière groupée à l'aide de la méthode setCustomKeysAndValues
avec un NSDictionary comme seul paramètre :
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];
Ajouter des messages de journaux personnalisés
Pour obtenir plus de contexte sur les événements ayant précédé un plantage, vous pouvez ajouter des journaux Crashlytics personnalisés à votre application. Crashlytics associe les journaux à vos données de plantage et les affiche sur la page Crashlytics de la console Firebase, sous l'onglet Journaux.
Swift
Utilisez log()
ou log(format:, arguments:)
pour identifier les problèmes. Si vous souhaitez obtenir un résultat de journal utile avec des messages, l'objet que vous transmettez à log()
doit être conforme à la propriété CustomStringConvertible
. log()
renvoie la propriété de description que vous définissez pour l'objet. Exemple :
Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")
.log(format:, arguments:)
met en forme les valeurs renvoyées par l'appel de getVaList()
. Exemple :
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))
Pour en savoir plus sur l'utilisation de log()
ou log(format:, arguments:)
, consultez la documentation de référence Crashlytics.
Objective-C
Utilisez log
ou logWithFormat
pour identifier les problèmes. Notez que si vous souhaitez obtenir un résultat de journal utile avec des messages, l'objet que vous transmettez à l'une ou l'autre des méthodes doit remplacer la propriété d'instance description
.
Exemple :
[[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];
Pour en savoir plus sur l'utilisation de log
et logWithFormat
, consultez la documentation de référence sur Crashlytics.
Définir des identifiants utilisateur
Pour diagnostiquer un problème, il est souvent utile de savoir quels utilisateurs ont rencontré un plantage donné. Crashlytics inclut un moyen d'identifier anonymement les utilisateurs dans vos rapports d'erreur.
Pour ajouter des User-ID à vos rapports, attribuez à chaque utilisateur un identifiant unique sous la forme d'un numéro d'ID, d'un jeton ou d'une valeur hachée :
Swift
Crashlytics.crashlytics().setUserID("123456789")
Objective-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
Si vous devez effacer un identifiant utilisateur après l'avoir défini, réinitialisez la valeur sur une chaîne vide. Effacer un identifiant utilisateur ne supprime pas les enregistrements Crashlytics existants. Si vous devez supprimer des enregistrements associés à un ID utilisateur, contactez l'assistance Firebase.
Signaler les exceptions non fatales
En plus de signaler automatiquement les plantages de votre application, Crashlytics vous permet d'enregistrer les exceptions non fatales et de vous les envoyer au prochain lancement de votre application.
Vous pouvez enregistrer les exceptions non fatales en enregistrant des objets NSError
avec la méthode recordError
. recordError
capture la pile d'appels du thread en appelant [NSThread callStackReturnAddresses]
.
Swift
Crashlytics.crashlytics().record(error: error)
Objective-C
[[FIRCrashlytics crashlytics] recordError:error];
Lorsque vous utilisez la méthode recordError
, il est important de comprendre la structure NSError
et la façon dont Crashlytics utilise les données pour regrouper les plantages. Une utilisation incorrecte de la méthode recordError
peut entraîner un comportement imprévisible et peut amener Crashlytics à limiter le signalement des erreurs consignées pour votre application.
Un objet NSError
comporte trois arguments :
domain: String
code: Int
userInfo: [AnyHashable : Any]? = nil
Contrairement aux plantages fatals, qui sont regroupés par analyse de la trace de pile, les erreurs consignées sont regroupées par domain
et code
. Il s'agit d'une distinction importante entre les plantages fatals et les erreurs consignées. Exemple :
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];
Lorsque vous consignez l'erreur ci-dessus, un problème est créé et regroupé par NSSomeErrorDomain
et -1001
. Les autres erreurs consignées qui utilisent les mêmes valeurs de domaine et de code sont regroupées sous le même problème. Les données contenues dans l'objet userInfo
sont converties en paires clé/valeur et affichées dans la section "Clés/Journaux" d'un problème spécifique.
Journaux et clés personnalisées
Comme pour les rapports d'erreur, vous pouvez intégrer des journaux et des clés personnalisées pour ajouter du contexte à NSError
. Toutefois, les journaux associés aux plantages ne sont pas les mêmes que ceux associés aux erreurs consignées. Lorsqu'un plantage se produit et que l'application est relancée, les journaux Crashlytics récupérés à partir du disque sont ceux qui ont été écrits jusqu'au moment du plantage. Lorsque vous enregistrez un NSError
, l'application ne s'arrête pas immédiatement. Étant donné que Crashlytics n'envoie le rapport d'erreur enregistré qu'au prochain lancement de l'application et qu'il doit limiter l'espace alloué aux journaux sur le disque, il est possible d'enregistrer suffisamment de journaux après l'enregistrement d'un NSError
pour que tous les journaux pertinents soient supprimés au moment où Crashlytics envoie le rapport depuis l'appareil. Gardez cet équilibre à l'esprit lorsque vous enregistrez NSErrors
et que vous utilisez des journaux et des clés personnalisées dans votre application.
Considérations sur les performances
N'oubliez pas que la journalisation d'un NSError
peut être assez coûteuse. Au moment où vous effectuez l'appel, Crashlytics capture la pile d'appels du thread actuel à l'aide d'un processus appelé déroulement de la pile. Ce processus peut être gourmand en ressources processeur et en E/S, en particulier sur les architectures compatibles avec le déroulement DWARF (arm64 et x86).
Une fois le déroulement terminé, les informations sont écrites sur le disque de manière synchrone.
Cela évite la perte de données en cas de plantage de la ligne suivante.
Bien qu'il soit possible d'appeler cette API sur un thread d'arrière-plan, n'oubliez pas que l'envoi de cet appel à une autre file d'attente perd le contexte de la trace de pile actuelle.
Qu'en est-il des NSExceptions ?
Crashlytics n'offre pas de fonctionnalité permettant d'enregistrer directement les instances NSException
. En règle générale, les API Cocoa et Cocoa Touch ne sont pas sécurisées contre les exceptions. Cela signifie que l'utilisation de @catch
peut avoir des effets secondaires indésirables très graves dans votre processus, même si vous l'utilisez avec une extrême prudence. Vous ne devez jamais utiliser d'instructions @catch
dans votre code. Veuillez consulter la documentation d'Apple à ce sujet.
Personnaliser les traces de pile
Si votre application s'exécute dans un environnement non natif (tel que C++ ou Unity), vous pouvez utiliser l'API Exception Model pour signaler les métadonnées de plantage au format d'exception natif de votre application. Les exceptions signalées sont marquées comme non fatales.
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];
Les frames de pile personnalisés peuvent également être initialisés avec des adresses uniquement :
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];
Obtenir les journaux du fil d'Ariane
Les journaux de fil d'Ariane vous permettent de mieux comprendre les interactions d'un utilisateur avec votre application avant un plantage, une erreur non fatale ou un événement ANR. Ces journaux peuvent être utiles pour reproduire et déboguer un problème.
Les journaux de fil d'Ariane sont fournis par Google Analytics. Pour les obtenir, vous devez activer Google Analytics pour votre projet Firebase et ajouter le SDK Firebase pour Google Analytics à votre application. Une fois ces conditions remplies, les journaux de fil d'Ariane sont automatiquement inclus dans les données d'un événement dans l'onglet Journaux lorsque vous affichez les détails d'un problème.
Le SDK Analytics enregistre automatiquement l'événement screen_view
, ce qui permet aux journaux de fil d'Ariane d'afficher la liste des écrans consultés avant le plantage, l'erreur non fatale ou l'événement ANR. Un journal de breadcrumbs screen_view
contient un paramètre firebase_screen_class
.
Les journaux de fil d'Ariane sont également renseignés avec tous les événements personnalisés que vous enregistrez manuellement dans la session de l'utilisateur, y compris les données des paramètres de l'événement. Ces données peuvent aider à afficher une série d'actions utilisateur ayant conduit à un plantage, une erreur non fatale ou un événement ANR.
Notez que vous pouvez contrôler la collecte et l'utilisation des données Google Analytics, y compris celles qui alimentent les journaux de fil d'Ariane.
Activer les rapports d'activation
Par défaut, Crashlytics collecte automatiquement les rapports d'erreur pour tous les utilisateurs de votre application. Pour donner aux utilisateurs plus de contrôle sur les données qu'ils envoient, vous pouvez activer les rapports avec option d'activation en désactivant les rapports automatiques et en n'envoyant des données à Crashlytics que lorsque vous le choisissez dans votre code.
Pour désactiver la collecte automatique, ajoutez une clé à votre fichier
Info.plist
:- Clé :
FirebaseCrashlyticsCollectionEnabled
- Valeur :
false
- Clé :
Activez la collecte pour certains utilisateurs en appelant le remplacement de la collecte de données Crashlytics au moment de l'exécution. La valeur de remplacement persiste lors de tous les lancements ultérieurs de votre application. Crashlytics peut ainsi collecter automatiquement des rapports pour cet utilisateur.
Swift
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
Objective-C
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
Si l'utilisateur désactive ultérieurement la collecte de données, vous pouvez transmettre
false
comme valeur de remplacement. Cette valeur s'appliquera la prochaine fois que l'utilisateur lancera l'application et persistera lors de tous les lancements ultérieurs pour cet utilisateur.
Gérer les données des insights sur les plantages
Les insights sur les plantages vous aident à résoudre les problèmes en comparant vos traces de pile anonymisées à celles d'autres applications Firebase. Ils vous indiquent si votre problème fait partie d'une tendance plus large. Pour de nombreux problèmes, les insights sur les plantages fournissent même des ressources pour vous aider à déboguer le plantage.
Crash Insights utilise des données de plantage agrégées pour identifier les tendances de stabilité courantes. Si vous préférez ne pas partager les données de votre application, vous pouvez désactiver les insights sur les plantages dans le menu Insights sur les plantages en haut de la liste des problèmes Crashlytics de la Firebase Console.