joi, 4 iunie 2009

java.util.logging si o clasa de logare

In acest post arat cum se poate implementa o clasa logger care poate loga trei tipuri de mesaje:
  • info
  • warning
  • error
Aceste mesaje sunt salvate intr-un fisier de forma: err-"datacurenta". Acest stil de logger este inspirat din logger-ele traditionale din unix/linux. Clasa ce urmeaza sa fie listata mai jos utilizeaza java.util.logging si ar trebui sa fie suficienta pentru majoritatea aplicatiilor. Clasa este un singleton intrucat am nevoie sa o instantiez o singura data.

package ro.example;

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.logging.*;

public class LoggerSingleton {
private static Logger logger;
private static LoggerSingleton selfInst = null;
private String msgFile = "err%s.log";

private LoggerSingleton() throws Exception {
logger = Logger.getLogger("MyApplication");

this.switchStdErr(this.msgFile);
}

/**
* Metoda folosita pentru a schimba stderr(standard error stream)
* @param fName
* @throws Exception
*/
private void switchStdErr(String fName) throws Exception {
Calendar cal = GregorianCalendar.getInstance();
String file = String.format(fName, cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH));

PrintStream err = new PrintStream(new FileOutputStream(file, true));

System.setErr(err);
}

public static LoggerSingleton getInstance() throws Exception {
if(selfInst == null)
selfInst = new LoggerSingleton();

return selfInst;
}

/**
* Metoda folosita pentru a scrie un mesaj de tip info
* @param msg
*/
public void writeInfo(String msg) {
try {
logger.log(Level.INFO, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}


/**
* Metoda folosita pentru a scrie un warning
* @param msg
*/
public void writeWarning(String msg) {
try {
logger.log(Level.WARNING, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}

public void writeWarning(Exception excp) {
try {
logger.log(Level.WARNING, excp.getMessage(), excp);
}
catch(Exception ex) {
ex.printStackTrace();
}
}


/**
* Metoda folosita pentru a loga un mesaj de eroare.
* @param msg
*/
public void writeError(String msg) {
try {
logger.log(Level.SEVERE, msg);
}
catch(Exception ex) {
ex.printStackTrace();
}
}

public void writeError(Exception excp) {
try {
logger.log(Level.SEVERE, excp.getMessage(), excp);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}

Obs: Metoda log din class Logger scrie mesajele in System.err. Din acest motiv primul lucru pe care il fac este sa redirectionez System.err catre fisierul dorit.

In continuare arat un posibil fisier de test care utilizeaza toate metodele disponibile.

package ro.example;

/**
* @author Radu Viorel Cosnita
* Doar testez logarea fiecarui tip de mesaj definit in logger singleton.
*/
public class TestLoggerSingleton {
public static void main(String[] args) throws Exception {
LoggerSingleton log = LoggerSingleton.getInstance();

log.writeInfo("Doar ca sa ma amuz");
log.writeWarning("Doar un warning");
log.writeError("Doar un mesaj de eroare");

try {
throw new Exception("O eroare draguta");
}
catch(Exception ex) {
log.writeWarning(ex);
log.writeError(ex);
}
}
}

Rezultatul obtinut a fost generarea unui fisier numit: err2009-5-4.log cu urmatorul continut:

Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeInfo
INFO: Doar ca sa ma amuz
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeWarning
WARNING: Doar un warning
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeError
SEVERE: Doar un mesaj de eroare
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeWarning
WARNING: O eroare draguta
java.lang.Exception: O eroare draguta
at ro.example.TestLoggerSingleton.main(TestLoggerSingleton.java:16)
Jun 4, 2009 3:27:01 PM ro.example.LoggerSingleton writeError
SEVERE: O eroare draguta
java.lang.Exception: O eroare draguta
at ro.example.TestLoggerSingleton.main(TestLoggerSingleton.java:16)

In fiecare zi in care se executa/invoca metode din clasa TestLoggerSingleton va fi generat un log separat. Aceasta abordare permite urmarirea evolutiei aplicatie intr-o maniera extrem de simpla. Intr-un post viitor voi arata cum se poate genera un log in format xml in log de plaintext.

Niciun comentariu:

Trimiteți un comentariu