Ir para o console

Personalizar relatórios de erros do Firebase Crashlytics

Para o Firebase Crashlytics funcionar, você praticamente não precisa configurá-lo. Assim que você adiciona o SDK, o Crashlytics começa a funcionar enviando relatórios de falhas para o Console do Firebase.

Para fornecer mais insights sobre relatórios de erros, o Firebase Crashlytics oferece quatro mecanismos de geração de registros: chaves personalizadas, registros personalizados, identificadores de usuários e exceções capturadas.

Adicionar chaves personalizadas

As chaves personalizadas ajudam você a saber o estado específico do seu aplicativo que está gerando uma falha. Você pode associar pares de chave/valor arbitrários aos seus relatórios de erros e vê-los no Console do Firebase.

Comece com [CrashlyticsKit setObjectValue:forKey:] ou um dos métodos relacionados:

- (void)setObjectValue:(id)value forKey:(NSString *)key;

// calls -description on value, perfect for NSStrings!
- (void)setIntValue:(int)value forKey:(NSString *)key;

- (void)setBoolValue:(BOOL)value forKey:(NSString *)key;

- (void)setFloatValue:(float)value forKey:(NSString *)key;

Às vezes, você precisa alterar o valor da chave existente. Chame a mesma chave, mas substitua o valor, por exemplo:

Objective-C
[CrashlyticsKit setIntValue:3 forKey:@"current_level"];
[CrashlyticsKit setObjectValue:@"logged_in" forKey:@"last_UI_action"];
Swift
Crashlytics.sharedInstance().setIntValue(42, forKey: "MeaningOfLife")
Crashlytics.sharedInstance().setObjectValue("Test value", forKey: "last_UI_action")

Adicionar mensagens de registro personalizadas

Para que você tenha mais contexto sobre os eventos que causam falhas, é possível adicionar registros personalizados do Crashlytics ao seu aplicativo. O Crashlytics associa os registros aos seus dados de falhas e os torna visíveis no Console do Firebase .

Objective-C

Em Objective-C, use CLS_LOG para ajudar a identificar problemas. Ele inclui automaticamente informações sobre a classe, o método e o número da linha em Objective-C associados ao registro.

O comportamento de CLS_LOG muda caso ele esteja registrando uma compilação de depuração ou de lançamento:

  • Compilações de depuração: o CLS_LOG é transmitido para o NSLog. Dessa forma, é possível ver o resultado no Xcode no dispositivo ou no simulador.
  • Compilações de lançamento: para melhorar o desempenho, o CLS_LOG silencia todos os outros resultados e não é transmitido ao NSLog.

Use CLS_LOG(format, ...) para registrar com CLS_LOG. Exemplo:

CLS_LOG(@"Higgs-Boson detected! Bailing out... %@", attributesDict);

Procure o arquivo de cabeçalho Crashlytics/Crashlytics.h para mais detalhes sobre como usar CLS_LOG.

Swift

Em Swift, use CLSLogv ou CLSNSLogv para ajudar a identificar problemas.

Há dois pontos a serem considerados ao gerar registros com CLSLogv e CLSNSLogv:

  • Seu argumento de formato precisa ser uma string constante de tempo de compilação. Isso é executado pelo compilador em Objective-C, mas essa proteção é perdida na transição para Swift.
  • Armazene os valores do registro em uma matriz e chame getVaList nessa matriz para recuperá-los.

Exemplo:

func write(string: String) {
    CLSLogv("%@", getVaList([string]))
}
A interpolação de string Swift não resultará em uma string constante de tempo de compilação. Assim como com printf e NSLog, usar uma string não constante com CLSLog pode resultar em uma falha.

Avançado

Para ter mais controle, é possível usar diretamente CLSLog(format, ...) e CLSNSLog(format, ...). Este último é transmitido para o NSLog de modo que é possível ver o resultado no Xcode ou no dispositivo ou simulador. CLSLog(format, ...) e CLSNSLog(format, ...) têm linhas de execução não concorrentes. CLSLog destina-se a registrar informações importantes para solucionar falhas. Não deve ser usado para rastrear eventos no aplicativo.

Definir identificadores de usuários

Para diagnosticar um problema, muitas vezes é útil saber quais usuários tiveram uma determinada falha. O Crashlytics inclui uma maneira de identificar anonimamente os usuários nos seus relatórios de erros.

Para adicionar IDs de usuários aos seus relatórios, atribua a cada usuário um identificador exclusivo na forma de um número de identificação, token ou hash:

Objective-C
[CrashlyticsKit setUserIdentifier:@"123456789"];
Swift
Crashlytics.sharedInstance().setUserIdentifier("123456789")

Se você precisar apagar um identificador de usuário depois de configurá-lo, redefina o valor deixando uma string em branco. Limpar um identificador de usuário não remove os registros atuais do Crashlytics. Se você precisar excluir registros associados a um ID de usuário, entre em contato com o suporte do Firebase.

Registrar exceções não fatais

Além de registrar automaticamente falhas do seu aplicativo, o Crashlytics permite que você registre exceções não fatais.

No iOS, isso é possível por meio do registro de objetos NSError, que o Crashlytics registra e agrupa assim como ocorre com as falhas:

Objective-C
[CrashlyticsKit recordError:error];
Swift
Crashlytics.sharedInstance().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 exigir que o Crashlytics limite relatórios de erros registrados para seu aplicativo.

Um objeto NSError tem três argumentos: domain: String, code: Int e userInfo: [AnyHashable : Any]? = nil

Ao contrário de 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 do NSError. Esta é uma distinção importante entre falhas fatais e erros registrados. Por exemplo, registrar um erro como:

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";
    UserID: @"Jane Smith"
};

NSError *error = [NSError domain:NSSomeErrorDomain
                          code:-1001
                          userInfo:userInfo];

Isso cria um novo problema que é agrupado por NSSomeErrorDomain e -1001. Demais erros registrados que usam o mesmo domínio e valores de código serão agrupados nesse problema.

Evite usar valores exclusivos como IDs de usuários, de produtos e carimbos de data/hora nos campos de domínio e código. O uso de valores exclusivos nesses campos causa uma alta cardinalidade de problemas e pode fazer com que o Crashlytics precise limitar os relatórios de erros registrados no seu aplicativo. Os valores exclusivos devem, em vez disso, ser adicionados ao objeto userInfo do dicionário.

Os dados contidos no objeto userInfo são convertidos em pares de chave-valor e exibidos na seção de chaves/registros em um problema individual.

O Crashlytics armazena apenas as oito exceções mais recentes em uma determinada sessão do aplicativo. Se o aplicativo lançar mais de oito exceções em uma sessão, as antigas serão perdidas.

Registros e chaves personalizadas

Assim como os relatórios de erros, você pode incorporar registros e chaves personalizadas para adicionar contexto ao NSError. No entanto, há uma diferença entre registros anexados a falhas e erros registrados. Quando ocorre uma falha e o aplicativo é reiniciado, os registros do Crashlytics recuperados do disco são os 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 erro registrado na próxima inicialização do aplicativo e precisa limitar a quantidade de espaço alocada para registros no disco, é possível registrar o suficiente depois que um NSError é gravado para que todos os registros relevantes sejam substituídos no momento em que o Crashlytics enviar o relatório do dispositivo. Tenha em mente esse equilíbrio ao registrar NSErrors e usar o CLSLog e chaves personalizadas em seu aplicativo.

Considerações sobre desempenho

Atente-se ao fato de que registrar um NSError pode ser bastante caro. No momento em que você faz a chamada, o Crashlytics captura a pilha de chamadas da linha de execução atual usando um processo chamado desenrolamento de pilha. Esse processo pode ser intenso para CPU e E/S, particularmente em arquiteturas compatíveis com desenrolamento DWARF (arm64 e x86). Quando o desenrolamento estiver finalizado, as informações serão gravadas em disco de maneira síncrona. Isso evita a perda de dados se a próxima linha falhar.

É seguro chamar essa API em uma linha de execução em segundo plano, mas lembre-se de que despachar essa chamada para outra fila fará com que o contexto do rastreamento da pilha atual seja perdido.

E as NSExceptions?

O Crashlytics não oferece uma facilidade para registrar ou gravar instâncias de NSExceptions diretamente. De modo geral, as APIs Cocoa e Cocoa Touch não são seguras contra exceções. Isso significa que o uso de @catch pode causar grandes efeitos colaterais no seu processo, mesmo quando usado com muito cuidado. Você nunca deve usar as instruções @catch no seu código. Consulte a documentação da Apple (em inglês) sobre o assunto.

Ativar a permissão para geração de relatórios

Por padrão, o Firebase Crashlytics coleta automaticamente relatórios de falhas de todos os usuários do seu aplicativo. Para dar aos usuários mais controle sobre os dados que enviam, você pode ativar a permissão para geração de relatórios.

Para isso, você deve desativar a coleta automática e inicializar o Crashlytics somente para os usuários que tiverem permitido a geração de relatórios.

  1. Desative a coleta automática com uma nova chave no arquivo Info.plist:
    • Chave: firebase_crashlytics_collection_enabled
    • Valor: false
  2. Ative a coleta para usuários selecionados inicializando o Crashlytics no ambiente de execução:
    Objective-C
    [Fabric with:@[[Crashlytics class]]];
    Swift
    Fabric.with([Crashlytics.self])

Gerenciar dados do Crash Insights

Com o Crash Insights, você soluciona problemas quando compara rastreamentos anônimos de pilhas com os de outros aplicativos do Firebase. Você será informado se o problema fizer parte de uma tendência maior. Para muitos problemas, o Crash Insights também oferece recursos para ajudá-lo a depurar a falha.

Ele usa dados de falhas agregados para identificar tendências de estabilidade comuns. Caso prefira não compartilhar os dados do app, é possível desativar o Crash Insights no menu com o mesmo nome na parte superior da lista de problemas do Crashlytics no Console do Firebase.