Log de erros. [RESOLVIDO]

Pessoal Boa Noite,
Sou bem novato no mundo java e gostaria de saber se o código abaixo que eu fiz ta legal ou se tem um jeito mais fácil de fazer…eu quis fazer o seguinte…eu capturo a Exception e gravo em um arquivo TXT…funciona bem legal, mas eu não sei se existe algum código pronto que já faz isso…se algum puder dar uma olha e me dar uns toque…valeu pessoal!!!

public class GeraLog {

	public void gravaErro(String erro){

		File log = new File("Log.txt");
		GregorianCalendar gc = new GregorianCalendar();  
		
		
		try {

			FileWriter escrever = new FileWriter("Log.txt", true);
			
			if (log.exists()){
				escrever.write("Data: " + gc.getTime() + "\nErro: " + erro + "\n\n");
				escrever.close();
			}
			else {
				log.createNewFile();
			}
		}catch (IOException e) {
			throw new  RuntimeException(e);
		}catch (NullPointerException e) {
			throw new  RuntimeException(e);
		}catch (Exception e) {
			throw new  RuntimeException(e);
		}
	}
}

Tem alguns problemas:

  1. Feche sempre os writers num bloco finally, e não esqueça de dar flush() antes;
  2. Geralmente, em métodos de log, caso exista problemas para abrir o arquivo, nós simplesmente ignoramos e não geramos o log. Isso evita que o sistema pare de funcionar só pq não está logando. (Só se o sistema for muito crítico para ter algo assim).
  3. Pode ser uma boa associar um PrintWriter ao seu FileWriter. Pelo menos, é mais confortável (você usa métodos como println e printf no lugar de write).

Opa blz, vlw mesmo ViniGody vou concertar os erros, qualquer coisa eu peço ajuda…muito obrigado por ter me ajudado…abraços

Além do que o ViniGodoy citou, levanto mais alguns detalhes:

  1. Você não precisa fazer o teste do if. O construtor do FileWriter vai criar o arquivo caso ele não exista. Então simplesmente crie o FileWriter (ou o PrintWriter, como comentou o Vini) em modo de append e grave a informação.

  2. Ao invés de ficar abrindo e fechando toda vez o arquivo de log onde você vai armazenar os dados, você pode fazer isso apenas uma vez na classe GeraLog (no construtor, por exemplo). Daí o seu método gravaErro() pode ficar responsável apenas por gravar os dados, e não precisa mais ficar abrindo e fechando o arquivo. Caso opte por esta abordagem, você deve ter algum método close() na sua classe que seja chamado em algum lugar do seu código, que vai fechar este arquivo.

  3. O seu método recebe uma string com o erro. Pode ser interessante também você ter um gravaErro() que receba uma Exception como parâmetro. As exceptions possuem a informação sobre a stacktrace do erro, que podem ser armazenadas no log e ajudam bastante quando erros acontecem.

Abraço!

Opa, vlw pela ajuda…mas olha só…eu consegui fazer o que vocês disseram…troquei alguns pontos…fico bem mais rápido…e aproveitei a idéia e não recebo mais uma String e sim um Throwable…ficou bem legal…mais tem algumas coisa que vocês disseram que eu não consegui fazer de jeito nenhum…tipo usar o bloco finally ele pedi para colocar um try para utilizar o flush e o close, muito estranho…mas tudo bem…também não consegui utilizar o print/printf para escrever no arquivo…como faço isso??? olha como ficou o código…bem melhor em…auhauahuahauhauhaa obrigado por me ajudar pessoal…

public class GeraLog {

	
	public GeraLog(Throwable erro){

		try {

			GregorianCalendar gc = new GregorianCalendar();  

			BufferedWriter out = new BufferedWriter(new FileWriter("Log.txt",true));

			out.write("Data do erro: " + gc.getTime() + "\nErro: " + erro + "\n\n");
			out.flush();
			out.close();

		} catch (IOException e) {

			e.printStackTrace();

		} 
	}
}

Só que tem um problema…ta tudo no construtor…tentei colocar só a aparte do arquivo assim:

BufferedWriter out = new BufferedWriter(new FileWriter("Log.txt",true));

Mas ai ele começa a pedir um monte de try/catch para tudo que é lado…

Mas vocês já me ajudaram muito…se puderem dar mais uma olhada…fiquei muito agradecido…

vlw pessoal!!!

Que tal assim?

public class GeraLog {
	
	private PrintWriter out;
	
	public GeraLog() {
		try {
			out = new PrintWriter(new FileWriter("Log.txt"));
		} catch (IOException e) {
			/*
			 * Se der algum erro com o arquivo de log, imprime a stacktrace no console, mas a 
			 * aplicação continua funcionando
			 */
			e.printStackTrace();
		}
	}
	
	public void gravaErro(Throwable erro) {
		out.print("Data do erro: ");
		out.println(new Date());
		out.print("Mensagem de erro: ");
		out.println(erro);
		out.print("Stacktrace: ");
		erro.printStackTrace(out);
	}
	
	public void close() {
		if (out != null) {
                        out.fluse();
			out.close();
		}
	}
}

Você constroi o objeto uma vez na sua aplicação e chama o método gravaErro() sempre que acontecer um problema. No final, quando sua aplicação for ser finalizada, por exemplo, você deve chamar o método close(), para garantir a correta gravação dos dados no arquivo de log.

Sobre o uso dos métodos print() e println() da classe PrintWriter, está mostrado neste exemplo. Ele substituem os write() que você chamava e os “\n”.

O que o Vini havia falado antes sobre a questão do finally não se aplica neste exemplo. Se aplicaria apenas se o seu método gravaErro() abrisse o arquivo (neste caso, ele deveria fechar também). Seria mais ou menos assim:

public void gravaErro(Throwable erro) {
		PrintWriter out = null;
		
		try {
			//abre o arquivo
			out = new PrintWriter(new FileWriter("Log.txt"));
			
			//imprime o log
			out.print("...");
		} catch (IOException e) {
			e.printStackTrace();
		
		} finally {
			//fecha o arquivo
			if (out != null) {
				out.flush();
				out.close();
			}
		}
	}

Espero ter dado mais uma esclarecida em algumas coisas :slight_smile:

Abraço!

Agora eu entendi…hauhauahuahua…novato é fogo viu!!! hauhauahuahuahuahau…mas eu achei um errinho!!! sei lá se é erro…mas no código que você fez ele sempre substitui a ultima Exception! pois na linha:

out = new PrintWriter(new FileWriter("Log.txt"));

Você esqueceu de colocar um true depois do nome do arquivo…

out = new PrintWriter(new FileWriter("Log.txt", true));

Mas MUITO OBRIGADO PELA FORÇA…nunca mais vou esquecer esse código!!!

Vlw mesmo a todos!!!

Ah, você tem razão. Desculpe, fiz o código na mão sem testar e acabou escapando. Mas a ideia é essa mesmo! Boa sorte aí nos seus códigos Java! :slight_smile:

Abraço