Personal tools
gvSIG Desktop
gvSIG Desktop

Cached time 11/22/13 08:18:34 Clear cache and reload

 
Document Actions

Logging

by Cèsar Ordiñana last modified 2010-08-27 13:59
En gvSIG se emplea la librería SLF4J como API de logging a emplear.

SLF4J_ Simple Logging Facade o *"Fachada de Registro Simple"* es un framework que se ha creado para abstraer el sistema de registro que hay por debajo. Como el sistema de registro más popular usado es Log4j, el API del framework es muy similar para simplificar al máximo eliminar la dependencia directa de este sistema. Este framework por tanto es una capa de abstracción del sistema de registro, y nos va a permitir cambiar el componente de registro que lleve por debajo sin necesidad de un gran esfuerzo de recodificación de la aplicación.

.. _SLF4J : http://www.slf4j.org/


Características de SLF4J
-----------------------------

- **SLF4J** es una capa de abstracción independiente cualquier sistema de registro *"logging"* concreto.
- Permite al usuario final acoplar la implementación deseada en tiempo de despliegue.
- Permite una migración gradual a partir de Jakarta Commons Logging ( **JCL** ), ya que dispone de un wrapper del API de JCL sobre su propio API.
- Dispone de un sistema de registro parametrizado que reduce el *overhead* de evaluar los strings de los mensajes, sobre todo cuando no están habilitados los mensajes de debug.

.. code-block:: java

 // Those lines produce the same results. The second one has parameters that reduce the overhead when debuggin is disabled
 LOG.debug("The new entry is "+entry+"."); 
 LOG.debug("The new entry is {}.", entry);

- Dispone de soporte para Mapped Diagnostic Context ( **MDC** ), si el sistema de registro que funciona bajo SLF4J lo soporta. Por el momento sólo lo hacen **Log4j** y **logback** .
- Los sistemas de logging pueden escoger entre implementar el interfaz de SLF4J directamente como **logback** y **SimpleLogger** ó escribir adpatadores SLF4J para una implementación dada como en los casos de **Log4jLoggerAdapter** y **JDK14LoggerAdapter** .
- No delega en un sistema de carga de clases específico (class loader) para delegar en un sistema de registro específico, es decir, se configura estáticamente en tiempo de compilación, sólo se permite usar uno y sólo un sistema de registro *logging* . Simplemente se añade al CLASSPATH el jar del API del sistema de *logging* junto con *slf4j-api.jar*. Esto evita los problemas de carga de clases y pérdidas de memoria sufridos por Jakarta **JCL** .
- **SLF4J** tiene también una interfaz muy próxima a **JCL** y **Log4j** API actualmente en uso, por tanto el esfuerzo de implementación se reduce significativamente.
- **gvSIG** continúa utilizando el mismo toolkit de logging ( **Log4j** ) por tanto, prácticamente no existen cambios en tiempo de ejecución.
- Se gana en flexibilidad, robustez y eficiencia, mediante la posibilidad de cambiar el componente de logging, ya sea para todas las versiones de gvSIG o alternativamente para versiones concretas sin modificar el código fuente de **gvSIG**.
- Es el standard que se ha recogido en los proyectos OSGI_ , debido a que puede adaptar proyectos que ya usan commons-logging con facilidad, debido a la popularidad adquirida de este framework estudiado anteriormente.

.. _OSGI : http://www.osgi.org/Main/HomePage

Cómo usar SLF4J en gvSIG
--------------------------------

gvSIG 2.0 ya está preparado para trabajar con SLF4J, usando LOG4J como implementación, por lo que podemos usarlo directamente desde cualquier extensión de gvSIG.

Para usar SLF4J desde una clase Java basta con incluir las siguientes sentencias:

1.- Importar las clases necesarias

.. code-block:: java

      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;

2.- Declaramos e inicializamos el *Logger*.

.. code-block:: java

      public class MyClass
      {
          private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
          ...
          
3.- Usamos el *Logger* dentro del código de la clase, cuando queramos mostrar un mensaje de log, dependiendo del tipo: error, alerta, información, depuración o traza:

.. code-block:: java

          LOG.warn(String message);
          LOG.warn(String message,Object arg1);
          LOG.warn(String message,Object[] arg1);
          LOG.warn(String message, Throwable arg1);
          LOG.info(String message);
          LOG.info(String message,Object arg1);
          LOG.info(String message,Object[] arg1);
          LOG.info(String message, Throwable arg1);
          LOG.error(String message);
          LOG.error(String message,Object arg1);
          LOG.error(String message,Object[] arg1);
          LOG.error(String message, Throwable arg1);
          LOG.debug(String message);
          LOG.debug(String message,Object arg1);
          LOG.debug(String message,Object[] arg1);
          LOG.debug(String message, Throwable arg1);
          LOG.trace(String message);
          LOG.trace(String message,Object arg1);
          LOG.trace(String message,Object[] arg1);
          LOG.trace(String message, Throwable arg1);
              

Los siguientes métodos se proporcionan para consultar la activación de los mensajes por nivel:

.. code-block:: java

          LOG.isErrorEnabled();
          LOG.isWarnEnabled();
          LOG.isInfoEnabled();
          LOG.isDebugEnabled();
          LOG.isTraceEnabled();

En **SLF4J** tenemos la capacidad adicional de parametrizar los mensajes, insertando variables dentro de la cadena String del mensaje de registro, como en el siguiente ejemplo: 

.. code-block:: java

        private Integer temperature;

        public void setTemperature(Integer temperature) {
    
            LOG.debug("Setting temperature to {}. Old temperature was {}.", temperature, this.temperature);
  
            this.temperature = temperature;

            if(temperature.intValue() > 50) {
              LOG.info("Temperature has risen above 50 degrees.");
            }
        }

Esto evita que tengamos que ir concatenando Strings, lo cuál reduce el coste del uso de las instrucciones de logging. Esto es debido a que, aunque el nivel de log que estemos usando esté desactivado (por ejemplo, el de debug), la invocación al método se hará de todas formas, incluyendo la concatenación de Strings para construir el mensaje, si la hubiera.

De todas formas, si la obtención de alguno de los parámetros que vamos a pasar al mensaje de log fuera costosa, es conveniente emplear los métodos de consulta para evitar dicha ejecución. Por ejemplo:

.. code-block:: java

        private Integer temperature;

        public void setTemperature(Integer temperature) {
    
            LOG.debug("Setting temperature to {}. Old temperature was {}.", temperature, this.temperature);
  
            this.temperature = temperature;
            addToTemperatureLog(temperature);
    
            if (LOG.isDebugEnabled()) {
                LOG.debug("The current average temperature is {} Celsius", calculateAverageTemperature());
            }
        }

View source document

View source document Get permanent link


Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: