SLF4J versión 1.6.1

Este mes fue liberada la versión 1.6.1 del framework SLF4J, del cual ya hablé en un post anterior. Solamente quiero hacer notar una de las mayores diferencias con las versiones anteriores (esto que voy a mencionar fue introducido en la 1.6.0 pero yo apenas me di cuenta):

Los métodos trace, debug, warn, info, etc tenían varias versiones: la que recibe un solo objeto, la que recibe 2, la que recibe un arreglo de objetos y la que recibe un Throwable. Anteriormente, esta última versión era la única que imprimía el stack trace del Throwable, cosa que ya todos sabemos que puede ser muy útil. El problema era si queríamos imprimir algunos otros datos en el mensaje de la excepción; la única opción era usar String.format o concatenar cadenas con el "+" (muy ineficiente). Pero ahora, las versiones que reciben 2 objetos y un arreglo de objetos, detectan si el último objeto recibido es un Throwable y entonces imprimen el stack trace. Esto es muy útil porque ahora podemos convertir una invocación al logger de este tipo:

try {
  //algo que arroja excepcion
} catch (SomeException ex) {
  logger.error(String.format("Hubo un error con el objeto %s clave %d ID %s", objeto, clave, id), ex);
}

En algo más simple, como esto:

try {
  //algo que arroja excepcion
} catch (SomeException ex) {
  logger.error("Hubo un error con el objeto {} clave {} ID {}", new Object[]{ objeto, clave, id, ex });
}

Lo cual además es más rápido en ejecutarse, ya que el mecanismo para formatear cadenas de SLF4J es más rápido que el de String.format(). Evidentemente la ventaja en desempeño se debe a que no hay manera de indicar el formato de un objeto con SLF4J, a diferencia de String.format() en donde podemos indicar el número de posiciones, justificación, dígitos, decimales, formato de fecha, etc para los objetos que se van a imprimir en el mensaje. Por ejemplo si queremos imprimir un BigDecimal siempre con dos decimales o un entero siempre con 6 dígitos relleno con ceros a la izquierda, tenemos que continuar usando String.format, pasando %.2f y %06d para formatear esos parámetros.

Pero en muchos casos cuando estamos imprimiendo errores ya no importa tanto el formato sino imprimir la información pertinente y en eso nos ayuda SLF4J ahora de manera un poco más simple. Pero sigo esperando a que tengan la versión para Java 5 con varargs, lo cual nos va a evitar el engorroso new Object[]{ ... }.

Otro cambio en la versión 1.6.1 es que ahora la dependencia con Log4J es con la versión 1.2.16, que salió en abril de este año.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Buena info...

Estuve leyendo la introducción en tu post Aqui

No conocia este framework...el problema de los frameworks es, que hay mucha diversidad y cuando empiezas a conocer uno ya salio otro mas

Imagen de ezamudio

Problema bueno

El exceso de diversidad, por llamarle de alguna forma, es un problema bueno. Es peor cuando no hay un solo framework para realizar alguna tarea.

Para el caso específico de bitácoras no hay taaaaaanta diversidad: Tienes Log4J que fue de lo primero que salió, luego tienes commons-logging que es una capa de abstracción sobre Log4J y posteriormente cuando salió JUL (java.util.logging) pues ya también commons-logging te permite usar JUL o Log4J. Todos estos frameworks tenían ciertas desventajas, y por eso uno de los programadores que trabajó en Log4J después hizo Logback, una especie de Log4J mejorado en performance y en flexibilidad. Y encima de Logback hizo el SLF4J, que es más simple que commons-logging. SLF4J se puede considerar una capa de abstracción sobre Logback, pero también te permite usar Log4J, JUL, etc. Esa es una de sus ventajas principales; si usas SLF4J en tu aplicación, en tu código solamente tienes una dependencia, y es con al API de SLF4J. Ya la implementación podrá ser sobre Log4J o sobre logback o commons-logging o JUL o lo que sea. Pero a la hora de programar no deberías estarte preocupando por qué framework vas a usar para logging...

Imagen de Nopalin

Hmm

No veo donde este la mejora para el programador, tal vez en performance, pero en comodidad no lo creo. Hubiera sido mejor hicieran nuevas versiones de los metodos que utilizen varargs en lugar de que pases tu un array:

//nueva version del metodo
public void error(String message, Object... params){
}

try {
  //algo que arroja excepcion
} catch (SomeException ex) {
  logger.error("Hubo un error con el objeto {} clave {} ID {}", objeto, clave, id, ex);
}

Eso desde mi parecer, es comodidad para el programdor y no les cuesta nada hacerlo.

sobres.

Imagen de ezamudio

Costo

El costo es perder compatibilidad con Java 1.4, donde no hay varargs. Pero supongo que falta poco para que tengan esas versiones.

Tal vez no va tanto por la parte de comodidad pero sí por el performance. Suponiendo que lo hacen por fases, en el paso de 1.5 a 1.6 puedes empezar a quitar String.format() en los logs que imprimen excepciones, sustituir los %s por {} y poner todos los objetos en un arreglo (cuando tienes más de 1 parámetro y la excepción). Probablemente de la 1.6 a la 1.7 (si no es que antes, dentro de alguna 1.6.x) agreguen por fin la variante con varargs que yo tanto espero también, y entonces ya podemos quitar esos arreglos de objetos y nunca tener que volverlos a usar para logging.

Imagen de Nopalin

A veces pienso que en

A veces pienso que en realidad exageran demasiado muchos programadores, todavia java 1.4? Como (no recuerdo quien) de microsoft dijo hace poco: vamos a quitar el soporte de winxp para que la gente ya empieze a utilizar lo mas nuevo.

Sobres.

Imagen de ezamudio

EOL'd

Pues sí, sobre todo que Java 1.4 ya está oficialmente muerto, al menos la versión normalita JavaSE. Pero la edición de negocios muere en 2013 y se retira todo servicio hasta el 2018. Más info aquí.