Recentemente, tive que investigar um problema de campo para nosso aplicativo corporativo de grande porte. Fiquei horrorizado com os logs que tive que vasculhar na tentativa de encontrar o problema e, no final do dia, os logs não ajudaram em nada a identificar / isolar o bug.
Nota: Entendo que nem todos os erros são detectáveis através de logs. Isso não altera o fato de que os logs são horríveis.
Existem alguns problemas óbvios em nosso registro que já podemos tentar corrigir. Não quero listá-las aqui e não posso simplesmente mostrar nossos arquivos de log para que você possa dar conselhos sobre o que fazer.
Em vez disso, para avaliar o quão ruim estamos no setor de extração de madeira, eu gostaria de saber:
- Quais são algumas diretrizes , se houver, quando se trata de registrar um aplicativo, especialmente um aplicativo grande.
- Existem padrões que devemos seguir ou antipadrões que devemos estar cientes?
- Isso é importante para corrigir ou pode ser corrigido ou todos os arquivos de log são simplesmente enormes e você precisa de scripts adicionais para analisá-los?
Nota lateral: usamos log4j.
Eu trabalho com sistemas críticos de segurança em tempo real, e a criação de logs geralmente é a única maneira de detectar bugs raros que aparecem uma vez na lua azul a cada 53ª terça-feira quando é lua cheia, se você entender minha tendência. Isso meio que deixa você obsessivo com o assunto, então peço desculpas agora se começar a espuma na boca. O seguinte foi escrito para logs de depuração de código nativo, mas a maioria também é aplicável ao mundo gerenciado ...
Use arquivos de log de texto. Parece óbvio, mas algumas pessoas tentam gerar arquivos de log binários: isso é idiota, porque eu não preciso procurar uma ferramenta de leitura quando estou em campo. Além disso, se for texto e a depuração for detalhada, há uma boa chance de o engenheiro de campo ler o arquivo e diagnosticar o problema sem nunca voltar para mim. Todo mundo ganha.
Projecto sistemas capazes de registrar praticamente tudo, mas por padrão não ligo tudo. As informações de depuração são enviadas para uma caixa de diálogo de depuração oculta, que as marca e as envia para uma caixa de listagem (limitada a cerca de 500 linhas antes da exclusão), e a caixa de diálogo permite que eu pare, salve-a automaticamente em um arquivo de log ou desvie-a para um depurador conectado. Esse desvio me permite ver a saída de depuração de vários aplicativos, tudo serializado ordenadamente, que às vezes pode salvar vidas. Eu costumava usar níveis de registro numérico (quanto mais alto você define o nível, mais captura):
mas isso é muito inflexível - à medida que você trabalha em direção a um bug, é muito mais eficiente concentrar-se em fazer exatamente o que você precisa sem precisar percorrer toneladas de detritos e pode ser um tipo específico de transação ou operação Isso causa o erro. Se isso exigir que você ligue tudo, você está apenas dificultando seu próprio trabalho. Você precisa de algo mais refinado.
Então agora estou no processo de mudar para o log com base em um sistema de sinalização. Tudo o que é registrado tem um sinalizador detalhando que tipo de operação é, e há um conjunto de caixas de seleção que permitem definir o que é registrado. Normalmente, essa lista fica assim:
Esse sistema de registro é fornecido com a compilação do release , ativada e salva em arquivo por padrão. É muito tarde para descobrir que você deveria estar registrando APÓS o bug ter ocorrido, se esse bug ocorrer apenas uma vez a cada seis meses em média e você não tiver como reproduzi-lo. O registro que funciona apenas com compilações de depuração é justo. avião. idiota.
O software normalmente é fornecido com ERROR, BASIC, STATE_CHANGE e EXCEPTION ativado, mas isso pode ser alterado no campo através da caixa de diálogo de depuração (ou uma configuração de registro / ini / cfg, onde essas coisas são salvas).
Ah, e uma coisa - meu sistema de depuração gera um arquivo por dia. Seus requisitos podem ser diferentes. Mas verifique se o seu código de depuração inicia todos os arquivos com a data, a versão do código que você está executando e, se possível, com algum marcador para o ID do cliente, a localização do sistema ou o que for. Você pode obter uma mistura de arquivos de log vindo do campo e precisa de algum registro do que veio de onde e qual versão do sistema eles estavam executando, que está realmente nos próprios dados e não pode confiar no cliente / engenheiro de campo para dizer qual versão eles têm - eles podem apenas dizer qual versão eles pensam que têm. Pior, eles podem relatar a versão exe que está no disco, mas a versão antiga ainda está em execução porque se esqueceu de reiniciar após a substituição. Faça com que seu código diga a si mesmo.
Por fim, você não deseja que seu código gere seus próprios problemas; portanto, coloque uma função de timer para limpar os arquivos de log após tantos dias ou semanas (basta verificar a diferença entre a hora atual e a hora da criação do arquivo). Isso é bom para um aplicativo de servidor que é executado o tempo todo; em um aplicativo do lado do cliente, você pode limpar todos os dados antigos ao iniciar. Normalmente, limpamos após 30 dias ou mais, em um sistema sem visitas frequentes ao engenheiro, talvez você queira deixá-lo por mais tempo. Obviamente, isso também depende do tamanho dos seus arquivos de log.
fonte
Meu recurso público favorito para diretrizes de registro em log é o Apache JCL Best Practices .
Apesar de direcionar a JCL, elas parecem ser genéricas o suficiente para serem adotadas para o log em geral.
O anti-padrão mais famoso é provavelmente "engolir exceções" - basta pesquisar na web por ele.
Quanto aos grandes arquivos de registro, na minha prática, esse era o caso normal. E sim, scripts suplementares como você os chama e / ou ferramentas como o Chainsaw também parecem normais para mim.
PS. Em relação aos antipadrões, outros que vêm à mente são mensagens "inundadas" e sem sentido.
Chamo de inundação quando vejo várias mensagens semelhantes provenientes de um loop com muitas iterações. Para mim, as inundações são irritantes o suficiente para tentar me livrar delas quando a detecto no código fonte. Geralmente, melhorá-lo requer alguma arte - porque, bem, as coisas que acontecem dentro do loop podem ser interessantes. Quando não tenho tempo para aprimorá-lo mais, tento alterar pelo menos o nível de log dessas mensagens para o mais baixo, para facilitar a filtragem.
Mensagens sem sentido parecem ser um lixo bastante popular. Eles parecem inofensivos quando lidos no código fonte - acho que é preciso passar pela dor de analisar a saída de depuração parecida com ...
... para apreciar profundamente sua feiura inerente. Minha heurística favorita para detectar esse tipo de problema no nível do código-fonte (proposto por um colega em um dos meus projetos anteriores) é calcular o número de ocorrências de símbolos de espaço em literais de string usados no log. Na minha experiência, zero espaços basicamente garante que a instrução de log não faz sentido, um espaço também é um bom indicador do possível problema.
fonte
somethingSpecialHappenedCount
) e depois enviada para o criador de logs.Registre a exceção apenas uma vez!
Um dos pontos problemáticos comuns que notei é o registro e a repetição de uma exceção. Como resultado, os arquivos de log contêm as mesmas exceções várias vezes em vários níveis de pilha.
fonte
Aqui está um antipadrão: Criar duas dúzias de campos "genéricos" em uma tabela de banco de dados para rastrear qualquer coisa concebível e, em seguida, ter 88 (e contar) valores de enumeração diferentes para diferentes tipos de logs.
fonte
Minha experiência com logs é quanto maior, melhor, mas seja consistente o suficiente para torná-lo filtrável por máquina e seja capaz de configurar um nível de severidade para cada componente do seu aplicativo individualmente.
Além disso, é muito difícil prever qual registro você precisará para encontrar um bug futuro. A maioria dos locais óbvios para registrar erros é corrigida antes que o produto saia pela porta. Não é incomum que o resultado de um relatório de bug seja que você acabou de adicionar o log para ajudar a diagnosticá-lo se isso acontecer novamente.
fonte
Algumas notas do lado de operações da casa aqui:
1) Verifique se os logs são configuráveis localmente, de preferência com uma ferramenta não mais pesada que um editor de texto. Na maioria das vezes, não queremos obter o registro no nível TRACE, mas gostamos de poder ativá-lo.
2) Se possível, verifique se os logs podem ser lidos com uma ferramenta não mais pesada que um editor de texto. Nada é pior do que ter que ir em uma busca de ferramentas em uma hora ímpar, quando o sistema de produção está falhando.
fonte
De minha própria experiência trabalhando com aplicativos da Web:
(e considerando o armazenamento é muito barato hoje em dia)
Seja consistente com suas seqüências de log. Desde sempre eu uso esse tipo de padrão:
fonte
Além do rastreamento de pilha, registre o estado atual do aplicativo e a entrada.
O software é determinístico, esses dois geralmente são a única coisa que você precisa para reproduzir o bug. O armazenamento do estado completo pode, em alguns casos, ser problemático, portanto, maneiras de reproduzir o estado atual, por exemplo, por entradas anteriores, também são boas.
É claro que mais dados são sempre melhores, mas no mínimo esses dois são um bom começo para as falhas mais fáceis.
fonte