Práticas recomendadas para log e rastreamento no .NET


53

Eu tenho lido muito sobre rastreamento e registro, tentando encontrar alguma regra de ouro para as melhores práticas no assunto, mas não há nenhuma. As pessoas dizem que bons programadores produzem bons rastreamentos, mas colocam assim e isso tem que vir da experiência.

Também li perguntas semelhantes aqui e pela Internet e elas não são exatamente a mesma coisa que estou perguntando ou não têm uma resposta satisfatória, talvez porque as perguntas carecem de detalhes.

Portanto, as pessoas dizem que o rastreamento deve replicar a experiência de depurar o aplicativo nos casos em que você não pode anexar um depurador. Ele deve fornecer contexto suficiente para que você possa ver qual caminho é seguido em cada ponto de controle no aplicativo.

Aprofundando, você pode até distinguir entre rastreamento e log de eventos, pois "o log de eventos é diferente do rastreamento, pois captura os principais estados em vez do fluxo detalhado de controle".

Agora, digamos que eu queira rastrear e registrar usando apenas as classes .NET padrão, aquelas no System.Diagnosticsespaço para nome. Imaginei que a classe TraceSource é melhor para o trabalho do que a classe estática Trace, porque quero diferenciar os níveis de rastreio e, usando a classe TraceSource, posso passar um parâmetro informando o tipo de evento enquanto estiver usando a classe Trace. Trace.WriteLineIfe depois verifique coisas como SourceSwitch.TraceInformatione SourceSwitch.TraceErrors, e ele nem sequer tem propriedades como TraceVerboseou TraceStart.

Com tudo isso em mente, você consideraria uma boa prática fazer o seguinte:

  • Rastreie um evento "Iniciar" ao iniciar um método, que deve representar uma única operação lógica ou um pipeline, juntamente com uma representação em cadeia dos valores dos parâmetros passados ​​para o método.
  • Rastreie um evento "Informações" ao inserir um item no banco de dados.
  • Rastreie um evento "Informações" ao seguir um caminho ou outro em uma instrução if / else importante.
  • Rastreie um "Crítico" ou "Erro" em um bloco de captura, dependendo se é um erro recuperável.
  • Rastreie um evento "Stop" ao concluir a execução do método.

Além disso, esclareça a melhor forma de rastrear os tipos de evento verboso e de aviso. Se você tiver exemplos de código com bom rastreamento / registro e estiver disposto a compartilhar, isso seria excelente.

Nota: Encontrei algumas informações boas aqui, mas ainda não o que estou procurando: http://msdn.microsoft.com/en-us/magazine/ff714589.aspx


talvez a maneira preferida de fazer logon na rede implantada no azure no stackoverflow também seja útil.
K3b

algum aplicativo de amostra de código-fonte completo usando bons padrões para o log?
Kiquenet

Sinceramente ... Se eu estivesse trabalhando com o .NET, provavelmente instalaria algo como o New Relic e terminaria. (Talvez não seja uma boa opção no momento em que foi publicada)
svidgen

Respostas:


17

A importância dos tipos de rastreamento deve ser escolhida não devido ao local onde o rastreamento está no código, mas porque a mensagem rastreada é mais ou menos importante. Exemplo:

Rastreie um evento "Iniciar" ao iniciar um método, que deve representar uma única operação lógica ou um pipeline, juntamente com uma representação em seqüência dos valores dos parâmetros passados ​​para o método.

Use o tipo de início ao iniciar uma operação lógica. Isso não significa que o rastreio inicial deve estar no início de um método, nem significa que um método deve ter um rastreio inicial.

Dito isto, na maioria dos casos, uma operação lógica realmente começará no início do método. Caso contrário, você deve se perguntar se o código foi refatorado corretamente.

Parâmetros de rastreamento também podem ser uma má ideia . Você tem que pensar no que rastrear, caso a caso. Por exemplo, é muito ruim rastrear parâmetros de um método void Authenticate(string userName, string plainPassword).

Rastreie um evento "Informações" ao inserir um item no banco de dados.

Depende. Alguns itens devem ser rastreados, mas nem todos os itens.

  • Por exemplo, imagine que você está realmente inserindo um item de log no seu banco de dados. Você rastreará logs? E depois registrar rastreamentos? E, em seguida, rastrear o log do rastreamento?
  • Outro exemplo: você está inserindo dados confidenciais. Isso requer auditoria. Desde que você auditou a inserção, por que rastreá-la?

Rastreie um evento "Informações" ao seguir um caminho ou outro em uma instrução if / else importante.

Mais uma vez, depende.

Rastrear um "Crítico" ou "Erro" em um bloco de captura, dependendo do clima, é um erro recuperável.

A ação executada após um erro não recuperável pode ser mais do que rastrear. Por exemplo, no lado do servidor, você gostaria de armazenar a exceção no banco de dados para análise posterior. Além disso, algumas exceções são menos importantes que outras e não requerem rastreamento.

Rastreie um evento "Stop" ao concluir a execução do método.

Veja o primeiro ponto.

esclareça a melhor forma de rastrear os tipos de evento verboso e de aviso.

Verbose:

Detalhado é usado para rastrear o que você precisa rastrear quando algo der realmente errado. Isso significa que, na maioria dos casos, você desabilitará o rastreamento de mensagens detalhadas, mas às vezes precisará depurar algumas partes do seu código para entender por que algo falha em um caso extremo.

Você geralmente tem muitas mensagens detalhadas que permitem entender muito bem o fluxo do aplicativo. Isso também significa que essas mensagens devem ser desativadas na maioria das vezes porque:

  • caso contrário, o log crescerá muito rápido,
  • você não precisa deles na maioria das vezes,
  • eles podem conter dados confidenciais sobre o fluxo do aplicativo.

Pense em detalhado como uma ferramenta que você deve usar quando não tiver acesso ao depurador.

Aviso:

O rastreamento do tipo de aviso é usado quando algo errado e importante acontece, mas não é crucial demais para ser tratado como um erro. Por exemplo, pouca RAM pode emitir um aviso, mas não há motivo para rastrear um erro, pois seu aplicativo pode continuar, mesmo que seja mais lento que o normal.

Exemplos:

  • Exemplo 1: o aplicativo falhou ao abrir o arquivo solicitado pelo usuário. O arquivo existe e não está em uso, as permissões são definidas corretamente, mas algo bloqueia a abertura de um arquivo. Nesse caso, você rastreará um erro , pois seu aplicativo não pode gerenciar este caso e continuará a funcionar conforme o esperado pelo usuário (ou seja, na verdade, leia o arquivo).

  • Exemplo 2: após a inspeção do erro no primeiro exemplo, você descobre que o erro é causado pelo fato de o caminho do arquivo ter mais de 259 caracteres. Então você refatora seu código para capturar PathTooLongException. Quando, na próxima vez em que o usuário tentar abrir o mesmo arquivo, a nova versão do aplicativo mostrará uma mensagem explicando que o arquivo é muito longo e deve ser movido para outra pasta para reduzir o caminho completo para abri-lo. esta aplicação. Você também rastreia uma mensagem .

  • Exemplo 3: seu aplicativo passou vinte segundos abrindo e analisando um arquivo pequeno, enquanto a maioria dos arquivos leva de dez a cem milissegundos para abrir e analisar. Você rastreia um aviso com informações relevantes: o tipo de disco onde o arquivo realmente está, o sistema de arquivos, o tamanho do arquivo, o tempo exato gasto, o tempo em que o computador estava ligado etc. Quando o usuário reclama que são necessários vinte segundos para abrir o arquivo, faça o rastreamento para descobrir o que acontece. Você descobre, por exemplo, que leva muito tempo para carregar os arquivos de um compartilhamento de rede quando o computador acaba de iniciar. Você explica ao usuário que o atraso é devido à rede e não está relacionado ao seu aplicativo.

  • Exemplo 4: o arquivo aberto é exibido incorretamente. Você ativa o rastreamento detalhado, onde realmente vê como os dados são carregados do arquivo e analisados ​​passo a passo.


Um padrão que usamos onde trabalho é registrar "KnownErrors" como avisos e "UnknownErrors" como erros. Pode não ser apropriado, dependendo da sua infraestrutura e de como ela lida com os avisos, mas funciona bem para nós.
Andrew Piliser

5
 > say I want to do my tracing and logging using only the standard .NET classes

System.Diagnostics é ótimo porque você pode configurar para onde quais informações de rastreamento devem ir para onde (arquivo, log de eventos, banco de dados, ....)

Infelizmente, se você deseja usar, System.Diagnosticsdeve saber com antecedência ( no momento do design ), quais fluxos de rastreamento devem ser possíveis de seguir. (No artigo de exemplo, são Transferir, Continuar, Suspender, ...). Estes podem ser configurados para serem desativados, nível de depuração ou nível de erro.

Prefiro ter um sistema de registro em que eu possa decidir, em tempo de execução, no nível de classe / namespacelevel , quão detalhado o registro deve ser. Por exemplo, todo Debug e acima de MyNamespace.Business.*mas não MyNamespace.Business.Calculations.

Se você estiver usando log4net (ou Common.logging), todas as classes obterão seu próprio criador de logs, para que você possa decidir facilmente quais classes serão registradas em qual nível.

Como as operações do banco de dados estão em uma classe separada, não há mais necessidade de uma regra distinta

Trace an "Information" event when inserting an item into the database.

Em vez disso, prefiro ter estas diretrizes:

  • O Tracelevel deve mostrar o fluxo de trabalho básico
  • O nível de depuração deve mostrar dados e processamento detalhados no fluxo de trabalho, incluindo decisões no fluxo de programas com motivos (Criando novo item porque o item não existia no banco de dados)
  • Nível de desenvolvimento para iniciar / parar serviços e uma entrada para cada ação do fluxo de trabalho / GUI iniciada

Entendo, que boa informação, obrigado! Mas, ainda assim, como pergunto na minha pergunta original, você poderia esclarecer os usos dos tipos de evento verboso e de aviso? E também peço a outras pessoas que contribuam com seu ponto de vista, porque esse tópico merece uma exploração mais profunda do que eu vi na internet.
Levidad 14/03/11

4

Você pode experimentar a estrutura do Story , que possui uma abordagem exclusiva para o log, pois "faz" você escrever todos os logs (e adicionar outras informações relevantes) no contexto. Assim, quando você precisar lê-lo mais tarde, terá tudo o que precisa.

Ele adicionará automaticamente os conceitos "iniciar" e "parar" como o início e o final de uma história.

E com um sistema baseado em regras, você pode controlar o que fazer com cada história (contexto) com base nas informações que ela possui, por exemplo, imprimir todas as histórias com erro ou provenientes do usuário "admin".

Também mais informações sobre este post do blog



11
resposta atualizada com mais informações
Amit Apple
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.