ASP.NET - Geração e tratamento de log de erros
Este artigo mostra como você pode gerar um arquivo de log de erros em uma aplicação ASP.NET. Vai ser um abordagem bem simples onde os erros serão gravados em um arquivo texto chamado logErro.txt.
Para que serve um arquivo de log ? Serve para você auditar o seu sistema em produção e acompanhar o seu comportamento monitorando as ocorrências que porventura estejam afetando o desempenho ou causando um problema.
Irei criar um novo web site usando o Visual Web Developer Express onde a página Default.aspx irá conter um controle dropdownlist e um controle GridView .
O controle DropDownlist será preenchido com os dados da tabela Categories do banco de dados Northwind.mdf e o GridView irá exibir os dados da tabela Products e Categories relacionados com a categoria selecionada no Dropdownlist.
Para criar esta aplicação podemos usar os assistentes de configuração sem ter que digitar nenhuma linha de código mas não vou usar os assistentes e vou fazer tudo via programação. Além disso vou criar um web site AJAX usando o componente UpdatePanel para evitar o postback da página inteira.
Inicie o Visual Web Developer Express e crie um novo web site chamado cmdFiltroNet a partir do menu File -> New Web Site selecionando na janela New Web Site o template ASP.NET AJAX - Enabled Web Site. (Você deve instalar o pacote a última versão do Microsoft ASP.NET AJAX instalada e configurada.( http://ajax.asp.net/)
Selecionando a página Default.aspx , no modo Design, você deverá ver o controle ScriptManager exibido na página.
Inclua agora , a partir da guia AJAX Extensions da ToolBox, o controle UpdatePanel na página;
A seguir inclua , no interior do componente UpdatePanel, um controle DropdownList e um controle GridView , e, fora do UpdatePanel um controle Label;
Como não vou usar nenhum assistente para configurar a conexão com o banco de dados nem preencher os controles ou selecionar os dados para exibição, e assim, teremos que definir primeiro a string de conexão com o banco de dados Northwind.mdf no arquivo web.config.
Você pode usar o assistente de configuração e definir uma fonte de dados para o controle Dropdownlist salvando a string de conexão no web.config e em seguida remover o componente de dados da página ou pode informar a string diretamente no arquivo web.config conforme o código abaixo:
<connectionStrings> <add name="NORTHWNDConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\NORTHWND.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True" providerName="System.Data.SqlClient"/> </connectionStrings> |
Em seguida devemos declarar os seguintes namespaces no arquivo code-behind :
Imports
System.IO
Imports
System.Data.sqlclient
Imports
System.Data
Preenchendo o DropDownList com os dados da tabela Categories
Vamos preencher o controle Dropdownlist com os dados da tabela Categories. Isto deve ser feito quando a página for carregada por isso no evento Load da página inclua o seguinte código:
Protected Sub
Page_Load(ByVal
sender As Object, ByVal
e As System.EventArgs) Handles Me.Load If Page.IsPostBack = False Then
End If End Sub |
No evento DropDownList1_SelectedIndexChanged vamos colocar o código que irá exibir os dados no GridView de acordo com a seleção feita no dropdownlist:
Protected Sub
DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged ' configura a string de conexão a partir do arquivo web.config ' abre a conexão Dim strConnectionString As String = ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString Dim conexaoBD As New SqlConnection(strConnectionString) Try
finally
End Try |
Executando a página no servidor ASP.NET teremos o seguinte resultado:
Para provocar um erro vou alterar o nome do parâmetro CategoryID removendo a letra I , desta forma ao executar iremos o obter a seguinte mensagem de erro:
Dê uma olhada na janela Solution Explorer , clicando no botão Refresh e perceba que o arquivo logErro.txt foi criado. Se visualizarmos o seu conteúdo iremos ver exatamente a mesma mensagem de erro com indicação de data e hora.
Tudo certo ? Quase...
Na verdade podemos melhorar essa nossa implementação de forma a torná-la menos rígida e mais elegante.
A primeira coisa a fazer é criar uma pasta na estrutura do nosso projeto para armazenar o arquivo de log. Clique com o botão direito do mouse sobre o nome do projeto e selecione a opção New Folder e crie uma nova pasta chamada logErro |
Agora vamos abrir o arquivo web.config e vamos definir o local e o nome do arquivo de log que vamos criar incluindo uma chave para que possamos identificar e obter estas informações através da nossa aplicação. Abaixo temos a definição incluída entre as tags <appSettings>:
..... <configuration> <appSettings> <add key="arqLogErro" value="~/logErro/logErro.txt"/> </appSettings> <connectionStrings/> <system.web> ....... |
Outra mudança importante que vamos efetuar será criar uma classe e nela definir a criação do arquivo e a gravação das mensagens no arquivo de log . Na solução atual estamos usando código diretamente na instrução try/catch e desta forma teremos que repetir o código para cada try/catch existente na aplicação.
É Bom saber. Se você rodar a sua aplicação usando o
Visual Web Developer, a ASP.NET irá
reportar erros pela exibição de uma mensagem na página do seu Browser.
Será usada uma página com uma mensagem de erro padrão mas você pode
personalizar a página que é exibida quando um erro ocorrer. Basta
definir a tag customErrors no arquivo web.config.: Veja o
exemplo abaixo: Existem 3 valores modos que podem ser usados:
Após isso você deve definir a página paginaErro.aspx contendo a mensagem que deseja exibir para o usuário. |
Clique com o botão direito sobre o nome do projeto e selecione a opção Add New Item. Na janela templates selecione o template Class e informe o nome Log.vb. O arquivo será incluído na pasta App_Data.
Abra o arquivo Log.vb e defina as seguintes declarações no início do arquivo:
Imports
Microsoft.VisualBasic
Imports System.configuration
Imports System.io
Em seguida vamos definir dois construtores para a nossa classe:
1- O
construtor padrão sem argumentos
2- O construtor que usa dois argumentos: a mensagem de erro e o
objeto Exception
Observe que agora podemos gravar a mensagem e também o stackTrace, ou seja, a pilha de erros, fornecendo assim mais informações sobre a exceção ocorrida.
Public
Sub New() MyBase.New() End Sub Public Sub New(ByVal mensagem As String, ByVal erro As Exception) logErro(mensagem) If erro IsNot Nothing Then logErro(erro.StackTrace) End If End Sub |
Agora vamos criar o método estático (Shared) logErro(msg) que irá efetivamente criar o arquivo e gravar as mensagens de erro:
Public
Shared Sub logErro(ByVal mensagem As String) Dim caminho As String = "" Dim data As String = "" Dim contexto As HttpContext = HttpContext.Current caminho = ConfigurationManager.AppSettings("arqlogErro") data = DateTime.Now.ToString Try Dim sw As StreamWriter = File.AppendText(contexto.Server.MapPath(caminho)) sw.WriteLine(data & " :: " & mensagem) sw.Close() Catch ex As Exception MsgBox(ex.Message) End Try End Sub |
Aqui temos o código usado na solução inicial , onde incluímos a obtenção do caminho e nome do arquivo de log. Usamos a classe HttpContext para obtermos o caminho a partir do contexto , pois no servidor o caminho pode ser diferente do definido inicialmente.
Para usar a classe você deve criar uma instância da mesma e no bloco try/catch, fazer a chamada do construtor passando os argumentos, que podem ser : a mensagem e/ou objeto Exception.
....... Dim log As LogErro Try 'codigo que efetua uma ação Catch ex As Exception log = New LogErro(ex.Message, ex) End Try .................. |
Após efetuarmos alguns testes abrimos o arquivo logErro.txt onde podemos visualizar as mensagens gravadas:
09/08/2007
08:47:53 :: Arithmetic operation resulted in an overflow. 09/08/2007 08:48:13 :: Arithmetic operation resulted in an overflow. 09/08/2007 08:48:19 :: at _Default.Button1_Click(Object sender, EventArgs e) in C:\_aspn\artigos\geraLog\Default.aspx.vb:line 11 09/08/2007 08:49:44 :: Arithmetic operation resulted in an overflow. 09/08/2007 08:49:44 :: App_Web_dhz8c-i7 09/08/2007 08:49:44 :: at _Default.Button1_Click(Object sender, EventArgs e) in C:\_aspn\artigos\geraLog\Default.aspx.vb:line 11 09/08/2007 08:50:53 :: Arithmetic operation resulted in an overflow. 09/08/2007 08:51:28 :: Arithmetic operation resulted in an overflow. 09/08/2007 08:51:28 :: at _Default.Button1_Click(Object sender, EventArgs e) in C:\_aspn\artigos\geraLog\Default.aspx.vb:line 11 |
Temos ainda uma outra opção para tratar os erros inesperados em páginas ASP.NET : fazer o tratamento no evento de erro a nível de página ou no evento de erro a nível de aplicação.
Para ilustrar isso clique com o botão direito do mouse sobre o nome do projeto e selecione a opção Add New Item.
Na janela Templates selecione o template Global Configuration Class e aceite o nome padrão Global.asax
Abra o arquivo Global.asax podemos notar o evento Application_Error() destacada na figura abaixo.
Você pode incluir o seu código para tratar erros neste evento. Abaixo um exemplo de código que você pode usar neste evento para tratar erros:
<% @ Application Language="VB" %><% @ Import Namespace="System.Diagnostics"%>< script runat="server"> Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) ' Code that runs on application startup End Sub Sub Application_End(ByVal sender As Object, ByVal e As EventArgs) ' Code that runs on application shutdown End SubSub Application_Error(ByVal sender As Object, ByVal e As EventArgs) Dim descricaoErro As String = Server.GetLastError.ToString 'Cria um evento de log se ele não existir Dim eventoLog As String = "logErro" If (Not EventLog.SourceExists(eventoLog)) Then EventLog.CreateEventSource(eventoLog, eventoLog) End If' Inclui no evento Log Dim Log As New EventLog()
Log.WriteEntry(descricaoErro, EventLogEntryType.Error) End Sub Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs) ' Code that runs when a new session is started End Sub Sub Session_End(ByVal sender As Object, ByVal e As EventArgs) ' Code that runs when a session ends. ' Note: The Session_End event is raised only when the sessionstate mode ' is set to InProc in the Web.config file. If session mode is set to StateServer ' or SQLServer, the event is not raised. End Sub </ script>
|
A classe EventLog permite que você leia e escreva para o log de eventos e permite também que você crie um log, e, é isso que estamos fazendo no código acima.
É Bom saber.
Podemos ainda usar o evento Page_Error() para tratar erros a nível de página conforme exemplo de código abaixo:
|
Eu sei é apenas ASP.NET mas eu gosto ...
José Carlos Macoratti