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 informações sobre relatórios de falha, o Firebase Crashlytics oferece quatro mecanismos de registro: chaves personalizadas, registros personalizados, identificadores de usuários e exceções capturadas.

Adicionar chaves personalizadas

As chaves personalizadas ajudam você a chegar ao estado específico do seu aplicativo que está gerando uma falha. Você pode associar pares 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 falha, é possível adicionar registros personalizados do Crashlytics ao seu aplicativo. O Crashlytics associa os registros aos seus dados de falha e os torna visíveis no Console do Firebase.

Objective-C

No 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 do Objective-C associados ao registro.

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

  • Versõ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.
  • Versões de lançamento: para melhorar o desempenho, o CLS_LOG silencia todos os outros resultados e não é transmitido para o NSLog.

Use o CLS_LOG(format, ...) para registrar com o CLS_LOG. Por exemplo:

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

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

Swift

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

Ao gerar registros com CLSLogv e CLSNSLogv, considere os seguintes pontos:

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

Por 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, você pode usar diretamente CLSLog(format, ...) e CLSNSLog(format, ...). O último é passado até o NSLog de modo que você veja a saída no Xcode ou no dispositivo ou simulador. CLSLog(format, ...) e CLSNSLog(format, ...) são thread-safe. 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 códigos do usuário 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 para uma string em branco. Limpar um identificador de usuário não remove os registros existentes do Crashlytics. Se você precisar excluir registros associados a um código 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 como 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 pode 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 através de análise de rastreamento de pilha, os erros registrados são agrupados pelo domain e o code do NSError. Esta é uma distinção importante entre falhas fatais e erros registrados. Por exemplo, registrando 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];

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 códigos do usuário, do produto 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 apenas armazena 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 em quais registros são anexados a falhas ou em erros registrados. Quando ocorre uma falha e o aplicativo é relançado, os registros do Crashlytics recuperados do disco são os que foram escritos até o momento da falha. Quando você registra um NSError, o aplicativo não é encerrado imediatamente. Como o Crashlytics envia apenas 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 thread atual usando um processo chamado desenrolar 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 sã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 thread de 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 instalação para registrar ou gravar instâncias de NSException 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 tal, 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 tempo 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 agregadas para identificar tendências de estabilidade comuns. Caso prefira não compartilhar os dados do app, será 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.