Personal tools
gvSIG Desktop
gvSIG Desktop

Cached time 11/21/13 17:00:12 Clear cache and reload

 
In gvSIG the SLF4J library is used as a logging API.

The Simple Logging Facade SLF4J is a framework that is designed to abstract the underlying logging system. As Log4j is the most popular logging system in use, the framework's API is very similar to simply removing the direct dependence of this system. This framework is therefore an abstraction layer of the logging system and will allow us to change the underlying components without having to undertake major recoding of the application.

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


Features of SLF4J
-----------------------------

- **SLF4J** is an abstraction layer independent of any actual logging system.
- Allows the end user to attach the desired implementation at deployment time.
- Allows gradual migration from Jakarta Commons Logging (**JCL**), because it has a JCL API wrapper in its own API.
- There is a parameterized logging system that reduces the overhead of assessing the message strings, especially when debug messages are enabled.

.. code-block:: java

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


- Support for Mapped Diagnostic Context (**MDC**), if the logging system operating under SLF4J supports it. At the moment only **Log4j** and **logback** do so.
- Logging systems may choose to implement the SLF4J interface directly as **logback** and **SimpleLogger**, or write SLF4J adapters for a given implementation as in the cases of **Log4jLoggerAdapter** and **JDK14LoggerAdapter**.
- Does not delegate to a specific class loading system (class loader) for delegating to a specific logging system, ie statically configured at compile time, only allowed to use one and only one *logging* system. Simply add the logging system API's jar to the CLASSPATH, together with *slf4j-api.jar*. This avoids the problems of class loading and memory loss suffered by Jakarta **JCL**.
- **SLF4J** also has an interface very similar to the **JCL** and **Log4j** APIs currently in use, so the implementation effort is significantly reduced.
- **gvSIG** continues to use the same logging toolkit (**Log4j**) so there will be practically no changes at run time.
- You gain in flexibility, robustness and efficiency through the ability to change the logging component without modifying the **gvSIG** source code, either for all versions of gvSIG or for specific versions.
- It's the standard that has been collected in OSGI_ projects because projects that are already using commons-logging can be adapted easily due to the popularity that this framework has gained.

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

Using SLF4J in gvSIG
--------------------------------

gvSIG 2.0 is ready to work with SLF4J, using LOG4J as implementation, and can be used directly from any gvSIG extension.

To use SLF4J from a Java class just include the following statements:

1.- Import the necessary classes:

.. code-block:: java

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

2.- Declare and initialize the *Logger*:

.. code-block:: java

      public class MyClass
      {
          private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
          ...
          
3.- We use the *Logger* within the code of the class when we want to display a log message, depending on the type: error, warning, information, debug or trace:

.. 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);
              

The following methods are provided to check the activation of messages for each level:

.. code-block:: java

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

In addition, the messages can also be customized in **SLF4J** by inserting variables into the String of the log message, as in the following example:

.. 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.");
            }
        }

This stops us from having to concatenate Strings, which reduces the cost of using the instructions for logging. This is because, although the log level that we are using is disabled (for example, debug), the method call will be made anyway, including the concatenation of strings to build the message, if any.

However, if the obtaining of any of the parameters to be passed to the message log proves costly, it is convenient to use the consultation methods to avoid such implementation. For example:

.. 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


Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: