Práticas recomendadas de log [fechado]

323

Gostaria de obter histórias sobre como as pessoas lidam com o rastreamento e o logon em aplicativos reais. Aqui estão algumas perguntas que podem ajudar a explicar sua resposta.

Frameworks

Quais estruturas você usa?

  • log4net
  • System.Diagnostics.Trace
  • System.Diagnostics.TraceSource
  • Bloco de aplicativos de log
  • De outros?

Se você usa o rastreamento, utiliza Trace.Correlation.StartLogicalOperation?

Você escreve esse código manualmente ou usa alguma forma de programação orientada a aspectos para fazer isso? Gostaria de compartilhar um trecho de código?

Você fornece alguma forma de granularidade sobre fontes de rastreamento? Por exemplo, o WPF TraceSources permite configurá-los em vários níveis:

  • System.Windows - configurações para todo o WPF
  • System.Windows.Animation - substituir especificamente para Animação.

Ouvintes

Quais saídas de log você usa?

  • Arquivos de texto
  • Arquivos XML
  • Log de eventos
  • De outros?

Se estiver usando arquivos, você usa logs contínuos ou apenas um único arquivo? Como você disponibiliza os logs para as pessoas consumirem?

Visualizando

Quais ferramentas você usa para visualizar os logs?

  • Bloco de anotações
  • Rabo
  • Visualizador de eventos
  • Gerente de Operações do Systems Center / Gerente de Operações da Microsoft
  • Visualizador de rastreamento de serviço WCF
  • De outros?

Se você estiver criando uma solução ASP.NET, também usa o Monitoramento de Integridade do ASP.NET? Você inclui saída de rastreio nos eventos do monitor de integridade? E o Trace.axd?

E os contadores de desempenho personalizados?

Paul Stovell
fonte
3
Seria útil que pessoas que encerrassem perguntas como essa com 300 votos positivos pudessem sugerir um formato wiki ou postar em programmers.stackexchange, ou então o Quora, se esse tipo de pergunta não for bem-vindo. Obviamente, a pergunta é realmente muito construtiva, apenas não está de acordo com os critérios que o StackOverflow deseja. programmers.stackexchange.com/questions/57064/… possui 24 votos positivos. Talvez o StackOverflow esteja faltando alguma coisa?
Niall Connaughton
Se esta pergunta violar o formato de perguntas e respostas, ALGO ESTÁ ERRADO com o formato de perguntas e respostas e não com esta pergunta. Às vezes, a decisão de fechar uma pergunta deve ser uma função das respostas fornecidas, algumas perguntas abertas convidam ao debate, mas outras convidam os usuários a fornecer conteúdo valioso, como este!
Matthias Wolf #
1
Essa pergunta - particularmente a principal resposta - provavelmente seria uma excelente base para uma postagem no blog se alguém quisesse usá-la como tal ... Como uma pergunta objetiva, ela realmente não se encaixa - ela é estruturada explicitamente como uma pesquisa de opinião - mas há algumas boas informações abaixo, daí o bloqueio.
Shog9

Respostas:

232

Atualização: para extensões ao System.Diagnostics, fornecendo alguns dos ouvintes que você deseja, consulte Essential.Diagnostics no CodePlex ( http://essentialdiagnostics.codeplex.com/ )


Frameworks

P: Quais estruturas você usa?

R: System.Diagnostics.TraceSource, incorporado ao .NET 2.0.

Ele fornece logs poderosos, flexíveis e de alto desempenho para aplicativos, no entanto, muitos desenvolvedores não estão cientes de seus recursos e não os utilizam totalmente.

Existem algumas áreas em que a funcionalidade adicional é útil ou, às vezes, a funcionalidade existe, mas não está bem documentada; no entanto, isso não significa que toda a estrutura de log (projetada para ser extensível) deve ser descartada e substituída completamente, como algumas alternativas populares (NLog, log4net, Common.Logging e até mesmo EntLib Logging).

Em vez de alterar a maneira como você adiciona instruções de registro em seu aplicativo e reinventa a roda, apenas estendeu a estrutura System.Diagnostics nos poucos locais em que você precisa.

Parece-me que as outras estruturas, mesmo a EntLib, simplesmente sofrem da Síndrome de Not Invented Here, e acho que perderam tempo reinventando os conceitos básicos que já funcionam perfeitamente bem no System.Diagnostics (como a forma como você escreve instruções de log), em vez de preencher as poucas lacunas existentes. Em resumo, não os use - eles não são necessários.

Recursos que você talvez não conheça:

  • O uso das sobrecargas TraceEvent que usam uma sequência de caracteres de formato e args pode ajudar no desempenho, pois os parâmetros são mantidos como referências separadas até que o Filter.ShouldTrace () tenha sido bem-sucedido. Isso significa que nenhuma chamada cara para ToString () nos valores dos parâmetros até que o sistema confirme que a mensagem será efetivamente registrada.
  • O Trace.CorrelationManager permite correlacionar instruções de log sobre a mesma operação lógica (veja abaixo).
  • VisualBasic.Logging.FileLogTraceListener é bom para gravar arquivos de log e oferece suporte à rotação de arquivos. Embora no espaço para nome VisualBasic, ele pode ser usado com a mesma facilidade em um projeto C # (ou outro idioma) simplesmente incluindo a DLL.
  • Ao usar EventLogTraceListener se você chamar TraceEvent com vários argumentos e com uma sequência de formato vazia ou nula, os argumentos serão passados ​​diretamente para EventLog.WriteEntry () se você estiver usando recursos de mensagem localizados.
  • A ferramenta Service Trace Viewer (do WCF) é útil para visualizar gráficos de arquivos de log correlatos de atividades (mesmo se você não estiver usando o WCF). Isso pode realmente ajudar a depurar problemas complexos em que vários segmentos / atividades estão envolvidos.
  • Evite sobrecarga limpando todos os ouvintes (ou removendo o Padrão); caso contrário, o padrão passará tudo para o sistema de rastreamento (e incorrerá em todas as despesas gerais de ToString ()).

Áreas que você pode querer estender (se necessário):

  • Ouvinte de rastreamento de banco de dados
  • Ouvinte de rastreamento do console colorido
  • Ouvintes de rastreamento MSMQ / Email / WMI (se necessário)
  • Implemente um FileSystemWatcher para chamar Trace.Refresh para alterações dinâmicas na configuração

Outras Recomendações:

Use IDs de eventos estruturados e mantenha uma lista de referência (por exemplo, documente-os em uma enumeração).

Ter IDs de eventos exclusivos para cada evento (significativo) em seu sistema é muito útil para correlacionar e encontrar problemas específicos. É fácil rastrear o código específico que registra / usa os IDs de evento e pode facilitar a orientação de erros comuns, por exemplo, erro 5178 significa que a cadeia de conexão do banco de dados está incorreta etc.

Os IDs de evento devem seguir algum tipo de estrutura (semelhante à Teoria dos Códigos de Resposta usada no email e HTTP), que permite tratá-los por categoria sem conhecer códigos específicos.

por exemplo, o primeiro dígito pode detalhar a classe geral: 1xxx pode ser usado para operações 'Iniciar', 2xxx para comportamento normal, 3xxx para rastreamento de atividades, 4xxx para avisos, 5xxx para erros, 8xxx para operações 'Stop', 9xxx para erros fatais, etc.

O segundo dígito pode detalhar a área, por exemplo, 21xx para informações do banco de dados (41xx para avisos do banco de dados, 51xx para erros do banco de dados), 22xx para o modo de cálculo (42xx para avisos de cálculo, etc.), 23xx para outro módulo, etc.

Os IDs de eventos estruturados atribuídos também permitem que você os use em filtros.

P: Se você usa o rastreamento, utiliza Trace.Correlation.StartLogicalOperation?

R: Trace.CorrelationManager é muito útil para correlacionar instruções de log em qualquer tipo de ambiente multithread (que é praticamente qualquer coisa hoje em dia).

Você precisa pelo menos definir o ActivityId uma vez para cada operação lógica para correlacionar.

Iniciar / Parar e o LogicalOperationStack podem ser usados ​​para um contexto simples baseado em pilha. Para contextos mais complexos (por exemplo, operações assíncronas), o uso de TraceTransfer para o novo ActivityId (antes de alterá-lo) permite a correlação.

A ferramenta Service Trace Viewer pode ser útil para exibir gráficos de atividades (mesmo se você não estiver usando o WCF).

P: Você escreve esse código manualmente ou usa alguma forma de programação orientada a aspectos para fazer isso? Gostaria de compartilhar um trecho de código?

R: Você pode criar uma classe de escopo, por exemplo, LogicalOperationScope, que (a) configura o contexto quando criado e (b) redefine o contexto quando descartado.

Isso permite que você escreva códigos como os seguintes para quebrar automaticamente as operações:

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

Na criação, o escopo pode primeiro definir ActivityId, se necessário, chame StartLogicalOperation e, em seguida, registre uma mensagem TraceEventType.Start. Em Dispose, ele pode registrar uma mensagem de parada e, em seguida, chamar StopLogicalOperation.

P: Você fornece alguma forma de granularidade sobre fontes de rastreamento? Por exemplo, o WPF TraceSources permite que você os configure em vários níveis.

R: Sim, várias fontes de rastreamento são úteis / importantes à medida que os sistemas aumentam.

Embora você provavelmente deseje registrar consistentemente todas as mensagens de Aviso e acima, ou Todas as informações e acima, para qualquer sistema de tamanho razoável, o volume de registro de rastreamento de atividades (iniciar, parar etc.) e verboso simplesmente se torna excessivo.

Em vez de ter apenas um comutador que ativa ou desativa tudo, é útil poder ativar essas informações para uma seção do sistema por vez.

Dessa forma, você pode localizar problemas significativos a partir do log normalmente (todos os avisos, erros, etc.) e, em seguida, "aumentar o zoom" nas seções desejadas e configurá-las para os níveis de Rastreamento de Atividade ou mesmo de Depuração.

O número de fontes de rastreamento necessárias depende do seu aplicativo, por exemplo, você pode desejar uma fonte de rastreamento por montagem ou por seção principal do seu aplicativo.

Se você precisar de um controle ainda mais preciso, adicione switches booleanos individuais para ativar / desativar o rastreamento de alto volume específico, por exemplo, descargas brutas de mensagens. (Ou uma fonte de rastreamento separada pode ser usada, semelhante ao WCF / WPF).

Você também pode considerar fontes de rastreio separadas para o rastreamento de atividades versus o registro geral (outros), pois pode facilitar um pouco a configuração dos filtros exatamente como você deseja.

Observe que as mensagens ainda podem ser correlacionadas via ActivityId, mesmo que fontes diferentes sejam usadas, portanto, use quantas você precisar.


Ouvintes

P: Quais saídas de log você usa?

Isso pode depender do tipo de aplicativo que você está escrevendo e do que está sendo registrado. Geralmente coisas diferentes acontecem em lugares diferentes (ou seja, várias saídas).

Geralmente, classifico as saídas em três grupos:

(1) Eventos - log de eventos do Windows (e arquivos de rastreamento)

Por exemplo, se estiver escrevendo um servidor / serviço, a melhor prática no Windows é usar o Log de Eventos do Windows (você não tem uma interface do usuário para reportar).

Nesse caso, todos os eventos Fatais, Erro, Aviso e Informações (em nível de serviço) devem ir para o Log de Eventos do Windows. O nível de informação deve ser reservado para esse tipo de evento de alto nível, aquele que você deseja exibir no log de eventos, por exemplo, "Serviço iniciado", "Serviço interrompido", "Conectado ao Xyz" e talvez até "Programação iniciada" , "Usuário conectado", etc.

Em alguns casos, convém tornar a gravação no log de eventos uma parte interna do seu aplicativo e não através do sistema de rastreamento (por exemplo, gravar diretamente as entradas do log de eventos). Isso significa que não pode ser desativado acidentalmente. (Observe que você também deseja observar o mesmo evento em seu sistema de rastreio para poder correlacionar).

Por outro lado, um aplicativo GUI do Windows geralmente os informava ao usuário (embora eles também possam fazer logon no Log de Eventos do Windows).

Os eventos também podem ter contadores de desempenho relacionados (por exemplo, número de erros / s) e pode ser importante coordenar qualquer gravação direta no log de eventos, contadores de desempenho, gravação no sistema de rastreamento e relatórios ao usuário para que eles ocorram em o mesmo tempo.

ou seja, se um usuário vir uma mensagem de erro em um determinado momento, você poderá encontrar a mesma mensagem de erro no log de eventos do Windows e, em seguida, o mesmo evento com o mesmo registro de data e hora no log de rastreamento (junto com outros detalhes de rastreamento).

(2) Atividades - arquivos de log de aplicativo ou tabela de banco de dados (e arquivos de rastreio)

Essa é a atividade regular que um sistema realiza, por exemplo, página da web veiculada, negociação na bolsa de valores, pedido efetuado, cálculo realizado etc.

O rastreamento de atividades (iniciar, parar etc.) é útil aqui (na granualidade correta).

Além disso, é muito comum usar um log de aplicativo específico (às vezes chamado de log de auditoria). Geralmente, esta é uma tabela de banco de dados ou um arquivo de log do aplicativo e contém dados estruturados (ou seja, um conjunto de campos).

As coisas podem ficar um pouco desfocadas aqui, dependendo da sua aplicação. Um bom exemplo pode ser um servidor da web que grava cada solicitação em um log da web; exemplos semelhantes podem ser um sistema de mensagens ou sistema de cálculo em que cada operação é registrada juntamente com detalhes específicos do aplicativo.

Um exemplo não tão bom é o mercado de ações ou um sistema de pedidos de vendas. Nesses sistemas, você provavelmente já está registrando a atividade, pois ela possui um importante valor comercial, no entanto, o principal de correlacioná-la com outras ações ainda é importante.

Além de logs de aplicativos personalizados, as atividades também costumam ter contadores de desempenho relacionados, por exemplo, número de transações por segundo.

Em geral, você deve coordenar o log de atividades em diferentes sistemas, ou seja, gravar no log do aplicativo ao mesmo tempo em que aumenta o contador de desempenho e registra no sistema de rastreamento. Se você fizer tudo ao mesmo tempo (ou logo após o outro no código), os problemas de depuração serão mais fáceis (do que se todos ocorrerem em horários / locais diferentes no código).

(3) Rastreio de depuração - arquivo de texto ou talvez XML ou banco de dados.

São informações no nível detalhado e inferior (por exemplo, comutadores booleanos personalizados para ativar / desativar despejos de dados brutos). Isso fornece as entranhas ou detalhes do que um sistema está fazendo em um nível de subatividade.

Este é o nível que você deseja ativar / desativar para seções individuais do seu aplicativo (daí as várias fontes). Você não quer essas coisas bagunçando o Log de Eventos do Windows. Às vezes, um banco de dados é usado, mas é mais provável que estejam rolando arquivos de log que são eliminados após um certo tempo.

Uma grande diferença entre essas informações e um arquivo de log de aplicativos é que elas não são estruturadas. Enquanto um log de aplicativo pode ter campos para, de, quantidade, etc., os rastreamentos de depuração detalhados podem ser o que um programador colocar, por exemplo, "verificando valores X = {valor}, Y = falso" ou comentários / marcadores aleatórios como " Feito isso, tentando novamente ".

Uma prática importante é garantir que as coisas inseridas nos arquivos de log do aplicativo ou no Log de Eventos do Windows também sejam registradas no sistema de rastreamento com os mesmos detalhes (por exemplo, registro de data e hora). Isso permite correlacionar os diferentes logs ao investigar.

Se você planeja usar um visualizador de log específico porque possui uma correlação complexa, por exemplo, o Service Trace Viewer, precisará usar um formato apropriado, por exemplo, XML. Caso contrário, um arquivo de texto simples geralmente é bom o suficiente - nos níveis inferiores, as informações são amplamente desestruturadas, portanto, você pode encontrar despejos de matrizes, despejos de pilha, etc. Desde que você possa se correlacionar com logs mais estruturados em níveis mais altos, as coisas devem fique bem.

P: Se estiver usando arquivos, você usa logs contínuos ou apenas um único arquivo? Como você disponibiliza os logs para as pessoas consumirem?

R: Para arquivos, geralmente você deseja rolar arquivos de log do ponto de vista de capacidade de gerenciamento (com System.Diagnostics, basta usar VisualBasic.Logging.FileLogTraceListener).

A disponibilidade novamente depende do sistema. Se você está falando apenas de arquivos e, em seguida, de um servidor / serviço, os arquivos contínuos podem ser acessados ​​apenas quando necessário. (Log de eventos do Windows ou Logs de aplicativos de banco de dados teriam seus próprios mecanismos de acesso).

Se você não tiver acesso fácil ao sistema de arquivos, o rastreamento de depuração em um banco de dados poderá ser mais fácil. [ie implementar um banco de dados TraceListener].

Uma solução interessante que vi para um aplicativo da GUI do Windows foi que ele registrou informações de rastreamento muito detalhadas em um "gravador de vôo" enquanto estava em execução e, em seguida, quando você o desligava se não houvesse problemas, simplesmente excluía o arquivo.

Se, no entanto, travar ou encontrar um problema, o arquivo não será excluído. Se ele detectar o erro, ou na próxima vez em que ele for executado, ele notará o arquivo e poderá executar uma ação, por exemplo, compactá-lo (por exemplo, 7zip) e enviá-lo por e-mail ou disponibilizar.

Atualmente, muitos sistemas incorporam relatórios automatizados de falhas a um servidor central (após verificação com os usuários, por exemplo, por motivos de privacidade).


Visualizando

P: Quais ferramentas você usa para visualizar os logs?

R: Se você tiver vários logs por diferentes motivos, usará vários visualizadores.

O Notepad / vi / Notepad ++ ou qualquer outro editor de texto é o básico para logs de texto sem formatação.

Se você possui operações complexas, por exemplo, atividades com transferências, obviamente usaria uma ferramenta especializada como o Service Trace Viewer. (Mas se você não precisar, um editor de texto é mais fácil).

Como geralmente registro informações de alto nível no Log de Eventos do Windows, ele fornece uma maneira rápida de obter uma visão geral, de maneira estruturada (procure os ícones de aviso / erro bastante). Você só precisa começar a procurar por arquivos de texto se não houver o suficiente no log, embora pelo menos o log lhe dê um ponto de partida. (Nesse ponto, garantir que seus logs tenham entradas coordenadas se torna útil).

Geralmente, o Registro de Eventos do Windows também disponibiliza esses eventos significativos para ferramentas de monitoramento como MOM ou OpenView.

Outras --

Se você fizer login em um banco de dados, pode ser fácil filtrar e classificar informações (por exemplo, ampliar um ID de atividade específico. (Com arquivos de texto, você pode usar o Grep / PowerShell ou similar para filtrar o GUID particiular que você deseja)

MS Excel (ou outro programa de planilha). Isso pode ser útil para analisar informações estruturadas ou semiestruturadas, se você puder importá-las com os delimitadores certos, para que valores diferentes entrem em colunas diferentes.

Ao executar um serviço em depuração / teste, eu geralmente o hospedo em um aplicativo de console por simplicidade. Acho um logger de console colorido útil (por exemplo, vermelho por erros, amarelo por avisos etc.). Você precisa implementar um ouvinte de rastreamento personalizado.

Observe que a estrutura não inclui um registrador de console colorido ou um registrador de banco de dados; portanto, neste momento, você precisará escrevê-los se precisar deles (não é muito difícil).

Realmente me incomoda que várias estruturas (log4net, EntLib, etc) tenham perdido tempo reinventando a roda e reimplementando o log básico, a filtragem e o log em arquivos de texto, o log de eventos do Windows e arquivos XML, cada um por conta própria maneira diferente (as instruções de log são diferentes em cada uma); cada um implementou sua própria versão de, por exemplo, um criador de logs de banco de dados, quando a maioria já existia e tudo o que era necessário era mais alguns ouvintes de rastreamento do System.Diagnostics. Fale sobre um grande desperdício de esforços duplicados.

P: Se você está criando uma solução ASP.NET, também usa o Monitoramento de integridade do ASP.NET? Você inclui saída de rastreio nos eventos do monitor de integridade? E o Trace.axd?

Essas coisas podem ser ativadas / desativadas conforme necessário. Acho o Trace.axd bastante útil para depurar como um servidor responde a certas coisas, mas geralmente não é útil em um ambiente muito usado ou para rastreamento a longo prazo.

P: E os contadores de desempenho personalizados?

Para um aplicativo profissional, especialmente um servidor / serviço, espero vê-lo totalmente instrumentado com os contadores do Performance Monitor e com o log no Windows Event Log. Essas são as ferramentas padrão do Windows e devem ser usadas.

Você precisa certificar-se de incluir instaladores para os contadores de desempenho e logs de eventos que você usa; estes devem ser criados no momento da instalação (ao instalar como administrador). Quando seu aplicativo está sendo executado normalmente, ele não precisa ter privilégios de administração (e, portanto, não poderá criar logs ausentes).

Esse é um bom motivo para praticar o desenvolvimento como não administrador (tenha uma conta de administrador separada para quando você precisar instalar serviços, etc.). Se gravar no log de eventos, o .NET criará automaticamente um log ausente na primeira vez que você gravar nele; se você se tornar um não administrador, perceberá isso cedo e evitará uma surpresa desagradável quando um cliente instalar o sistema e não poderá usá-lo porque não está executando como administrador.

Sly Gryphon
fonte
FYI: Encontrei um problema em que o rastreamento da Microsoft para um arquivo falha. Se você tiver vários processos (ou threads) gravando no mesmo arquivo e eles colidirem, você receberá um erro de bloqueio de acesso exclusivo do sistema de arquivos no arquivo de log.
Jay em Jay
1
A infraestrutura System.Diagnostics é segura para threads; o comportamento padrão é o bloqueio da estrutura, no entanto, você pode substituir TraceListener.IsThreadSafe se você fornecer seu próprio bloqueio. Consulte msdn.microsoft.com/en-us/library/… . Para vários processos, você normalmente gravaria em arquivos separados, mas observe que o Service Trace Viewer pode carregar vários arquivos de rastreamento (por exemplo, de várias máquinas) e correlacioná-los via ActivityId.
Sly Gryphon
1
Pode ser que você possa sugerir como usar o TraceEvent () para registrar exceções?
Dmitriy Sosunov
1
Não é uma das principais desvantagens System.Diagnostics.Tracedisso decorada, o [Conditional("TRACE")]que o torna inutilizável em ambientes de produção, onde você raramente tem código compilado com o TRACEsinalizador?
Asbjørn Ulsberg
2
@asbjornu A configuração de compilação do Release padrão no Visual Studio definiu TRACE (é DEBUG desativado para compilações do Release); se você estiver construindo a partir da linha de comando, precisará ativá-la.
Sly Gryphon
40

Eu tenho que ingressar no coro recomendando o log4net, no meu caso, vindo de um ponto de vista de flexibilidade da plataforma (desktop .Net / Compact Framework, 32/64 bits).

No entanto, envolvê-lo em uma API de marca própria é um grande antipadrão . log4net.ILoggerjá é a contrapartida .Net da API do wrapper de logging do Commons , portanto, o acoplamento já é minimizado para você e, como também é uma biblioteca Apache, isso geralmente não é uma preocupação, porque você não abre mão de nenhum controle: bifurque-o se desejar devo.

A maioria das bibliotecas de invólucros domésticos que eu já vi também cometem uma ou mais litanias de falhas:

  1. O uso de um criador de log singleton global (ou equivalente a um ponto de entrada estático) que perde a resolução fina do padrão recomendado de logger por classe para nenhum outro ganho de seletividade.
  2. Falha ao expor o Exceptionargumento opcional , levando a vários problemas:
    • Isso torna ainda mais difícil manter uma política de registro de exceções, para que nada seja feito de maneira consistente com as exceções.
    • Mesmo com uma política consistente, a formatação da exceção em uma string perde os dados prematuramente. Eu escrevi um ILayoutdecorador personalizado que executa uma pesquisa detalhada em uma exceção para determinar a cadeia de eventos.
  3. Falha ao expor as propriedadesIsLevelEnabled , o que descarta a capacidade de ignorar o código de formatação quando áreas ou níveis de log estão desativados.
Jeffrey Hantin
fonte
1
Fui encarregado de refatorar um invólucro interno (horrível) em torno do log4j para algo um pouco menos horrível (ainda é muito ruim, mas isso é resultado da manutenção dos requisitos que me foram dados no log4j). Tentei eliminar o ponto de entrada estático global, mas fui abatido. Eu realmente não entendi. Em nossa configuração, o log4j é tão extenso e distorcido que está apenas sendo usado como despachante de eventos; estamos usando apenas porque alguém perguntou "como podemos usar o log4j para isso?" Use log4whatever diretamente ou escreva sua própria estrutura. O caminho do meio é doloroso.
23611 Adam Jaskiewicz
25
Discordo da sua recomendação de não quebrar o log4net. O agrupamento com uma API fina de modelo de provedor permite que os usuários de suas bibliotecas de classes conectem sua estrutura de log favorita. YMMV, é claro, mas descrevê-lo como um "grande anti-padrão" é um pouco dogmático. Além disso, o fato de existirem bibliotecas de invólucros com "uma ladainha de falhas" não é um bom argumento contra um invólucro bem escrito.
21410 Joe
1
Chamar algo de antipadrão não significa que é sempre 100% uma péssima idéia - apenas cria uma tendência de pintar a si mesmo em um canto, se você não tomar cuidado. Além disso, o ILog / LogManager é, por si só, uma mini-biblioteca de empacotador bem escrita na imagem do log comum, empacotada no conjunto log4net, mas não há razão para que não possa ser extraída e transformada em um log comum apropriado para CLR.
Jeffrey Hantin
18

Geralmente não desenvolvo no asp.net, no entanto, quando se trata de criadores de logs, acho que muitas das melhores práticas são universais. Aqui estão alguns dos meus pensamentos aleatórios sobre o registro que aprendi ao longo dos anos:

Frameworks

  • Use uma estrutura de abstração do criador de logs - como slf4j (ou role a sua própria), para dissociar a implementação do criador de logs da sua API. Eu já vi várias estruturas de logger irem e virem e é melhor você poder adotar uma nova, sem muito aborrecimento.
  • Tente encontrar uma estrutura que suporte uma variedade de formatos de saída.
  • Tente encontrar uma estrutura que suporte plugins / filtros personalizados.
  • Use uma estrutura que possa ser configurada por arquivos externos, para que seus clientes / consumidores possam ajustar facilmente a saída do log para que possa ser lida pelos aplicativos comerciais de gerenciamento de logs com facilidade.
  • Certifique-se de não exagerar nos níveis de log personalizados, caso contrário, talvez não seja possível mudar para estruturas de log diferentes.

Saída do registrador

  • Tente evitar logs no estilo XML / RSS para log que possam encontrar falhas catastróficas. Isso é importante porque se o interruptor de energia for desligado sem que o seu logger escreva a </xxx>etiqueta de fechamento , seu log será quebrado.
  • Threads de log. Caso contrário, pode ser muito difícil rastrear o fluxo do seu programa.
  • Se você precisar internacionalizar seus logs, convém que um desenvolvedor faça logon apenas em inglês (ou no seu idioma preferido).
  • Às vezes, ter a opção de inserir instruções de log em consultas SQL pode ser um salva-vidas em situações de depuração. Tal como:
    - Invocando classe: com.foocorp.foopackage.FooClass: 9021
    SELECT * FROM foo;
  • Você deseja log em nível de classe. Normalmente, você também não deseja instâncias estáticas de registradores - não vale a micro-otimização.
  • Às vezes, marcar e categorizar exceções registradas é útil porque nem todas as exceções são criadas da mesma forma. Portanto, é útil conhecer um subconjunto de exceções importantes antecipadamente, se você tiver um monitor de log que precise enviar notificações sobre estados críticos.
  • Os filtros de duplicação salvarão sua visão e disco rígido. Deseja realmente ver a mesma instrução de log repetida 10 ^ 10000000 vezes? Não seria melhor apenas receber uma mensagem como: This is my logging statement - Repeated 100 times

Veja também esta minha pergunta .

Elijah
fonte
5
filtros de duplicação são uma grande idéia
Paul Stovell
Eu costumava concordar com o problema de marca quebrada, mas a maioria dos bons gravadores de XML não usa XML completo de qualquer maneira (ou seja, nenhum elemento raiz) para que possam fazer log sem carregar o XML DOM. no caso raro ocorrer um problema a partir de uma entrada parcialmente escrito, você pode corrigi-lo manualmente
Paul Stovell
Eu venho indo e voltando no log XML por anos. Agora, parece excessivo para mim. Se eu precisasse de um feed RSS do status de um aplicativo, acho que ele seria melhor implementado com um utilitário de monitoramento de log.
237 Elijah
Eu concordo com o RSS. Estou pensando mais nas ferramentas de visualização que permitem entender melhor a entrada. com arquivos de texto, você geralmente deseja manter uma entrada em uma linha; mas às vezes você deseja incluir rastreamentos de pilha ou objetos serializados. É aí que um log XML (como o usado pelo WCF) vem a calhar
Paul Stovell
+1 para mencionar a instrumentação de consultas SQL. Isso é realmente muito útil para correlação de rastreamentos de banco de dados e rastreamentos de aplicativos. Estou fazendo isso manualmente no meu DAL, mas me pergunto que tipo de suporte de ferramenta existe para esta técnica?
Constantin
17

Não estou qualificado para comentar sobre o registro em log para .Net, já que meu pão com manteiga é Java, mas tivemos uma migração em nosso registro nos últimos 8 anos. Você pode encontrar uma analogia útil para sua pergunta.

Começamos com um criador de logs Singleton usado por todos os encadeamentos da JVM e configuramos o nível de criação de log para todo o processo. Isso resultou em enormes logs se tivéssemos que depurar até uma parte muito específica do sistema, portanto, a lição número um é segmentar seu log.

Nossa encarnação atual do criador de logs permite várias instâncias, sendo uma definida como padrão. Podemos instanciar qualquer número de loggers filhos que possuam diferentes níveis de log, mas a faceta mais útil dessa arquitetura é a capacidade de criar loggers para pacotes e classes individuais, simplesmente alterando as propriedades de log. A lição número dois é criar um sistema flexível que permita substituir seu comportamento sem alterar o código.

Estamos usando a biblioteca de logon comum do Apache agrupada em torno do Log4J.

Espero que isto ajude!

* Editar *

Depois de ler o post de Jeffrey Hantin abaixo, percebi que deveria ter notado o que nosso invólucro de registro interno se tornou. Agora é essencialmente uma fábrica e é estritamente usado para obter um agente de log usando o arquivo de propriedades correto (que por motivos legados não foi movido para a posição padrão). Como você pode especificar o arquivo de configuração de log na linha de comando agora, eu suspeito que ele se tornará ainda mais enxuto e, se você estiver iniciando um novo aplicativo, eu definitivamente concordaria com a declaração dele de que você não deveria nem se dar ao trabalho de quebrar o logger.

Steve Moyer
fonte
obrigado pela resposta. você cria os loggers filhos manualmente no código (ou seja, eles são codificados) ou através de algum tipo de coisa automática / implícita?
Paul Stovell 23/02/09
Não ... se adicionarmos uma configuração de log aos arquivos logging.properties para um pacote ou classe, eles serão registrados de acordo com essa configuração, mas qualquer pacote ou classe não especificamente configurada será registrada nos níveis padrão.
23720 Steve Moyer
9

Usamos o Log4Net no trabalho como o provedor de log, com um wrapper singleton para a instância de log (embora o singleton esteja em revisão, questionando se é uma boa ideia ou não).

Nós o escolhemos pelos seguintes motivos:

  • Configuração / reconfiguração simples em vários ambientes
  • Bom número de anexadores pré-construídos
  • Um dos CMS que usamos já o incorporou
  • Bom número de níveis e configurações de log em torno deles

Devo mencionar, isso está falando do ponto de vista de desenvolvimento do ASP.NET

Eu posso ver alguns méritos no uso do Trace que está na estrutura .NET, mas não sou totalmente vendido, principalmente porque os componentes com os quais trabalho realmente não fazem nenhuma chamada do Trace. A única coisa que costumo usar é System.Net.Maildo que posso dizer.

Portanto, temos uma biblioteca que agrupa o log4net e, dentro do nosso código, precisamos de coisas como esta:

Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());

try {
  var i = int.Parse("Hello World");
} catch(FormatException, ex) {
  Logger.Instance.Error(ex);
}

Dentro dos métodos, fazemos uma verificação para verificar se o nível de log está ativado, para que você não tenha chamadas redundantes para a API log4net (por isso, se a Depuração não estiver ativada, as instruções de depuração serão ignoradas), mas quando tiver algum tempo Vou atualizá-lo para expô-los, para que você possa fazer as verificações você mesmo. Isso impedirá que avaliações sejam realizadas quando não deveriam, por exemplo:

Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

Isso se tornará:

if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);

(Economize um pouco de tempo de execução)

Por padrão, registramos em dois locais:

  1. Sistema de arquivos do site (em uma extensão de arquivo não veiculada)
  2. Envio de e-mail para Error & Fatal

Os arquivos são executados como rolagem de cada dia ou 10 MB (IIRC). Não usamos o EventLog, pois ele pode exigir maior segurança do que geralmente queremos oferecer a um site.

Acho que o Bloco de notas funciona muito bem para ler logs.

Aaron Powell
fonte
As estruturas de log são um dos poucos casos em que o singleton não é um uso indevido.
mmcdole 23/02/09
Pode ser que você queira fornecer um contexto em torno do seu criador de logs. Mas ajuda a lidar com a concorrência
Aaron Powell
7
Eu definitivamente arrancaria o singleton. Você certamente pode ter um único instância que é transmitida (de preferência no contêiner IOC / DI). Também gostaria de tentar mover o registo para um interceptor ....
yfeldblum
2
Também não é fã da instância única. Eu prefiro dar a cada classe um logger de nome exclusivo, portanto, é muito fácil aumentar o log para cima ou para baixo em uma base por módulo.
Jeffrey Hantin 25/10/10
8

Quais estruturas você usa?

Usamos uma mistura do bloco do aplicativo de log e um auxiliar de log personalizado que funciona em torno dos bits da estrutura .Net. O LAB está configurado para gerar arquivos de log razoavelmente extensos, incluindo arquivos de rastreio geral separados para entrada / saída do método de serviço e arquivos de erro específicos para problemas inesperados. A configuração inclui data / hora, encadeamento, ID etc. para assistência de depuração, bem como detalhes e exceções completos da exceção (no caso de uma exceção inesperada).

O auxiliar de log personalizado usa o Trace.Correlation e é particularmente útil no contexto de log no WF. Por exemplo, temos uma máquina de estado que chama uma série de fluxos de trabalho seqüenciais. Em cada uma dessas atividades de chamada, registramos o início (usando StartLogicalOperation) e, no final, paramos a operação lógica com um manipulador de eventos de retorno gerérico.

Isso provou ser útil algumas vezes ao tentar depurar falhas em sequências de negócios complexas, pois permite determinar coisas como decisões de filial If / Else etc. mais rapidamente com base na sequência de execução da atividade.

Quais saídas de log você usa?

Usamos arquivos de texto e arquivos XML. Os arquivos de texto são configurados através do bloco do aplicativo, mas também temos saídas XML do nosso serviço WF. Isso nos permite capturar os eventos de tempo de execução (persistência etc.), bem como exceções genéricas de tipo de negócios. Os arquivos de texto estão rolando logs que são rolados por dia e tamanho (acredito que o tamanho total de 1 MB seja um ponto de rolagem).

Quais ferramentas você usa para visualizar os logs?

Estamos usando o Notepad e o WCF Service Trace Viewer, dependendo do grupo de saída que estamos analisando. O WCF Service Trace Viewer é realmente muito útil se você tiver configurado sua saída corretamente e puder facilitar a leitura da saída. Dito isto, se eu souber aproximadamente onde está o erro - apenas ler um arquivo de texto bem anotado também é bom.

Os logs são enviados para um único diretório que é então dividido em subdiretórios com base no serviço de origem. O diretório raiz é exposto por meio de um site cujo acesso é controlado por um grupo de usuários de suporte. Isso nos permite dar uma olhada nos logs de produção sem precisar fazer solicitações e passar por longos processos de burocracia para dados de produção.

Steve Godbold
fonte
6

Como autores da ferramenta, é claro que usamos o SmartInspect para registrar e rastrear aplicativos .NET. Geralmente, usamos o protocolo de pipe nomeado para log ativo e arquivos de log binários (criptografados) para logs do usuário final. Usamos o SmartInspect Console como visualizador e ferramenta de monitoramento.

Na verdade, existem algumas estruturas e ferramentas de log para .NET por aí. Há uma visão geral e comparação das diferentes ferramentas no DotNetLogging.com .

Dennis G.
fonte
5

Há muitas ótimas recomendações nas respostas.

Uma prática recomendada geral é considerar quem estará lendo o log. No meu caso, será um administrador no site do cliente. Então, eu registro mensagens que lhes dão algo em que elas podem agir. Por exemplo, "Não é possível inicializar o aplicativo. Isso geralmente é causado por ......"

Matthew Sposato
fonte
1

Usamos o log4net em nossos aplicativos da web.

Sua capacidade de personalizar o log em tempo de execução alterando o arquivo de configuração XML é muito útil quando um aplicativo está com defeito em tempo de execução e você precisa ver mais informações.

Também permite que você direcione classes ou atributos específicos nos quais fazer logon. Isso é muito útil quando você tem uma ideia de onde o erro está ocorrendo. Um exemplo clássico é o NHibernate, no qual você deseja ver apenas o SQL indo para o banco de dados.

Editar:

Escrevemos todos os eventos em um banco de dados e no sistema Trace. O log de eventos que usamos para erros ou exceções. Registramos a maioria dos eventos em um banco de dados para que possamos criar relatórios personalizados e permitir que os usuários visualizem o log, se quiserem, diretamente do aplicativo.

Jeffrey Cameron
fonte
Você pode fornecer mais detalhes sobre como usá-lo? Você faz logon em um arquivo ou no log de eventos? É um arquivo de log contínuo? O que você faz para protegê-lo ou fazer backup? Estou interessado no uso na vida real.
Paul Stovell 23/02/09
1

No que diz respeito ao log orientado a aspectos, fui recomendado o PostSharp em outra questão SO -

Log Orientado a Aspectos com Unity \ T4 \ qualquer outra coisa

Vale a pena visitar o link fornecido na resposta se você estiver avaliando estruturas de log.

Unmesh Kondolikar
fonte