No painel do Crashlytics, você pode clicar em um problema e obter um relatório detalhado do evento. Você pode personalizar esses relatórios para ajudar a entender melhor o que está acontecendo no seu aplicativo e as circunstâncias dos eventos relatados ao Crashlytics.
Instrumente seu aplicativo para registrar chaves personalizadas , mensagens de log personalizadas e identificadores de usuário .
Relate exceções ao Crashlytics.
Obtenha registros de localização atual automaticamente se seu aplicativo usar o SDK do Firebase para Google Analytics. Esses registros fornecem visibilidade das ações do usuário que levaram a um evento coletado pelo Crashlytics no seu aplicativo.
Desative o relatório automático de falhas e ative o relatório opcional para seus usuários. Observe que, por padrão, o Crashlytics coleta automaticamente relatórios de erros de todos os usuários do seu aplicativo.
Adicione chaves personalizadas
As chaves personalizadas ajudam você a obter o estado específico do seu aplicativo que levou a uma falha. Você pode associar pares chave/valor arbitrários aos seus relatórios de falhas e, em seguida, usar as chaves personalizadas para pesquisar e filtrar relatórios de falhas no Console do Firebase.
- No painel do Crashlytics , você pode pesquisar problemas que correspondam a uma chave personalizada.
- Ao revisar um problema específico no console, você pode visualizar as chaves personalizadas associadas a cada evento (subguia Chaves ) e até mesmo filtrar os eventos por chaves personalizadas (menu Filtro na parte superior da página).
Use o método setCustomValue
para definir pares chave/valor. Por exemplo:
Rápido
// Set int_key to 100. Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key") // Set str_key to "hello". Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")
Objetivo-C
Ao definir números inteiros, booleanos ou flutuantes, coloque o valor na caixa como @( 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"];
Você também pode modificar o valor de uma chave existente chamando a chave e definindo-a com um valor diferente. Por exemplo:
Rápido
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key") // Set int_key to 50 from 100. Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")
Objetivo-C
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"]; // Set int_key to 50 from 100. [[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];
Adicione pares chave/valor em massa usando o método setCustomKeysAndValues
com um NSDictionary como único parâmetro:
Rápido
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)
Objetivo-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];
Adicione mensagens de log personalizadas
Para ter mais contexto sobre os eventos que levaram a uma falha, você pode adicionar registros personalizados do Crashlytics ao seu aplicativo. O Crashlytics associa os registros aos dados de falhas e os exibe na página Crashlytics do console do Firebase , na guia Logs .
Rápido
Use log()
ou log(format:, arguments:)
para ajudar a identificar problemas. Se você deseja obter uma saída de log útil com mensagens, o objeto que você passa para log()
deve estar em conformidade com a propriedade CustomStringConvertible
. log()
retorna a propriedade de descrição que você define para o objeto. Por exemplo:
Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")
.log(format:, arguments:)
formata os valores retornados da chamada getVaList()
. Por exemplo:
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))
Para obter mais detalhes sobre como usar log()
ou log(format:, arguments:)
, consulte a documentação de referência do Crashlytics.
Objetivo-C
Use log
ou logWithFormat
para ajudar a identificar problemas. Observe que se você deseja obter uma saída de log útil com mensagens, o objeto que você passa para qualquer um dos métodos deve substituir a propriedade da instância de description
. Por exemplo:
[[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];
Para obter mais detalhes sobre como usar log
e logWithFormat
, consulte a documentação de referência do Crashlytics.
Definir identificadores de usuário
Para diagnosticar um problema, muitas vezes é útil saber quais dos seus usuários sofreram uma determinada falha. O Crashlytics inclui uma maneira de identificar usuários anonimamente em seus relatórios de falhas.
Para adicionar IDs de usuário aos seus relatórios, atribua a cada usuário um identificador exclusivo na forma de um número de ID, token ou valor com hash:
Rápido
Crashlytics.crashlytics().setUserID("123456789")
Objetivo-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
Se você precisar limpar um identificador de usuário depois de defini-lo, redefina o valor para uma sequência em branco. Limpar um identificador de usuário não remove os registros existentes do Crashlytics. Se você precisar excluir registros associados a um ID de usuário, entre em contato com o suporte do Firebase .
Relatar exceções não fatais
Além de relatar automaticamente as falhas do seu aplicativo, o Crashlytics permite registrar exceções não fatais e enviá-las para você na próxima vez que o aplicativo for iniciado.
Você pode registrar exceções não fatais gravando objetos NSError
com o método recordError
. recordError
captura a pilha de chamadas do thread chamando [NSThread callStackReturnAddresses]
.
Rápido
Crashlytics.crashlytics().record(error: error)
Objetivo-C
[[FIRCrashlytics crashlytics] recordError:error];
Ao usar o método recordError
, é importante entender a estrutura NSError
e como o Crashlytics usa os dados para agrupar falhas. O uso incorreto do método recordError
pode causar um comportamento imprevisível e fazer com que o Crashlytics limite o relatório de erros registrados para seu aplicativo.
Um objeto NSError
possui três argumentos:
-
domain: String
-
code: Int
-
userInfo: [AnyHashable : Any]? = nil
Ao contrário das falhas fatais, que são agrupadas por meio de análise de rastreamento de pilha, os erros registrados são agrupados por domain
e code
. Esta é uma distinção importante entre falhas fatais e erros registrados. Por exemplo:
Rápido
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)
Objetivo-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];
Quando você registra o erro acima, ele cria um novo problema agrupado por NSSomeErrorDomain
e -1001
. Erros registrados adicionais que usam os mesmos valores de domínio e código são agrupados no mesmo problema. Os dados contidos no objeto userInfo
são convertidos em pares de valores-chave e exibidos na seção chaves/logs dentro de um problema individual.
Logs e chaves personalizadas
Assim como os relatórios de falhas, você pode incorporar logs e chaves personalizadas para adicionar contexto ao NSError
. No entanto, há uma diferença entre quais logs são anexados a falhas e erros registrados. Quando ocorre uma falha e o aplicativo é reiniciado, os registros que o Crashlytics recupera do disco são aqueles que foram gravados até o momento da falha. Quando você registra um NSError
, o aplicativo não é encerrado imediatamente. Como o Crashlytics só envia o relatório de erros registrados na próxima inicialização do aplicativo e deve limitar a quantidade de espaço alocado para logs no disco, é possível registrar o suficiente após um NSError
ser registrado para que todos os logs relevantes sejam alternados no momento em que o Crashlytics envia o relatório do dispositivo. Lembre-se desse equilíbrio ao registrar NSErrors
e usar logs e chaves personalizadas em seu aplicativo.
Considerações de desempenho
Tenha em mente que registrar um NSError
pode ser bastante caro. No momento em que você faz a chamada, o Crashlytics captura a pilha de chamadas do thread atual usando um processo chamado desenrolamento de pilha. Esse processo pode exigir uso intensivo de CPU e E/S, especialmente em arquiteturas que suportam desenrolamento DWARF (arm64 e x86). Após a conclusão do desenrolamento, as informações são gravadas no disco de forma síncrona. Isso evita a perda de dados se a próxima linha falhar.
Embora seja seguro chamar essa API em um thread em segundo plano, lembre-se de que despachar essa chamada para outra fila perde o contexto do rastreamento de pilha atual.
E quanto às NSExceptions?
O Crashlytics não oferece um recurso para registrar e registrar instâncias NSException
diretamente. De modo geral, as APIs Cocoa e Cocoa Touch não são seguras contra exceções. Isso significa que o uso do @catch
pode ter efeitos colaterais indesejados muito graves no seu processo, mesmo quando usado com extremo cuidado. Você nunca deve usar instruções @catch
em seu código. Consulte a documentação da Apple sobre o assunto.
Personalize rastreamentos de pilha
Se o seu aplicativo for executado em um ambiente não nativo (como C++ ou Unity), você poderá usar a API do modelo de exceção para relatar metadados de falha no formato de exceção nativo do seu aplicativo. As exceções relatadas são marcadas como não fatais.
Rápido
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)
Objetivo-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];
Stack frames personalizados também podem ser inicializados apenas com endereços:
Rápido
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)
Objetivo-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];
Obtenha registros de localização atual
Os registros de localização atual fornecem uma melhor compreensão das interações que um usuário teve com seu aplicativo, levando a um evento de falha, não fatal ou ANR. Esses logs podem ser úteis ao tentar reproduzir e depurar um problema.
Os registros de navegação estrutural são desenvolvidos pelo Google Analytics. Portanto, para obtê-los, você precisa ativar o Google Analytics para seu projeto do Firebase e adicionar o SDK do Firebase para Google Analytics ao seu aplicativo. Depois que esses requisitos forem atendidos, os logs de navegação serão automaticamente incluídos nos dados de um evento na guia Logs quando você visualizar os detalhes de um problema.
O SDK do Analytics registra automaticamente o evento screen_view
, que permite que os registros de localização atual mostrem uma lista de telas visualizadas antes do evento de falha, não fatal ou ANR. Um log de localização atual screen_view
contém um parâmetro firebase_screen_class
.
Os logs de localização atual também são preenchidos com quaisquer eventos personalizados registrados manualmente na sessão do usuário, incluindo os dados de parâmetro do evento. Esses dados podem ajudar a mostrar uma série de ações do usuário que levam a um evento de falha, não fatal ou ANR.
Observe que você pode controlar a coleta e o uso de dados do Google Analytics , que incluem os dados que preenchem os registros de localização atual.
Ativar relatórios de aceitação
Por padrão, o Crashlytics coleta automaticamente relatórios de erros de todos os usuários do seu aplicativo. Para dar aos usuários mais controle sobre os dados que enviam, você pode ativar os relatórios de aceitação desativando os relatórios automáticos e enviando dados ao Crashlytics apenas quando desejar em seu código:
Desative a coleta automática adicionando uma nova chave ao seu arquivo
Info.plist
:- Chave:
FirebaseCrashlyticsCollectionEnabled
- Valor:
false
- Chave:
Habilite a coleta para usuários selecionados chamando a substituição da coleta de dados do Crashlytics em tempo de execução. O valor de substituição persiste durante as inicializações do seu aplicativo para que o Crashlytics possa coletar relatórios automaticamente.
Para cancelar o relatório automático de falhas, passe
false
como o valor de substituição. Quando definido comofalse
, o novo valor não se aplica até a próxima execução do aplicativo.Rápido
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
Objetivo-C
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
Gerenciar dados do Crash Insights
O Crash Insights ajuda a resolver problemas comparando seus rastreamentos de pilha anônimos com rastreamentos de outros aplicativos do Firebase e informando se o problema faz parte de uma tendência maior. Para muitos problemas, o Crash Insights ainda fornece recursos para ajudá-lo a depurar a falha.
Crash Insights usa dados agregados de falhas para identificar tendências comuns de estabilidade. Se preferir não compartilhar os dados do seu aplicativo, você pode desativar o Crash Insights no menu Crash Insights, na parte superior da lista de problemas do Crashlytics no console do Firebase .