[This blog was syndicated from http://nitschinger.at/]

Introducción

Hay una gran variedad de marcos de registro para Java, y es difícil complacer a todos. Para entender cómo se gestiona actualmente el registro en el SDK, tenemos que retroceder unos años. Como ya sabrás, el SDK depende del framework spymemcached y, por tanto, hereda también sus mecanismos de registro. En los tiempos en que @dustin escribió espía, no había una buena abstracción para el registro disponible (como SLF4J), así que escribió el suyo propio. Hoy en día las cosas han cambiado, pero el espionaje sigue heredando este legado.

En el momento de escribir esto, el SDK soporta el registro en un simple registrador por defecto (registra en STDERR a partir del nivel INFO), Log4J y SunLogger (java.util.logging). En la próxima versión 2.9.0 de spymemcached, también será compatible con la fachada de registro SLF4J donde podrá conectar su propia implementación. La próxima versión del SDK (probablemente 1.1.7) dependerá de spy 2.9, por lo que también obtendrá los beneficios allí.

Antes de profundizar en los conceptos, he aquí los niveles de registro admitidos (definidos por net.spy.memcached.compat.log.Level):

  1. TRACE (con 2.9)
  2. DEBUG
  3. INFO
  4. AVISO
  5. ERROR
  6. FATAL

Tenga en cuenta que los diferentes registradores implementan diferentes niveles, por lo que para algunos de ellos es necesario realizar un mapeo. Esto se indicará durante las descripciones de cada implementación.

A continuación veremos los distintos mecanismos de registro disponibles y cómo configurarlos. SLF4J será cubierto hacia el final.

Conmutación Registro

Si no cambias nada, se utilizará el logger por defecto. Este mecanismo sólo imprime mensajes de registro en STDERR (a partir del nivel INFO). Lo más probable es que quiera integrar el SDK con la misma librería de logging que utiliza. El LoggerFactory dentro de spy decide en la construcción cual elegir, basado en una propiedad del sistema. Por lo tanto, puede cambiar esto mediante programación o a través de un parámetro de la directiva java mando.

Si desea utilizar el Log4JLogger mediante programación, hágalo de esta forma (antes de inicializar el archivo CouchbaseClient objeto):

Propiedades systemProperties = System.getProperties();
systemProperties.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.Log4JLogger");
System.setProperties(systemProperties);

Por supuesto, necesitas añadir el JAR Log4J a tu CLASSPATH para que funcione (como veremos más adelante). Alternativamente, puedes configurarlo así en la línea de comandos:

java -Dnet.spy.log.LoggerImpl=net.spy.memcached.compat.log.Log4JLogger ...

Ahora que ya sabemos cómo activar las distintas implementaciones, vamos a verlas con más detalle.

El registrador simple por defecto

Si no cambia nada, el SDK utilizará el DefaultLogger (net.spy.memcached.compat.log.DefaultLogger). Este registrador no tiene dependencias e imprime todos los mensajes de registro de nivel INFO o superior (INFO, WARN, ERROR y FATAL) en el STDERR del sistema. Dado que el STDERR es cubierto por la mayoría de los IDEs automáticamente, también los verás en la ventana de salida de la consola.

Como es tan simple, no se puede personalizar este comportamiento. Cada mensaje de registro recibe también un sello de tiempo (el formato es aaaa-MM-dd HH:mm:ss.SSS). Conectarse a Couchbase comúnmente se parece a esto:

 
2013-05-07 12:28:41.852 INFO com.couchbase.client.CouchbaseConnection: Added {QA sa=/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2013-05-07 12:28:41.862 INFO com.couchbase.client.CouchbaseConnection: Estado de conexión cambiado para sun.nio.ch.SelectionKeyImpl@3d9360e2
2013-05-07 12:28:41.887 INFO com.couchbase.client.ViewConnection: Añadido localhost a la cola de conexión
2013-05-07 12:28:41.888 INFO com.couchbase.client.CouchbaseClient: la propiedad viewmode no está definida. Estableciendo viewmode a modo de producción.
2013-05-07 12:28:41.986 INFO com.couchbase.client.CouchbaseConnection: Shut down Couchbase client
2013-05-07 12:28:41.991 INFO com.couchbase.client.ViewConnection: El nodo localhost no tiene operaciones en la cola
2013-05-07 12:28:41.992 INFO com.couchbase.client.ViewNode: Reactor de E/S terminado para localhost
 

Así que el formato es siempre: . Recuerda que los mensajes DEBUG o similares no se registrarán, por lo que no los verás con el DefaultLogger.

 

SunLogger (java.util.logging)

El SunLogger tampoco introduce dependencias adicionales, ya que depende del módulo java.util.logging aplicación. El sitio java.util.logging.Level define los siguientes niveles: ALL, CONFIG, FINEST, FINER, FINE, INFO, WARNING, SEVERE y OFF. Dado que esto no se corresponde bien con nuestros niveles definidos, a continuación se muestra la correspondencia que se produce:

 
  1. TRACE to FINEST (con 2.9)
  2. DEBUG a FINE
  3. INFO a INFO
  4. de WARN a WARNING
  5. ERROR a SEVERO
  6. FATAL a SEVERO
 
Sin más cambios, el SunLogger también imprime desde el nivel INFO hacia arriba de la siguiente manera:
 
7 de mayo de 2013 12:42:16 PM com.couchbase.client.CouchbaseProperties setPropertyFile
INFO: No se ha podido cargar el fichero de propiedades "cbclient.properties" porque: Archivo no encontrado con el cargador de clases del sistema.
May 7, 2013 12:42:16 PM net.spy.memcached.MemcachedConnection createConnections
INFO: Añadido {QA sa=/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} a la cola de conexión.
7 de mayo de 2013 12:42:16 PM net.spy.memcached.MemcachedConnection handleIO
INFO: Estado de conexión cambiado para sun.nio.ch.SelectionKeyImpl@4ce2cb55
7 de mayo de 2013 12:42:16 PM com.couchbase.client.ViewConnection createConnections
INFO: Añadido localhost a la cola de conexión
7 de mayo de 2013 12:42:16 PM com.couchbase.client.CouchbaseClient
INFO: la propiedad viewmode no está definida. Establecer viewmode a modo de producción
May 7, 2013 12:42:16 PM com.couchbase.client.CouchbaseConnection run
INFO: Cerrar cliente Couchbase
7 de mayo de 2013 12:42:16 PM cierre de com.couchbase.client.ViewConnection
INFO: El nodo localhost no tiene operaciones en la cola.
May 7, 2013 12:42:16 PM com.couchbase.client.ViewNode$1 run
INFO: Reactor de E/S terminado para localhost
 

Si quieres cambiar el nivel de registro a DEBUG e inferior, puedes hacerlo así:

 
Logger.getLogger("com.couchbase.client").setLevel(Level.FINEST);
 

Ahora hay una cosa más que tienes que hacer si quieres imprimir todos los mensajes de depuración en la consola. Has configurado correctamente el nivel de registro, pero la opción ConsoleHandler aún no está configurado para depuración (así que lo más probable es que pague el precio del registro de depuración, pero en realidad no verá nada en su IDE).

 
for(Handler h : Logger.getLogger("com.couchbase.client").getParent().getHandlers()) {
     if(h instanceof ConsoleHandler) {
        h.setLevel(Level.FINEST);
     }
}
 

Así pues, he aquí un ejemplo completo de cómo utilizar la función SunLogger y obtener todos los mensajes de depuración en la consola.

 
    Propiedades systemProperties = System.getProperties();
    systemProperties.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.SunLogger");
    System.setProperties(systemProperties);

    Logger logger = Logger.getLogger("com.couchbase.client");
    logger.setLevel(Level.FINEST);
    for(Handler h : logger.getParent().getHandlers()) {
       if(h instanceof ConsoleHandler){
         h.setLevel(Level.FINEST);
       }
    }

 

A continuación, sólo tiene que seguir adelante y crear su CouchbaseClient verá un resultado detallado como éste (recortado aquí):

 
May 7, 2013 12:54:34 PM com.couchbase.client.vbucket.ReconfigurableObserver update
FINEST: Recibida una actualización, notificando reconfigurables sobre un com.couchbase.client.vbucket.config.Bucketcom.couchbase.client.vbucket.config.Bucket@3d77949
May 7, 2013 12:54:34 PM com.couchbase.client.vbucket.ReconfigurableObserver update
FINEST: Recibida una actualización, notificando reconfigurables sobre un com.couchbase.client.vbucket.config.Bucketcom.couchbase.client.vbucket.config.Bucket@4e927ae
May 7, 2013 12:54:34 PM com.couchbase.client.vbucket.ReconfigurableObserver update
FINEST: Dice que es por defecto y está hablando con /pools/default/bucketsStreaming/default?bucket_uuid=adfff22b70e09fafaa26ca37b7e05e9d
May 7, 2013 12:54:34 PM com.couchbase.client.vbucket.ReconfigurableObserver updat
FINEST: Dice que es por defecto y está hablando con /pools/default/bucketsStreaming/default?bucket_uuid=adfff22b70e09fafaa26ca37b7e05e9d
 

Log4J

La mayoría de la gente necesitará más flexibilidad, y Log4J era (y sigue siendo) estándar en muchas aplicaciones. El SDK también proporciona soporte para Log4J. Para que funcione, primero tienes que configurar la instancia correctamente:

 
    Propiedades systemProperties = System.getProperties();
    systemProperties.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.Log4JLogger");
    System.setProperties(systemProperties);
 

Ahora bien, si ejecuta esto, obtendrá un error que algunas de las clases Log4J no se puede encontrar. Esto no es una sorpresa, porque no está en el classpath. Vamos a arreglar esto añadiéndolo como corresponde. Si usas maven, añade el log4j.log4j (la versión actual es 1.2.17). También puede descargar el JAR y añadirlo al CLASSPATH según sea necesario.

 
Ahora, si lo ejecutamos de nuevo, obtenemos otro error:
 
log4j:WARN No se han encontrado appenders para el logger (com.couchbase.client.vbucket.ConfigurationProviderHTTP).
log4j:WARN Por favor, inicialice el sistema log4j correctamente.
log4j:WARN Consulte http://logging.apache.org/log4j/1.2/faq.html#noconfig para obtener más información.
 

Una forma de solucionarlo es obtener un log4j.xml en nuestro CLASSPATH, pero para que funcione con rapidez Log4J proporciona un archivo de configuración ConfiguradorBásico. Justo después de las configuraciones de las propiedades del sistema, añade esto:

 
org.apache.log4j.BasicConfigurator.configure();
 

Si lo ejecutas con el cambio de código aplicado, verás que obtenemos mensajes de registro bien impresos. También puede ver que se muestran directamente desde el nivel DEBUG (e incluso contienen información de qué hilo se registraron):

 
69 [main] INFO com.couchbase.client.CouchbaseConnection - Añadido {QA sa=/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} a la cola de conexión.
70 [main] DEBUG com.couchbase.client.vbucket.VBucketNodeLocator - Actualizando nodesMap en VBucketNodeLocator.
73 [main] DEBUG com.couchbase.client.vbucket.VBucketNodeLocator - Añadiendo nodo con nombre de host 127.0.0.1:11210.
74 [main] DEBUG com.couchbase.client.vbucket.VBucketNodeLocator - El nodo añadido es {QA sa=localhost/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=8}.
74 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG com.couchbase.client.CouchbaseConnection - Terminado el tratamiento de la cola.
74 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG com.couchbase.client.CouchbaseConnection - Seleccionando con retardo de 0ms
79 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG com.couchbase.client.CouchbaseConnection - Seleccionado 1, seleccionadas 1 claves
79 [Memcached IO sobre
 

Puedes controlar los niveles de registro a través de los mecanismos habituales de Log4J. No voy a entrar en detalles acerca de ellos aquí, así que por favor comprobar su documentación oficial (por ejemplo, sobre cómo utilizar el Configurador de propiedades en su lugar).

Hablando de Log4J,  Steffen Larsen implementado un Apéndice Log4J ¡para almacenar los registros en Couchbase (en lugar de un archivo)!

La nueva fachada: SLF4J

No vincular la aplicación a una biblioteca de registro específica es siempre una buena idea. SLF4J es una fachada para varios marcos de registro enchufables detrás de él. Así que puedes elegir la implementación de registro durante el tiempo de ejecución, ya sea LogbackLog4J u otros. Puesto que ya hemos probado Log4J, vamos a hacer que SLF4J funcione con Logback, uno de los marcos de registro más comunes que existen.

Tenga en cuenta que la compatibilidad con SLF4J estará disponible en la versión 1.9.0 de spymemcached y, por tanto, también en una de las próximas versiones del SDK Java de Couchbase.

En primer lugar, tenemos que configurarlo en consecuencia:

Propiedades systemProperties = System.getProperties();
systemProperties.put("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.SLF4JLogger");
System.setProperties(systemProperties);
 

Ahora, necesitamos incluir dos JARs en nuestro classpath. El primero es la API de fachada SLF4J y el otro es nuestro marco de registro de elección. El paquete de la API de fachada se llama slf4j-api (este paquete tiene que estar siempre en su sitio) y como queremos usar logback tenemos que incluir el paquete logback-classic JAR. Tenga en cuenta que esto no es específico para el SDK, puede encontrar esta información aquí. Si usas maven, puedes usar este snippet:

   
      org.slf4j
      slf4j-api
      1.7.5
   

   
      ch.qos.logback
      logback-classic
      1.0.12
   
 

SLF4J recogerá automáticamente nuestra implementación de logback, por lo que los registros tendrán este aspecto:

 
13:25:43.692 [main] INFO c.c.client.CouchbaseConnection - Añadido {QA sa=/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} a la cola de conexión.
13:25:43.694 [main] DEBUG c.c.c.vbucket.VBucketNodeLocator - Actualizando nodesMap en VBucketNodeLocator.
13:25:43.697 [main] DEBUG c.c.c.vbucket.VBucketNodeLocator - Añadiendo nodo con nombre de host 127.0.0.1:11210.
13:25:43.697 [main] DEBUG c.c.c.vbucket.VBucketNodeLocator - El nodo añadido es {QA sa=localhost/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=8}.
13:25:43.698 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG c.c.client.CouchbaseConnection - Terminado el tratamiento de la cola.
13:25:43.699 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG c.c.client.CouchbaseConnection - Seleccionando con retardo de 0ms
13:25:43.702 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG c.c.client.CouchbaseConnection - Seleccionado 1, seleccionadas 1 claves
13:25:43.703 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] DEBUG c.c.client.CouchbaseConnection - Manejo de IO para: sun.nio.ch.SelectionKeyImpl@48ff2413 (r=false, w=false, c=true, op={QA sa=localhost/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=8})
13:25:43.703 [Memcached IO sobre {MemcachedConnection a localhost/127.0.0.1:11210}] INFO c.c.client.CouchbaseConnection - Estado de conexión cambiado para sun.nio.ch.SelectionKeyImpl@48ff2413
13:25:43.713
 

Como puedes ver, aquí también incluyen el registro a nivel DEBUG. Si no incluye la implementación de registro durante el tiempo de ejecución, SLF4J se quejará al inicio:

 
SLF4J: Error al cargar la clase "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Implementación por defecto del registrador sin operación (NOP)
SLF4J: Para más información, consulte http://www.slf4j.org/codes.html#StaticLoggerBinder
 
Si quieres aprender a configurar logback, mira aquí.
 

Resumen

Una vez que conoces la abstracción en spymemcached y cómo funciona, cambiar de implementación de logging es fácil y directo. Si trabajas con alguna de las personas de Couchbase para reportar errores, por favor intenta incluir la salida con DEBUG activado, porque esto incluye mucha información útil que puede ser usada para determinar las fuentes de fallo.

Con la fachada SLF4J que se añadirá en la próxima versión espía (2.9), podrá conectar al SDK todos los grandes marcos de registro existentes. Háganos saber si usted ve un caso de uso no cubierto con estos mecanismos o si tiene otros comentarios sobre esto.

Autor

Publicado por Michael Nitschinger

Michael Nitschinger trabaja como Ingeniero de Software Principal en Couchbase. Es el arquitecto y mantenedor del SDK Java de Couchbase, uno de los primeros controladores de bases de datos completamente reactivos en la JVM. También es autor y mantiene el conector Spark de Couchbase. Michael participa activamente en la comunidad de código abierto, contribuyendo a otros proyectos como RxJava y Netty.

Dejar una respuesta