[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [mindfood] SLF4J y Version 99 Does Not Exist



Hola,

Nosotros tambiÃn evaluamos cambiar a SLF4J hace un tiempo, aunque no
terminamos de (empezar a) hacer la migraciÃn.
En mi opiniÃn, lo peor de Commons-Logging es que no acabas percibiendo
el valor que presupone la librerÃa. Commons-Logging surgià para lidiar
con la amenaza que suponÃa el nuevo API del JDK para logging, que al
final resultà (al menos en lo que yo he visto) no ser tal competidor
frente a Log4J. Y a cambio de esa promesa, te obliga a sufrir pequeÃos
contratiempos esporÃdicos del tipo
"org.apache.commons.logging.impl.Log4jFactory does not implement
LogFactory", o incluso los temidos "NoClassDefFoundException".

Nosotros tenemos comentada la linea tÃpica de:
-Dorg.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.Log4jFactory
y vamos descomentÃndola y volviÃndola a comentar segÃn aparecen los
problemas. Al final, no llegas a nada en claro. SÃlo quieres no perder
tiempo en eso. Ya es bastante 'tricky' a veces Log4J como para hacerlo
todo mÃs lioso.

Aparte de eso, el 'Parameterized Logging' aparentemente no tiene mÃs
que ventajas: simplifica, no pierde el tiempo construyendo el mensaje
si no va a imprimirlo... Pero deja vÃa libre a que se haga mal uso
inadvertidamente.

Por ejemplo, al migrar a SLF4J un cÃdigo como Ãste:

if (logger.isInfoEnabled()) {
  logger.info("User " + user.getUserId() + " has posted " +
  dao.findMessagesByUser(user.getUserId()).size() + " messages in "
  + (dateFormatter.format(new Date() - user.getRegistrationDate())) + "
    days.");
}

Resultando si se hace tal cual en:

  logger.info("User {} has posted {} messages in {} days.",
     new Object[] {
         new Long(user.getUserId()),
         new Long(dao.findMessagesByUser(user.getUserId()).size()),
         new Integer(dateFormatter.format(new Date() -
         user.getRegistrationDate()))
     });

Con lo que incurrirÃamos en un peor rendimiento si INFO no estÃ
habilitado para ese logger, que con el 'if'. Aparte, el 'if' tampoco lo
hace mÃs complicado, pero sà mÃs incÃmodo.

Que conste que aunque uno se hace mayor y tal, y ya no soy tan
activista en contra del logging, sigue gustÃndome mÃs un cÃdigo sin
logging que con Ãl. Si pones debug y lo dejas y llega a producciÃn, es
una 'guarrerÃa'. Si te sirvià para arreglar algo, perfecto, pero una
vez arreglado quÃtalo. El compilador deberÃa hacer incompatible la
optimizaciÃn con los 'logger.debug()".

BTW, Âquà fue de orange :) ?

On Tue, 10 Feb 2009 18:32:02 +0100 Rafael Luque Leiva
<rafael.luque@xxxxxxxx> wrote:

> 
> Hola,
> 
> En nuestro Ãltimo proyecto, que estamos a punto de poner en
> producciÃn, hemos decidido migrar a SLF4J (Simple Logging Facade for
> Java) [1], un proyecto detrÃs del cuÃl està Ceki GÃlcÃ, creador de
> Log4J.
> 
> Conceptualmente el proyecto es similar a Jakarta Commons Logging
> (JCL) [2]; es decir, proporciona a las aplicaciones un API fachada de
> logging, que permite reemplazar la implementaciÃn de logging
> subyacente (Log4J, JDK 1.4, Logback, etc.) sin tener que recompilar la
> aplicaciÃn. Esto es especialmente Ãtil para desarrolladores de
> librerÃas o frameworks, que de este modo, no imponen al usuario final
> ninguna dependencia de una implementaciÃn concreta.
> 
> La diferencia entre ambos frameworks radica en su implementaciÃn,
> siendo la de SLF4J mucho mÃs sencilla (y tambiÃn robusta). A
> diferencia de JCL, la asociaciÃn con la implementaciÃn finalmente
> empleada se realiza estÃticamente (en tiempo de despliegue)
> evitÃndonos los frecuentes problemas con classloaders que plantea
> commons-logging. Por ejemplo, para usar Log4J como backend, basta
> aÃadir el adaptador slf4j-log4j12.jar (y por supuesto
> log4j-1.2.x.jar) al classpath de la aplicaciÃn.
> 
> AdemÃs de resolver los quebraderos de cabeza habituales de JCL, aporta
> otras caracterÃsticas interesantes como:
> 
>   * Parametrized Logging: Estamos acostumbrados a evitar el coste de
>     generaciÃn de los mensajes de traza cuando està desactivada
>     mediante expresiones de comprobaciÃn del tipo:
> 
>       Logger logger = ...
> 
>       if (logger.isInfoEnabled()) {
>         logger.info("Thread name: " + name);
>       }
> 
>     Mediante los mensajes parametrizados de SLF4J esta expresiÃn se
>     puede reemplazar por esta otra, mucho mÃs simple:
> 
>       logger.info("Thread name: {}", name);
> 
> 
>   * Puente entre APIs de logging: AdemÃs de usar directamente el
>     SLF4J API, tambiÃn es posible usarlo como puente entre diferentes
>     implementaciones. Existen implementaciones de JCL over SLF4J o
>     Log4J over SLF4J, de modo que las aplicaciones existentes se
>     pueden migrar fÃcilmente.
> 
> Los que useis Maven2 os encontrareis con la tediosa tarea de
> excluir las dependencias transitivas de commons-logging de cada
> librerÃa que la utilice. En este punto nos ha resultado de gran
> utilidad "Version 99 Does Not Exist" [3], un simple pero genial idea
> de Erik Van Ooesten, consistente en un repositorio Maven 2 que sirve
> JARs vacÃos (y sus correspondientes poms y metadatos) de cualquier
> paquete con el nÃmero de versiÃn 99.0-does-not-exist. 
> 
> De esta manera, para eliminar cualquier rastro de commons-logging de
> un proyecto basado en Maven2, basta con aÃadir la dependencia:
> 
>     <dependency>
>         <groupId>commons-logging</groupId>
>         <artifactId>commons-logging</artifactId>
>         <version>99.0-does-not-exist</version>
>     </dependency>
> 
> 
> Espero que a alguien le pueda ser de utilidad.
> 
> Un saludo,
> Rafa
> 
> 
> [1] SLF4J: http://www.slf4j.org/
> [2] JCL: http://commons.apache.org/logging/
> [3] Version99 Does Not Exist:
> http://day-to-day-stuff.blogspot.com/2007/10/announcement-version-99-does-not-exist.html
> 
>