Gerando logs em Java

Introdução

Bom, vou mostrar a importância do logs para um sistema.

Logs, nada mais são do que arquivos gerados pelo programa para que haja uma comunicação entre o sistema para o usuário. Logs são relatórios de diversos tipos, informando o que está acontecendo no sistema.

Mas, o que irei abordar aqui, são logs de erros. Os logs gerados pelo sistema são de estrema importância, pois são eles que nos ajudam a fazer a manutenção de sistema, o que ajuda a vida de um programador.

Afinal, qual conteúdo deve-se ter um log de erro?

Dentro do log de erro, deve ter três coisas fundamentais, em minha opinião, mas óbvio que dentro do log, você pode colocar as informações que você quiser, quanto mais você detalhar o log com informações do erro que ocorreu melhor fica para sua manutenção.

  1. O primeiro item, que é meio óbvio, é informar onde que ocorreu o erro, em que parte do código que houve uma ocorrência, geralmente os logs são chamados no try/catch, nos if e por aí vai.
  2. Informar a classe onde está acontecendo o erro. É fundamental informar a classe onde está o erro, pois imagine na seguinte situação: Você abre vários arquivos e chama esse método em diferentes classes. Imagine se eu só informar o erro, terei que procurar em todas as classes que tenha esse método.
  3. Informar a data. Acho que desse item não precisar fala muito. É fundamental saber quando ocorreu e a hora e dia.

Lógico que isso só é o básico, poderia informar também a linha do código que está dando o erro, o que é comum programadores colocarem na hora de gerar o log.

Como havia dito, quanto mais informações do erro melhor.

Classe main / Classe conexão com MySQL

Classe main

Vou mostrar um exemplo de como usar log, fazendo uma conexão com banco de dados MySQL.

Para começar, vou criar três classes:

  • Conexao.class Responsável por fazer a conexão com o banco de dados;
  • geraLogs.class Classe genérica que ficará responsável por gerar nossos logs;
  • main Classe principal que ficará responsável por executar nosso exemplo.

Na classe main, ficará assim:

public class main
{
public static void main(String[] args)
{
Conexao conexao = new Conexao();

}
}

Simplesmente, ficará responsável por instância nossa classe Conexao, para iniciar a conexão com o banco de dados.

Vamos para a próxima classe, Conexão.

Classe conexão com MySQL

Como havia dito na página anterior, eu irei realizar um exemplo de uma conexão com banco de dados e farei com que dê errado propositadamente a conexão, para poder gerar os logs com a outra classe.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Conexao
{
String conexao;
boolean conectado;
geraLog log;

public Conexao()
{
criaConexao();
}

/**
*Metodo responsavel por criação da conexao com banco de dados
* @return retorna um boolean se for conectado
*
/
private boolean criaConexao()
{
log = new geraLog();
String usuario = “klone”;
String senha = “senha”;
String local = “localhost”;
String database = “Agenda”;
String url = “jdbc:mysql://”+local+ “/” + database;

Connection conexao;

//Força o uso do try / catch
try
{
String driver = “com.mysql.jdbc.Drivers”;
Class.forName(driver).newInstance();
conexao = DriverManager.getConnection(url,usuario,senha);
conectado = true;
System.out.println(“Conectado”);
}
catch (SQLException erro)
{
log.LogTxt(erro.toString(), “Conexao”);
erro.printStackTrace();
conectado = false;
}
catch (ClassNotFoundException e)
{
log.LogTxt(e.toString(), “Conexao”);
e.printStackTrace();
conectado = false;
}
catch (InstantiationException e)
{
log.LogTxt(e.toString(), “Conexao”);
e.printStackTrace();
conectado = false;
}
catch (IllegalAccessException e)
{
log.LogTxt(e.toString(), “Conexao”);
// TODO Auto-generated catch block
e.printStackTrace();
}

return conectado;
}
}

Bom, ficou assim a minha classe. Logo no começo, existe um construtor que irá chamar um método criaConexao(); para dar início à conexão.

Esse método criaConexao(); é um método booleano, pois tenho como objetivo no final desse método, retornar true ou false para verificar se está conectado.

Ainda nesse método, logo de cara, existem as variáveis com as configurações para poder fazer a conexão com banco de dados. Eu estou utilizando o driver JDBC MySQL para poder fazer a conexão e gerar a string do driver.

* Detalhe muito importante: quando você está criando a conexão com banco de dados, o Java força você a usar o try/catch como segurança. É aí que fica o segredo para poder gerar os logs. Pois o catch captura umaException e, a partir daí, podemos chamar um método para gerar o nosso log.

Ainda no método criaConexao(), coloquei diferentes tipos de Exception, para que fique melhor saber qual erro que estou tratando.

Vamos para a próxima etapa, que é nossa classe que gera os logs.

Classe que gera log

Bom, como disse, tem uma classe genérica que poderá gerar nosso log. Essa classe é genérica, porque não depende apenas de uma classe. Essa classe serve para qualquer classe para que eu possa gerar o log.

Obs.: os arquivos gerados de log, geralmente são com a extensão txt, log ou xml. Existe a opção de você gerar o seu log em XML e a partir daí, você pode criar um programinha para ler esse XML mostrando mais detalhes, mas aí vai da sua criatividade.

Minha classe que gera logs ficou assim:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;

public class geraLog
{
public void LogTxt(String nome,String classe)
{
File arquivoTxt = new File(“/home/klone/log_programa.txt”);

if(!arquivoTxt.exists())
{
try
{   //Cria o arquivo
arquivoTxt.createNewFile();
System.out.println(“Arquivo criado”);

//salva o arquivo
FileWriter  writer = new FileWriter(arquivoTxt);
writer.write(“Problema:” + nome+”\n”);
writer.write(“Classe:”+classe+”\n”);
writer.write(“Data:”+ new Date()+”\n”);

writer.close();
System.out.println(“Arquivo salvado”);
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
try
{
FileReader reader = new FileReader(arquivoTxt);
BufferedReader br = new BufferedReader(reader);
String linha = br.readLine();
FileWriter  writer = new FileWriter(arquivoTxt);

while(linha != null)
{
writer.write(linha+”\n”);
br.readLine();
linha = br.readLine();
}

br.close();
reader.close();

writer.write(“Problema:” + nome+”\n”);
writer.write(“Classe:”+classe+”\n”);
writer.write(“Data:”+ new Date());
writer.close();
System.out.println(“Arquivo salvado”);
}
catch(IOException err)
{
err.printStackTrace();
}
}
}
}

Logo no começo, eu crio o arquivo responsável por gravar os erro. Pode-se também fazer com que gere vários arquivos de log, mas nesse exemplo, estarei mostrando como salvar todo os erros num arquivo só.

Como podemos ver, é um método que recebe a mensagem de erro e a classe onde ocorreu o erro.

Essa classe, nada mais é que manipulação de arquivos, onde verifico se o arquivo existe. Se não existir, crio o arquivo e salvo as informações. Se o arquivo existir, abro ele e adiciono mais informações ao final.

Outro dado importante, é que coloco a data e a hora da ocorrência do erro, um dado fundamental.

Assim gera-se nosso log de erro simples.

Conclusão

Logs de erros são fundamentais para um bom sistema estruturado.

Sem eles, fica difícil realizar manutenção no código. Além disso, deixa o usuário mais confiável, pois sabendo-se onde ocorreu o erro, pode-se concertá-lo mais rapidamente.

Logs são mais do que um arquivo falando onde que ocorreu um erro, são um meio de comunicação entre o software e o usuário final.

Rolar para cima