Cuando vemos código que usa un sistema de log para mostrar los mensajes de la aplicación, suele ser habitual ver código como el siguiente
if (log.isDebugEnabled()) {
log.debug("Hola, " + nombre);
}
¿Por qué se usa isDebugEnabled()?
El motivo de usar esta llamada es para evitar que se construya la cadena de texto a mostrar en el log si realmente no se va a mostrar. En el ejemplo anterior, no tiene sentido componer la cadena «Hola, «+nombre si no la vamos a mostrar porque el log de debug no está habiliado.
Así que si nuestro mensaje es de debug, ponemos primero el if para ver si dicho mensaje va a salir. Sólo construimos la cadena si va a mostrarse.
En este ejemplo, construir la cadena no es muy costoso, pero puede haber cadenas a mostrar que requieran más variables, que las llamadas a toString() que hará java para esas variables no sean rápidas, quizás estén involucrados los antiguos StringBuffer que además están sincronizados.
Así que isDebugEnabled() se usa sólo por eficiencia. Evitar construir las cadenas de log si no van a mostrarse.
Por supuesto, tenemos variantes para los distintos niveles de log, como trace, info, warn, etc.
¿Pero es realmente necesario isDebugEnabled()?
Los nuevos sistemas de log, como slf4j, hacen esta llamada inútil. Eso sí, siempre y cuando no construyamos nosotros la cadena como en el ejemplo. Una llamada mejor, usando slf4j, sería la siguiente
if (log.isDebugEnabled()) {
log.debug("Hola, {}", nombre);
}
Fíjate que en vez de construir la cadena como antes y pasar un único parámetro al método debug(), estamos pasando una cadena «Hola, {}» que tiene una pareja de llaves y luego estamos pasando un parámetro. Deberíamos pasar tantos parámetros como parejas «{}» hayamos puesto en la primera cadena.
slf4j irá reemplazando los «{}» por los valores de los parámetros que pasemos a continuación, en orden. Y lo mejor de todo es, que internamente, mirará si el log va a salir o no antes de hacer las operaciones para componer la cadena.
Así que como lo hace internamente, la llamada externa a isDebugEnabled() nos sobra totalmente, es redundante. Nos basta con
log.debug("Hola, {}", nombre);
Mucho más sencillo que ir poniendo un if antes de cada log ¿verdad?
¿Y si quiero sacar el log de una excepción?
En los métodos normales de otros sistemas de log se admitía un texto como mensaje y un segundo parámetro que fuera una excepción. La idea es que si se produce una excepción en nuestro código y la capturamos, podamos sacarla por el sistema de log
try {
...
} catch (Exception e) {
log.error("Se ha producido un error", e);
}
Si ahora slf4j admite el mensaje con «{}» y todos los parámetros que queramos para reemplazar los «{}» con sus valores, ¿cómo sacamos la excepción?. Sencillo, nos basta ponerla como último parámetro. slf4j supondrá que si el último parámetro es de tipo Throwable, es una excepción que debe mostrar y no un parámetro para reemplazar una pareja «{}»
try {
...
} catch (Exception e) {
log.error("Lo siento {}, se ha producido un error", nombre, e);
}
Conclusión sobre isDebugEnabled()
Así que la conclusión es que si usas sl4j y un formato de mensajes de log basado en cadenas con «{}» para reemplazar valores, NO necesitas usar isDebugEnabled().
Tu pregunta ahora será ¿Por qué usar slf4j?