Author: [email protected]
Date: Wed Mar 11 12:03:13 2009
New Revision: 4987

Added:
     
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyNullLogger.java   
 
(contents, props changed)
Modified:
    releases/1.6/dev/core/src/com/google/gwt/dev/ServletValidator.java
     
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java

Log:
Make Jetty logging integration with GWT much better.  Individual requests  
are now logged, at appropriate logging levels based on status code.

Patch by: jat (+me)
Review by: me


Modified: releases/1.6/dev/core/src/com/google/gwt/dev/ServletValidator.java
==============================================================================
--- releases/1.6/dev/core/src/com/google/gwt/dev/ServletValidator.java   
(original)
+++ releases/1.6/dev/core/src/com/google/gwt/dev/ServletValidator.java  Wed  
Mar 11 12:03:13 2009
@@ -16,12 +16,14 @@
  package com.google.gwt.dev;

  import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.shell.jetty.JettyNullLogger;

  import org.mortbay.jetty.servlet.ServletHandler;
  import org.mortbay.jetty.servlet.ServletHolder;
  import org.mortbay.jetty.servlet.ServletMapping;
  import org.mortbay.jetty.webapp.WebAppContext;
  import org.mortbay.jetty.webapp.WebXmlConfiguration;
+import org.mortbay.log.Log;

  import java.io.File;
  import java.net.MalformedURLException;
@@ -37,6 +39,12 @@
   * from a <code>WEB-INF/web.xml</code>.
   */
  class ServletValidator {
+
+  static {
+    // Suppress spammy Jetty log initialization.
+    System.setProperty("org.mortbay.log.class",  
JettyNullLogger.class.getName());
+    Log.getLog();
+  }

    public static ServletValidator create(TreeLogger logger, File webXml) {
      try {

Modified:  
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
==============================================================================
---  
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java     
 
(original)
+++  
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java     
 
Wed Mar 11 12:03:13 2009
@@ -19,10 +19,15 @@
  import com.google.gwt.core.ext.ServletContainerLauncher;
  import com.google.gwt.core.ext.TreeLogger;
  import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.TreeLogger.Type;
  import com.google.gwt.dev.util.InstalledHelpInfo;

+import org.mortbay.component.AbstractLifeCycle;
+import org.mortbay.jetty.AbstractConnector;
+import org.mortbay.jetty.Request;
+import org.mortbay.jetty.RequestLog;
+import org.mortbay.jetty.Response;
  import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.RequestLogHandler;
  import org.mortbay.jetty.nio.SelectChannelConnector;
  import org.mortbay.jetty.webapp.WebAppClassLoader;
  import org.mortbay.jetty.webapp.WebAppContext;
@@ -32,6 +37,7 @@
  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
+import java.util.Enumeration;

  /**
   * A launcher for an embedded Jetty server.
@@ -39,64 +45,90 @@
  public class JettyLauncher extends ServletContainerLauncher {

    /**
-   * An adapter for the Jetty logging system to GWT's TreeLogger. This
-   * implementation class is only public to allow {...@link Log} to  
instantiate it.
-   *
-   * The weird static data / default construction setup is a game we play  
with
-   * {...@link Log}'s static initializer to prevent the initial log message  
from
-   * going to stderr.
+   * Log jetty requests/responses to TreeLogger.
     */
-  public static final class JettyTreeLogger implements Logger {
-    private static Type nextBranchLevel;
-    private static TreeLogger nextLogger;
+  public class JettyRequestLogger extends AbstractLifeCycle implements
+      RequestLog {

-    /**
-     * Returns true if the default constructor can be called.
-     */
-    public static boolean isDefaultConstructionReady() {
-      return nextLogger != null;
+    private final TreeLogger logger;
+
+    public JettyRequestLogger(TreeLogger logger) {
+      this.logger = logger;
      }

      /**
-     * Call to set initial state for default construction; must be called  
again
-     * each time before a default instantiation occurs.
+     * Log an HTTP request/response to TreeLogger.
       */
-    public static void setDefaultConstruction(TreeLogger logger,
-        Type branchLevel) {
-      if (logger == null || branchLevel == null) {
-        throw new NullPointerException();
+    @SuppressWarnings("unchecked")
+    public void log(Request request, Response response) {
+      int status = response.getStatus();
+      if (status < 0) {
+        // Copied from NCSARequestLog
+        status = 404;
+      }
+      TreeLogger.Type logStatus, logHeaders;
+      if (status >= 500) {
+        logStatus = TreeLogger.ERROR;
+        logHeaders = TreeLogger.INFO;
+      } else if (status >= 400) {
+        logStatus = TreeLogger.WARN;
+        logHeaders = TreeLogger.INFO;
+      } else {
+        logStatus = TreeLogger.INFO;
+        logHeaders = TreeLogger.DEBUG;
+      }
+      String userString = request.getRemoteUser();
+      if (userString == null) {
+        userString = "";
+      } else {
+        userString += "@";
+      }
+      String bytesString = "";
+      if (response.getContentCount() > 0) {
+        bytesString = " " + response.getContentCount() + " bytes";
+      }
+      TreeLogger branch = logger.branch(logStatus, String.valueOf(status)
+          + " - " + request.getMethod() + ' ' + request.getUri() + " ("
+          + userString + request.getRemoteHost() + ')' + bytesString);
+      TreeLogger headers = branch.branch(logHeaders, "Request headers");
+      Enumeration<String> headerNames = request.getHeaderNames();
+      while (headerNames.hasMoreElements()) {
+        String hdr = headerNames.nextElement();
+        String hdrVal = request.getHeader(hdr);
+        headers.log(logHeaders, hdr + ": " + hdrVal);
        }
-      nextLogger = logger;
-      nextBranchLevel = branchLevel;
+      // TODO(jat): add response headers
      }
+  }

-    private final Type branchLevel;
+  /**
+   * An adapter for the Jetty logging system to GWT's TreeLogger. This
+   * implementation class is only public to allow {...@link Log} to  
instantiate it.
+   *
+   * The weird static data / default construction setup is a game we play  
with
+   * {...@link Log}'s static initializer to prevent the initial log message  
from
+   * going to stderr.
+   */
+  public static final class JettyTreeLogger implements Logger {
      private final TreeLogger logger;

-    public JettyTreeLogger() {
-      this(nextLogger, nextBranchLevel);
-      nextLogger = null;
-      nextBranchLevel = null;
-    }
-
-    public JettyTreeLogger(TreeLogger logger, Type branchLevel) {
-      if (logger == null || branchLevel == null) {
+    public JettyTreeLogger(TreeLogger logger) {
+      if (logger == null) {
          throw new NullPointerException();
        }
-      this.branchLevel = branchLevel;
        this.logger = logger;
      }

      public void debug(String msg, Object arg0, Object arg1) {
-      logger.log(TreeLogger.DEBUG, format(msg, arg0, arg1));
+      logger.log(TreeLogger.SPAM, format(msg, arg0, arg1));
      }

      public void debug(String msg, Throwable th) {
-      logger.log(TreeLogger.DEBUG, msg, th);
+      logger.log(TreeLogger.SPAM, msg, th);
      }

      public Logger getLogger(String name) {
-      return new JettyTreeLogger(logger.branch(branchLevel, name),  
branchLevel);
+      return this;
      }

      public void info(String msg, Object arg0, Object arg1) {
@@ -104,7 +136,7 @@
      }

      public boolean isDebugEnabled() {
-      return logger.isLoggable(TreeLogger.DEBUG);
+      return logger.isLoggable(TreeLogger.SPAM);
      }

      public void setDebugEnabled(boolean enabled) {
@@ -191,6 +223,7 @@
        branch.log(TreeLogger.INFO, "Stopped successfully");
      }
    }
+
    /**
     * A {...@link WebAppContext} tailored to GWT hosted mode. Features  
hot-reload
     * with a new {...@link WebAppClassLoader} to pick up disk changes. The  
default
@@ -375,29 +408,23 @@
     */
    private static final String PROPERTY_NOWARN_WEBAPP_CLASSPATH  
= "gwt.nowarn.webapp.classpath";

+  static {
+    // Suppress spammy Jetty log initialization.
+    System.setProperty("org.mortbay.log.class",  
JettyNullLogger.class.getName());
+    Log.getLog();
+  }
+
    public ServletContainer start(TreeLogger logger, int port, File  
appRootDir)
        throws Exception {
      checkStartParams(logger, port, appRootDir);

-    // The dance we do with Jetty's logging system -- disabled, log to  
console.
-    if (false) {
-      System.setProperty("VERBOSE", "true");
-      JettyTreeLogger.setDefaultConstruction(logger, TreeLogger.INFO);
-      System.setProperty("org.mortbay.log.class",
-          JettyTreeLogger.class.getName());
-      // Force initialization.
-      Log.isDebugEnabled();
-      if (JettyTreeLogger.isDefaultConstructionReady()) {
-        // The log system was already initialized and did not use our
-        // newly-constructed logger, set it explicitly now.
-        Log.setLog(new JettyTreeLogger());
-      }
-    }
+    // Setup our own logger.
+    Log.setLog(new JettyTreeLogger(logger));

      // Turn off XML validation.
      System.setProperty("org.mortbay.xml.XmlParser.Validating", "false");

-    SelectChannelConnector connector = new SelectChannelConnector();
+    AbstractConnector connector = getConnector();
      connector.setPort(port);

      // Don't share ports with an existing process.
@@ -413,12 +440,19 @@
      WebAppContext wac = new WebAppContextWithReload(logger,
          appRootDir.getAbsolutePath(), "/");

-    server.setHandler(wac);
+    RequestLogHandler logHandler = new RequestLogHandler();
+    logHandler.setRequestLog(new JettyRequestLogger(logger));
+    logHandler.setHandler(wac);
+    server.setHandler(logHandler);
      server.start();
      server.setStopAtShutdown(true);

      return new JettyServletContainer(logger, server, wac,
          connector.getLocalPort(), appRootDir);
+  }
+
+  protected AbstractConnector getConnector() {
+    return new SelectChannelConnector();
    }

    private void checkStartParams(TreeLogger logger, int port, File  
appRootDir) {

Added:  
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyNullLogger.java
==============================================================================
--- (empty file)
+++  
releases/1.6/dev/core/src/com/google/gwt/dev/shell/jetty/JettyNullLogger.java   
 
Wed Mar 11 12:03:13 2009
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * 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.google.gwt.dev.shell.jetty;
+
+import org.mortbay.log.Logger;
+
+/**
+ * A Jetty {...@link Logger} that suppresses all output.
+ */
+public class JettyNullLogger implements Logger {
+
+  public void debug(String msg, Throwable th) {
+  }
+
+  public void debug(String msg, Object arg0, Object arg1) {
+  }
+
+  public Logger getLogger(String name) {
+    return this;
+  }
+
+  public void info(String msg, Object arg0, Object arg1) {
+  }
+
+  public boolean isDebugEnabled() {
+    return false;
+  }
+
+  public void setDebugEnabled(boolean enabled) {
+  }
+
+  public void warn(String msg, Throwable th) {
+  }
+
+  public void warn(String msg, Object arg0, Object arg1) {
+  }
+}

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to