Outro requisito não funcional das minhas novas aplicações, agora em .Net, que eu tive que aprender como implementar foi uma API de log.
E como no post sobre Spring.NET, fui a procura de uma velha conhecida API de log conhecida dos tempos de Java, a Log4J que na sua versão para .Net chamasse Log4Net.
Então criei um projeto do tipo Console Application e com o Manage NuGet Packages adicionei o Log4Net 1.2.11 ao projeto.
A primeira coisa é configurar o App.config.
Nele temos, entre outras coisas, que configurar a forma de saída desse log (se em banco de dados, e-mail, arquivo, etc) e o formato (que informações sobre o erro gravar).
Eu configurei o Log4Net para gravar em disco o arquivo de log e guardar as informações de:
Data da ocorrência;
Thead;
Nível da ocorrência;
Onde ocorreu a ocorrência;
Mensagem da ocorrência.
Esse é o arquivo de configuração da minha aplicação (App.config):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="C:\\LogginWithLog4net\\log.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
</configuration>
Então criei uma classe para lançar uma exceção qualquer além de ter duas informações também sendo gravadas no log. A minha classe main do projeto (Program.cs) ficou assim:
using System;
using log4net;
using log4net.Config;
using System.Reflection;
namespace LogginWithLog4net
{
class Program
{
private static readonly ILog log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
static void Main(string[] args)
{
XmlConfigurator.Configure(
new System.IO.FileInfo("C:\\LogginWithLog4net\\App.config"));
log.Info("Starting the process.");
try
{
throw new Exception("Fatal error");
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
log.Error("Exception: " + e.Message);
log.Error("Stack trace: " + e.StackTrace);
}
log.Info("Process terminated.");
Console.ReadKey();
}
}
}
Em primeiro lugar eu recupero uma instância do log e atribuo ao campo estático log da classe Program:
private static readonly ILog log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
Depois disto feito, dentro do main eu tenho que informar a instância do log onde ele deve buscar as definições e configurações para funcionar como eu quero que ele funcione. Então tenho uma classe XmlConfigurator recebendo o arquivo App.config:
XmlConfigurator.Configure(
new System.IO.FileInfo("C:\\LogginWithLog4net\\App.config"));
Feito isso estamos prontos para logar qualquer coisa.
Estou gravando uma linha de informação (nível INFO) no log: “Starting the process.” e depois lançando uma exceção em um bloco try/catch:
log.Info("Starting the process.");
try
{
throw new Exception("Fatal error");
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
log.Error("Exception: " + e.Message);
log.Error("Stack trace: " + e.StackTrace);
}
Essa exceção está sendo tratada no catch onde eu estou mostrando no console da aplicação a mensagem do erro recuperada da exceção lançada e logo depois eu gravo essa mesma informação no log junto com o stack trace completo da exceção.
A saída no arquivo de log ficou:
2013-09-02 11:37:54,890 [10] INFO LogginWithLog4net.Program - Starting the process.
2013-09-02 11:37:54,937 [10] ERROR LogginWithLog4net.Program - Exception: Fatal error
2013-09-02 11:37:54,937 [10] ERROR LogginWithLog4net.Program -
Stack trace: em LogginWithLog4net.Program.Main(String[] args)
na C:\LogginWithLog4net\Program.cs:linha 20
2013-09-02 11:37:54,953 [10] INFO LogginWithLog4net.Program - Process terminated.
E explorando as outras formas de gravar os logs ainda coloquei para gravar em banco de dados essas mesmas informações.
O nível de log está configurado para DEBUG, ou seja, vai gravar tudo. Claro que na hora de ir para produção o projeto deve filtrar por um nível mais alto, como WARM, que só exibirá o que estiver além de INFO. Ou seja, o que for warm do framework .Net e das demais libraries inclusas no projeto e tudo que for erro que acontecer na execução do projeto.
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário