My favorites | Sign in
Project Logo
                
Search
for
Updated Nov 08, 2009 by fredsa
Labels: Featured
GettingStarted  
Getting started with gwt-log in your own application.

Here's a quick tutorial to using the gwt-log module in your own application.

While the Eclipse IDE is not strictly necessary, having a good IDE such as Eclispe will make your life a lot easier. Certainly feel free to use your IDE of choice.

GWT Compatibility

GWT Version gwt-log Version
GWT 2.0.0 gwt-log-3.0.0.jar
GWT 1.7.0 gwt-log-2.6.2.jar
GWT 1.6.4 gwt-log-2.6.2.jar
GWT 1.5.3 gwt-log-2.5.2.jar
GWT 1.5.2 gwt-log-2.5.2.jar
GWT 1.5.1 (1.5 RC2) gwt-log-2.5.2.jar
GWT 1.5.0 (1.5 RC1) gwt-log-2.5.2.jar
GWT 1.4.62 (1.4 update 2) gwt-log-1.5.6.jar
GWT 1.4.61 (1.4 update) gwt-log-1.5.6.jar
GWT 1.4.60 (1.4) gwt-log-1.5.6.jar

If you can, please switch to the latest GWT version and gwt-log version.

Adding the gwt-log Module to your Eclipse Project

  1. Download the latest gwt-log-<version>.jar and place it in a convenient location.
  2. (Optional) if you want to play with the demo (examples), you'll need to grab that from Subversion in the trunk/Log/demo/ directory, as there is no jar file for the com.allen_sauer.gwt.log.demo package.
  3. Create a GWT Eclipse project as instructed here: http://code.google.com/webtoolkit/gettingstarted.html#NewEclipse
  4. Right-click on the project node in the Package Explorer and select 'Build Path > Add External Archives...'. Select gwt-log-<version>.jar.
  5. Make sure GWT can find the gwt-log module at runtime. Modify MyProject/src/com/mycompany/MyApplication.gwt.xml to include one of the following:
  6.         <!-- For production most teams prefer to set the default log level to `OFF` -->
    	<inherits name="com.allen_sauer.gwt.log.gwt-log-OFF" />
    
            <!-- For development a default of `DEBUG` is recommended -->
    	<inherits name="com.allen_sauer.gwt.log.gwt-log-DEBUG" />
    
            <!-- To compile at `DEBUG`, `WARN` and `OFF` log levels (at 3x compile time) -->
    	<inherits name="com.allen_sauer.gwt.log.gwt-log-OFF" />
            <extend-property name="log_level" values="DEBUG,WARN"/>
    
            <!-- 
               Default `OFF` but allow selection of a specific log level, say `INFO`, via the `log_level` URL parameter, e.g.
                 http[s]://hostame:port/path/to/your/module/Module.html?log_level=INFO
            -->
    	<inherits name="com.allen_sauer.gwt.log.gwt-log-OFF" />
            <extend-property name="log_level" values="INFO"/>
    
            <!-- 
               Compile both `DEBUG` and `ERROR` log level, with level selection via a `gwt:property` meta tag in your HTML file, e.g.
                    <meta name="gwt:property" content="log_level=DEBUG">
            -->
            <inherits name="com.allen_sauer.gwt.log.gwt-log-ERROR" />
            <extend-property name="log_level" values="DEBUG"/>

Other things you might want to do

  1. Dynamically adjust the run time log level at run time
  2.           Log.setCurrentLogLevel(Log.LOG_LEVEL_...);
  3. Get the floating DivLogger out of the way
  4. Enable the remote logging option (disabled by default), which send copies of all client log messages to the server. This is particularly useful for mobile development.
  5. Turn on the experimental WindowLogger (disabled by default), which can log messages to a separate window so that Logging does not affect the DOM in your application:
  6.   <!--
        Enable experimental WindowLogger, which logs messages to a separate
        popup window. There are currently a couple of restrictions:
    
        1. When Firefox is configured to open new Windows as new tabs,
           WindowLogger does not work
        2. In hosted mode, the windows are not automatically closed,
           although you can easily close them manually in the usual way
      -->
      <set-property name="log_WindowLogger" value="ENABLED" />
    
      <!--
        You probably will want to disable the default `DivLogger` as well:
      -->
      <set-property name="log_DivLogger" value="DISABLED" />
  7. Control which loggers are active:
  8.   <!-- Loggers Enabled by default -->
      <set-property name="log_ConsoleLogger" value="ENABLED" />
      <set-property name="log_DivLogger" value="ENABLED" />
      <set-property name="log_FirebugLogger" value="ENABLED" />
      <set-property name="log_GWTLogger" value="ENABLED" />
      <set-property name="log_SystemLogger" value="ENABLED" />
      
      <!-- Loggers Disabled by default -->
      <set-property name="log_RemoteLogger" value="DISABLED" />
      <set-property name="log_WindowLogger" value="DISABLED" />
  9. Control the format of your log messages
  10.   <!--
        Inspired by Apache log4j PatternLayout:
        http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html
      -->
      <set-configuration-property name="log_pattern" value="%d [%-5p] %m%n" />
  11. Adjust the z-index of the DivLogger panel
    • Review the gwt-log.css file to see the CSS which is injected into your application by gwt-log
    • Override the z-index (using !important if necessary) by adding a new rule to your application's CSS, e.g.
    •   .log-panel {
          z-index: 2000;
        }
    or
      .log-panel {
        z-index: 2000 !important;
      }

Getting More out of gwt-log

  1. Setup an UncaughtExceptionHandler, which is as easy as calling Log.setUncaughtExceptionHandler() before you do anything else in your module. Note that you will need to use a DeferredCommand and void any constructor or stand-alone initialization code in your EntryPoint class if you really want to catch everything in web mode. In Firefox and IE this will even catch exceptions thrown in setTimeout() or setInterval() functions.
  2.   public void onModuleLoad() {
        Log.setUncaughtExceptionHandler();
    
        DeferredCommand.addCommand(new Command() {
          public void execute() {
            onModuleLoad2();
          }
        });
      }
    
      private void onModuleLoad2() {
        // Your client code goes here
      }
  3. Add logging to your serializable domain objects, POJOs, etc. for both client and server side logging
  4. In development you likely want to use -style PRETTY rather than the default -style OBFUSCATED in order to get better web mode stack trace methods.
  5. (In svn trunk) when developing you may wish to turn on enhanced web mode stack traces. Note this adds overhead to the resulting JavaScript so you generally don't want to leave this on for production.
  6.   <set-property name="compiler.emulatedStack" value="true" />
      <set-configuration-property name="compiler.emulatedStack.recordLineNumbers" value="true"/>
      <set-configuration-property name="compiler.emulatedStack.recordFileNames" value="true"/>
  7. Use gwt-log seemlessly on Google App Engine

Working Examples

There are some working examples along with the demo source code for you to look at.

There's also the library source code if you want to see what makes it tick.

An Introductory Example

  1. Use this code in your EntryPoint class:
  2. /*
     * Copyright 2008 Fred Sauer
     * 
     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
     * use this file except in compliance with the License. You may obtain a copy of
     * the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations under
     * the License.
     */
    package com.mycompany.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.user.client.Command;
    import com.google.gwt.user.client.DeferredCommand;
    
    import com.allen_sauer.gwt.log.client.Log;
    
    public class MyApplication implements EntryPoint {
      /**
       * This field gets compiled out when <code>log_level=OFF</code>, or
       * any <code>log_level</code> higher than <code>DEBUG</code>.
       */
      private long startTimeMillis;
    
      /**
       * Note, we defer all application initialization code to
       * {@link #onModuleLoad2()} so that the UncaughtExceptionHandler
       * can catch any unexpected exceptions.
       */
      public void onModuleLoad() {
        /* Install an UncaughtExceptionHandler which will
         * produce <code>FATAL</code> log messages
         */
        Log.setUncaughtExceptionHandler();
    
        /* Use a deferred command so that the UncaughtExceptionHandler
         * catches any exceptions in onModuleLoad2()
         */
        DeferredCommand.addCommand(new Command() {
          public void execute() {
            onModuleLoad2();
          }
        });
      }
    
      private void onModuleLoad2() {
        /* Use a <code>if (Log.isDebugEnabled()) {...}</code> guard to
         * ensure that <code>System.currentTimeMillis()</code>
         * is compiled out when <code>log_level=OFF</code>, or
         * any <code>log_level</code> higher than <code>DEBUG</code>.
         */
        if (Log.isDebugEnabled()) {
          startTimeMillis = System.currentTimeMillis();
        }
    
        /* No guards necessary.
         * Code will be compiled out when <code>log_level=OFF</code>
         */
        Log.debug("This is a 'DEBUG' test message");
        Log.info("This is a 'INFO' test message");
        Log.warn("This is a 'WARN' test message");
        Log.error("This is a 'ERROR' test message");
        Log.fatal("This is a 'FATAL' test message");
    
        /* Again, we need a guard here, otherwise <code>log_level=OFF</code>
         * would still produce the following useless JavaScript:
         * <pre>
         *     var durationSeconds, endTimeMillis;
         *     endTimeMillis = currentTimeMillis_0();
         *     durationSeconds = (endTimeMillis - this$static.startTimeMillis) / 1000.0;
         * </pre>
         */
        if (Log.isDebugEnabled()) {
          long endTimeMillis = System.currentTimeMillis();
          float durationSeconds = (endTimeMillis - startTimeMillis) / 1000F;
          Log.debug("Duration: " + durationSeconds + " seconds");
        }
      }
    }

Hosted by Google Code