Personnaliser les rapports d'erreur pour les plates-formes Apple

Sélectionnez la plate-forme : iOS+ Android Flutter Unity


Vous pouvez cliquer sur un problème pour obtenir un rapport d'événement détaillé dans le DevOps et engagement > Crashlytics tableau de bord de la Firebase console. Vous pouvez personnaliser ces rapports pour mieux comprendre ce qui se passe dans votre application et les circonstances des événements signalés à Crashlytics.

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 de plantage, puis utiliser les clés personnalisées pour rechercher et filtrer les rapports de plantage dans le tableau de bord DevOps et engagement > Crashlytics de la Firebase console.

  • 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 valeurs à virgule flottante, encadrez la valeur avec @(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 lui attribuant une valeur différente. 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 en bloc à 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 journal personnalisés

Pour obtenir plus de contexte sur les événements qui ont conduit à un plantage, vous pouvez ajouter des journaux Crashlytics personnalisés à votre application. Crashlytics associe les journaux à vos données de plantage et les affiche dans l'onglet Journaux lorsque vous consultez les détails d'un problème (consultez tous vos problèmes dans le tableau de bord DevOps et engagement > Crashlytics de la console Firebase).

Swift

Utilisez log() ou log(format:, arguments:) pour identifier les problèmes. Si vous souhaitez obtenir une sortie de journal utile avec des messages, l'objet que vous transmettez à log() doit être conforme à la CustomStringConvertible propriété. 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 Crashlytics documentation de référence.

Objective-C

Utilisez log ou logWithFormat pour identifier les problèmes. Notez que si vous souhaitez obtenir une sortie de journal utile avec des messages, l'objet que vous transmettez à l'une ou l'autre méthode 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 Crashlytics documentation de référence.

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 de plantage.

Pour ajouter des ID utilisateur à 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. L'effacement d'un identifiant utilisateur ne supprime pas les enregistrements existants Crashlytics. 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 des 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 comment 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 enregistré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 via l'analyse de la trace de la pile, les erreurs enregistrées sont regroupées par domain et code. Il s'agit d'une distinction importante entre les plantages fatals et les erreurs enregistré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 enregistrez l'erreur ci-dessus, un problème est créé et regroupé par NSSomeErrorDomain et -1001. Les autres erreurs enregistré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 des clés/journaux d'un problème individuel.

Journaux et clés personnalisées

Comme pour les rapports de plantage, vous pouvez intégrer des journaux et des clés personnalisées pour ajouter du contexte à NSError. Toutefois, les journaux associés aux plantages et aux erreurs enregistrées sont différents. Lorsqu'un plantage se produit et que l'application est relancée, les journaux Crashlytics récupère sur le disque sont ceux qui ont été écrits jusqu'à le 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 doit limiter l'espace alloué aux journaux sur le disque, il est possible d'enregistrer suffisamment de données 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. Tenez compte de cet équilibre lorsque vous enregistrez des 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 l'enregistrement d'un NSError peut être assez coûteux. 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 intensif en termes de processeur et d'E/S, en particulier sur les architectures qui prennent en charge 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 si la ligne suivante plante.

Bien qu'il soit sûr d'appeler cette API sur un thread d'arrière-plan, n'oubliez pas que la distribution de cet appel à une autre file d'attente perd le contexte de la trace de la pile actuelle.

Qu'en est-il des NSExceptions ?

Crashlytics ne propose pas de fonctionnalité permettant d'enregistrer et d'enregistrer directement les instances NSException. En règle générale, les API Cocoa et Cocoa Touch ne sont pas sécurisées en cas d'exception. Cela signifie que l'utilisation de @catch peut avoir des effets secondaires indésirables très graves dans votre processus, même lorsqu'elle est utilisée avec une extrême prudence. Vous ne devez jamais utiliser d'instructions @catch dans votre code. Consultez la documentation d'Apple sur le 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 des journaux de navigation

Les journaux de navigation vous permettent de mieux comprendre les interactions d'un utilisateur avec votre application avant un plantage, un problème non fatal ou un événement ANR. Ces journaux peuvent être utiles lorsque vous essayez de reproduire et de déboguer un problème.

Les journaux de navigation sont alimentés 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 navigation sont automatiquement inclus dans les données d'un événement dans l'onglet Journaux lorsque vous consultez les détails d'un problème (consultez tous vos problèmes dans le tableau de bord DevOps et engagement > Crashlytics de la console Firebase).

Le Analytics SDK enregistre automatiquement l'événement screen_view, ce qui permet aux journaux de fil d'Ariane d'afficher une liste des écrans consultés avant le plantage, le problème non fatal ou l'événement ANR. Un journal de navigation screen_view contient un paramètre firebase_screen_class.

Les journaux de navigation 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 de paramètre de l'événement. Ces données peuvent aider à afficher une série d'actions utilisateur ayant conduit à un plantage, un problème non fatal ou un événement ANR.

Notez que vous pouvez contrôler la collecte et l'utilisation des donnéesGoogle Analytics, y compris les données qui alimentent les journaux de navigation.

Activer le signalement sur activation

Par défaut, Crashlytics collecte automatiquement les rapports de plantage 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 le signalement sur activation en désactivant le signalement automatique et en n'envoyant des données à Crashlytics que lorsque vous le choisissez dans votre code.

  1. Désactivez la collecte automatique en ajoutant une nouvelle clé à votre fichier Info.plist :

    • Clé : FirebaseCrashlyticsCollectionEnabled
    • Valeur : false
  2. Activez la collecte pour certains utilisateurs en appelant le Crashlytics remplacement de la collecte de données 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 au prochain lancement de l'application par l'utilisateur et persistera lors de tous les lancements ultérieurs pour cet utilisateur.

Gérer les données Crash Insights

Crash Insights vous aide à résoudre les problèmes en comparant vos traces de pile anonymisées à celles d'autres applications Firebase et en vous indiquant si votre problème s'inscrit dans une tendance plus large. Pour de nombreux problèmes, Crash Insights fournit 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 Crash Insights dans le menu Crash Insights en haut de la liste des problèmes du tableau de bord DevOps et engagement > Crashlytics de la Firebase console.

Étapes suivantes