Dudas de uso Logger en java

bloodhound

¡Hola!

Os explico rápidamente lo que me pasa. Estamos haciendo un trabajo en clase de programación y somos un grupo de 4 personas. A mi me ha tocado la parte del logging. La cosa es que después de mirar la API java.util.logging más o menos la entiendo, pero tengo un par de problemas a la hora de la implementación.

Código que he hecho

Como veréis tiene un "main", cosa que me extraña que debiera tener.

Mi principal duda es cómo podría modificar esta clase para llamarla desde cualquier clase del programa. Y como se pueden hacer las llamadas.

En realidad me importa poco que sea sobre mi clase (no pretendo que me hagáis los deberes). Lo que busco es entender un poco como se podría hacer.

Gracias de antemano. :)

cabron

En lugar de un método main deberías tener un constructor donde inicialices el objeto (crear el objeto Logger, configurar el nivel de log, el archivo en el que vas a escribir, etc). También tendrías que tener un método público al que llamarás cuando quieras escribir algo, este método delegará en el método de la clase Logger que es el que realmente escribé el log. Luego lo usarias tal que:

logger = new LoggerBasico();

logger.log("lo que sea" );

También podrías hacer que tu clase sea subclase de Logger, así no tienes que añadir tus propios métodos que delegen a la clase Logger para escribir.

1 respuesta
bloodhound

#2 Pero si quiero que el logger sea común para todas las clases no puedo estar creando un logger en cada clase ¿no?

1 respuesta
dagavi

#3 ¿El código de #1 lo has realizado (o copiado) sabiendo que es lo que hace? Porque me extraña mucho que digas "me extraña que tenga un main".

Eso es un simple código para ver como usar las clases de log de Java, y como ves, no es necesario que pongas ninguna clase de por medio. La gente que tenga que escribir logs puede hacerlo replicando el código que has escrito.

Por otro lado podrías crear una clase estática a la que se le pase un String y esta se encarge de escribir dicho string al log. Lo que necesitas saber es que es estática, con eso se puede llamar desde cualquier lado.

Logger.escribe("Se ha judio el prugrama!!!!" );

Como alternativa a los métodos y atributos estáticos está aplicar el patrón singleton: constructora privada (nadie puede crear instancias) y un método "getInstance()" que retorne la única instancia de logger del sistema.

1
JuAn4k4

Yo que tu, si tienes libre eleccion, usaria log4j y no java.util.logging que es la peste.

en cada clase, es tan sencillo como :

private static Logger logger = Logger.getLogger(MiClase.class);

y en el codigo :

logger.debug(...)

logger.info(..)

y solo tienes que tener en el classpath, un fichero log4j.properties que configuras para tener ficheros de logging etc.

Asi cada clase tiene su nivel de logging (definido en el fichero de propiedes)

log4j.logger.org.mipackage.MiClase=DEBUG

22 días después
bloodhound

Más o menos tenía solucionado el tema del logger, metiendolo en un bloque estático en la clase principal tal que así:

spoiler

Pues resulta que cuando yo llamo al logger desde cualquier clase de ese paquete si que me introduce archivos en el log.txt.

La llamada para obtener el logger es más o menos así:

Logger logger = Logger.getLogger("ubu.itig.prav.reproductor");
logger.severe("Esto ha petado");

El problema está en que tengo otras clases en otro paquete que requieren usar el mismo log. Y realizando la misma llamada es como si no estuviera. No funciona dentro un bloque catch. No introduce nada.

¿Sugerencias? Gracias.

JuAn4k4

Vamos a ver, creo que no entiendes muy bien lo que significa static.

static se ejecuta al cargar la clase, y se ejecuta una unica vez, no es muy lógico hacer try catch -> System.exit.

El logging es al fin y al cabo escribir mensajes en un fichero, cada mensaje puede tener un nivel distinto, y el Logger lo que proporciona es una interfaz sencilla de usar.

En general, cada clase deberia tener su instancia de Logger, y usarlo, pero si lo que quieres es, tener una clase que se encargue del Logging, eso ya esta hecho, por la mayoria de logs.

En si, deberias a acostumbrarte a no reinventar la rueda :

log4j -> http://logging.apache.org/log4j/
apache commons logging -> http://commons.apache.org/logging/
slf4j -> www.slf4j.org/

En si, es muy sencillo utilizar cualquiera de estos, pero si aun si quieres implementar tu clase, y utilizar la peor opcion de todas ( java.util.logging )

http://www.crazysquirrel.com/computing/java/logging.jspx

La configuracion de tu logger, deberia ir en un fichero a parte. logging.properties, log4j.properties , ... etc

public class MiClaseQueNecesitaLogging  {

   private static final org.apache.log4j.Logger logger =  org.apache.log4j.Logger.getLogger(MiClaseQueNecesitaLogging .class);

 private static final org.apache.commons.logging.Log logger = LogFactoryUtil.getLogger(MiClaseQueNecesitaLogging .class);


 private static final java.util.logging.Logger javaUtilLogger = java.util.logging.Logger.getLogger(MiClaseQueNecesitaLogging .class);



public void methodQueNecesitaLogging() {

   if (logger.isDebugEnabled()) {
     logger.debug("Hola!");
   }
   if (javaUtilLogger.isDebugEnabled()) {
    javaUtilLogger.debug("Mi logger 2");
   }
}

}

Te recomiendo mirarte de aquel que vayas a usar, como se configura...

Si te peta el logging, lo mas logico es desactivar el logging...

1 respuesta
bloodhound

#7 No me has entendido. Y no voy ni mucho menos reinventando la rueda.

Y sé bastante bien como funcionan los niveles del logger.

Sé lo que hace el bloque static al arrancar el programa por eso meto toda la configuración de mi Logger ahí (FileHandler, Formatter...).

Y no me peta el logging, no sé si me he explicado mal.

Lo que ocurre es que tengo una conexión a una base de datos, la cual, obligatoriamente, tiene que ir en un bloque try, haciendo un catch de una SQLException.
Dado el punto en el que no se puede conectar salta la excepción y la tengo que introducir en el Logger. ¿Dónde hago esto? Inmediatamente después de que suceda, en el bloque catch.

Y la cosa es que loguea en cualquier clase del programa, incluso en ese método, pero fuera del bloque catch.

Me he revisado el archivo de configuración config.logger, y no hay nada que me solucione el problema.

Por cierto tampoco puedo utilizar logger 4 java.

#9 Para llamar al logger desde la clase que necesito, pongo un atributo privado de esta forma:

private Logger logger = Logger.getLogger("ubu.itig.prav.reproductor");
1 respuesta
elkaoD

#8 cómo llamas al logger? Prueba a hacer el getLogger si vas a usar un logger global con Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)

1 respuesta

Usuarios habituales

  • elkaoD
  • bloodhound
  • JuAn4k4
  • dagavi
  • cabron