[logback-dev] svn commit: r608 - in logback/trunk/logback-access/src: main/java/ch/qos/logback/access main/java/ch/qos/logback/access/jetty main/java/ch/qos/logback/access/pattern main/java/ch/qos/logback/access/spi test/java/ch/qos/logback/access/jetty

noreply.seb at qos.ch noreply.seb at qos.ch
Wed Sep 27 16:17:35 CEST 2006


Author: seb
Date: Wed Sep 27 16:17:35 2006
New Revision: 608

Added:
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/PostContentConverter.java
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
   logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/
   logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
   logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java
Modified:
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
   logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java

Log:
Work in progress:

- added a PostContentConverter
- created a test case and test setup to create and launch a Jetty server
- added a getPostContent method to AccessEvent
- added the corresponding pattern to PatternLayout
- added javadoc to RequestLogImpl


Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java	Wed Sep 27 16:17:35 2006
@@ -17,6 +17,7 @@
 import ch.qos.logback.access.pattern.LineSeparatorConverter;
 import ch.qos.logback.access.pattern.LocalIPAddressConverter;
 import ch.qos.logback.access.pattern.NAConverter;
+import ch.qos.logback.access.pattern.PostContentConverter;
 import ch.qos.logback.access.pattern.RemoteHostConverter;
 import ch.qos.logback.access.pattern.RemoteIPAddressConverter;
 import ch.qos.logback.access.pattern.RemoteUserConverter;
@@ -49,8 +50,6 @@
     defaultConverterMap.put("b", ContentLengthConverter.class.getName());
     defaultConverterMap.put("B", ContentLengthConverter.class.getName());
     defaultConverterMap.put("bytesSent", ContentLengthConverter.class.getName());
-    
-    
 
     defaultConverterMap.put("h", RemoteHostConverter.class.getName());
     defaultConverterMap.put("clientHost", RemoteHostConverter.class.getName());
@@ -85,6 +84,9 @@
     defaultConverterMap.put("v", ServerNameConverter.class.getName());
     defaultConverterMap.put("server", ServerNameConverter.class.getName());
     
+    defaultConverterMap.put("p", PostContentConverter.class.getName());
+    defaultConverterMap.put("post", PostContentConverter.class.getName());
+    
   }
   
   public PatternLayout() {

Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java	Wed Sep 27 16:17:35 2006
@@ -31,5 +31,4 @@
   public String getResponseHeader(String key) {
     return response.getHeader(key);
   }
-
 }

Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java	Wed Sep 27 16:17:35 2006
@@ -16,7 +16,51 @@
 import ch.qos.logback.core.status.ErrorStatus;
 import ch.qos.logback.core.util.StatusPrinter;
 
-
+/**
+ * This class is logback's implementation of jetty's RequestLog interface.
+ * <p>
+ * It can be seen as logback classic's LoggerContext. Appenders can be attached
+ * directly to RequestLogImpl and RequestLogImpl uses the same StatusManager as
+ * LoggerContext does. It also provides containers for properties.
+ * <p>
+ * To configure jetty in order to use RequestLogImpl, the following lines must
+ * be added to the jetty configuration file:
+ * <pre>
+ * &lt;Ref id="requestLog"&gt; 
+ *   &lt;Set name="requestLog"&gt; 
+ *     &lt;New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl"&gt;&lt;/New&gt;
+ *   &lt;/Set&gt; 
+ * &lt;/Ref&gt;
+ * </pre>
+ * By default, RequestLogImpl looks for a logback configuration file called
+ * logback.xml, in the same folder where jetty.xml is located, that is
+ * /etc/logback.xml. The logback.xml file is slightly different than the usual
+ * logback classic configuration file. Most of it is the same: Appenders and
+ * Layouts are declared the exact same way. However, loggers elements are not
+ * allowed.
+ * <p>
+ * Here is a sample logback.xml file that can be used right away:
+ * <pre>
+ * &lt;configuration&gt; 
+ *   &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt; 
+ *     &lt;layout class="ch.qos.logback.access.PatternLayout"&gt; 
+ *       &lt;param name="Pattern" value="%date %server %remoteIP %clientHost %user %requestURL %post" /&gt;
+ *     &lt;/layout&gt; 
+ *   &lt;/appender&gt; 
+ *   
+ *   &lt;appender-ref ref="STDOUT" /&gt; 
+ * &lt;/configuration&gt;
+ * </pre>
+ * A special, module-specific implementation of PatternLayout was implemented to allow
+ * http-specific patterns to be used. The {@link ch.qos.logback.access.PatternLayout} provides
+ * a way to format the logging output that is just as easy and flexible as the usual 
+ * PatternLayout.
+ * For more information about the general use of a PatternLayout, please refer to logback
+ * classic's {@link ch.qos.logback.classic.PatternLayout}. For information about logback
+ * access' specific PatternLayout, please refer to it's javadoc.
+ * 
+ * @author Ceki G&uuml;lc&uuml;
+ */
 public class RequestLogImpl extends ContextBase implements RequestLog,
     AppenderAttachable {
 
@@ -27,8 +71,10 @@
   String filename;
 
   public void log(Request jettyRequest, Response jettyResponse) {
-    JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest, jettyResponse);
-    AccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse, adapter);
+    JettyServerAdapter adapter = new JettyServerAdapter(jettyRequest,
+        jettyResponse);
+    AccessEvent accessEvent = new AccessEvent(jettyRequest, jettyResponse,
+        adapter);
     // TODO better exception handling
     aai.appendLoopOnAppenders(accessEvent);
   }
@@ -51,18 +97,18 @@
       StatusPrinter.print(getStatusManager());
     } else {
       getStatusManager().add(
-          new ErrorStatus("["+filename+"] does not exist", this));
+          new ErrorStatus("[" + filename + "] does not exist", this));
     }
 
   }
 
   public void stop() throws Exception {
-    System.out.println("RequestLogImpl-stop called");
+    // System.out.println("RequestLogImpl-stop called");
     aai.detachAndStopAllAppenders();
   }
 
   public boolean isRunning() {
-    System.out.println("RequestLogImpl-isRunning called");
+    // System.out.println("RequestLogImpl-isRunning called");
     return false;
   }
 
@@ -71,22 +117,22 @@
   }
 
   public boolean isStarted() {
-    System.out.println("RequestLogImpl-isStarted called");
+    // System.out.println("RequestLogImpl-isStarted called");
     return true;
   }
 
   public boolean isStarting() {
-    System.out.println("RequestLogImpl-isStarting called");
+    // System.out.println("RequestLogImpl-isStarting called");
     return false;
   }
 
   public boolean isStopping() {
-    System.out.println("RequestLogImpl-isStopping called");
+    // System.out.println("RequestLogImpl-isStopping called");
     return false;
   }
 
   public boolean isFailed() {
-    System.out.println("RequestLogImpl-isFailed called");
+    // System.out.println("RequestLogImpl-isFailed called");
     return false;
   }
 

Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/PostContentConverter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/PostContentConverter.java	Wed Sep 27 16:17:35 2006
@@ -0,0 +1,12 @@
+package ch.qos.logback.access.pattern;
+
+import ch.qos.logback.access.spi.AccessEvent;
+
+public class PostContentConverter extends AccessConverter {
+
+  @Override
+  protected String convert(AccessEvent accessEvent) {
+    return accessEvent.getPostContent();
+  }
+
+}

Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java	(original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java	Wed Sep 27 16:17:35 2006
@@ -279,6 +279,20 @@
     return statusCode;
   }
 
+  public String getPostContent() {
+    String content = null;
+    try {
+      content = Util.readToString(httpRequest.getInputStream());
+    } catch (Exception ex) {
+      // do nothing
+    }
+    if (content != null && content.length() > 0) {
+      return content;
+    } else {
+      return NA;
+    }
+  }
+
   public int getLocalPort() {
     if (localPort == SENTINEL) {
       if (httpRequest != null) {

Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/Util.java	Wed Sep 27 16:17:35 2006
@@ -0,0 +1,20 @@
+package ch.qos.logback.access.spi;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Util {
+
+  public static String readToString(InputStream in) throws IOException {
+    StringBuffer sb = new StringBuffer();
+    BufferedReader inbr = new BufferedReader(new InputStreamReader(in));
+    String line;
+    while ((line = inbr.readLine()) != null) {
+      sb.append(line);
+    }
+
+    return sb.toString();
+  }
+}

Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java	Wed Sep 27 16:17:35 2006
@@ -0,0 +1,71 @@
+package ch.qos.logback.access.jetty;
+
+
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Iterator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.access.spi.Util;
+import ch.qos.logback.core.appender.ListAppender;
+
+public class JettyBasicTest extends TestCase {
+  
+  static RequestLogImpl requestLogImpl;
+  
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTestSuite(JettyBasicTest.class);
+    requestLogImpl = new RequestLogImpl();
+    return new JettyTestSetup(suite, requestLogImpl);
+  }
+  
+//  public void testGetRequest() throws Exception {
+//    URL url = new URL("http://localhost:8080/");
+//    HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 
+//    connection.setDoInput(true);
+//    
+//    String result = Util.readToString(connection.getInputStream());
+//    
+//    assertEquals("hello world", result); 
+//    
+//    ListAppender appender = (ListAppender)requestLogImpl.getAppender("list");
+//    appender.list.clear();
+//  }
+  
+  public void testPostContentConverter() throws Exception {
+    System.out.println("into test");
+    URL url = new URL("http://localhost:8080/");
+    HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 
+    ((HttpURLConnection)connection).setRequestMethod("POST");
+    connection.setDoOutput(true);
+    connection.setDoInput(true);
+    connection.setUseCaches(false);
+    connection.setRequestProperty("Content-Type", "text/plain");
+    
+    String msg = "test message";
+    PrintWriter output = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
+    output.print(msg);
+    output.flush();
+    output.close();
+    
+    String result = Util.readToString(connection.getInputStream());
+    
+    ListAppender appender = (ListAppender)requestLogImpl.getAppender("list");
+    //assertEquals(1, appender.list.size());
+    Iterator it = appender.list.iterator();
+    int i = 0;
+    while(it.hasNext()) {
+      AccessEvent event = (AccessEvent)it.next();
+      System.out.println(i++ + ": " + event.getPostContent());
+    }
+    //System.out.println("0: " + event.getPostContent());
+    
+  }
+
+}

Added: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyTestSetup.java	Wed Sep 27 16:17:35 2006
@@ -0,0 +1,119 @@
+package ch.qos.logback.access.jetty;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.HttpConnection;
+import org.mortbay.jetty.Request;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.AbstractHandler;
+import org.mortbay.jetty.handler.ContextHandler;
+import org.mortbay.jetty.handler.RequestLogHandler;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.util.ByteArrayISO8859Writer;
+
+import ch.qos.logback.access.PatternLayout;
+import ch.qos.logback.core.ConsoleAppender;
+import ch.qos.logback.core.appender.ListAppender;
+
+public class JettyTestSetup extends TestSetup {
+
+  ListAppender appender;
+  RequestLogImpl requestLogImpl;
+
+  public JettyTestSetup(Test suite, RequestLogImpl impl) {
+    super(suite);
+    requestLogImpl = impl;
+  }
+
+  Server server;
+  String url = "http://localhost:8080/";
+
+  public void setUp() throws Exception {
+    System.out.println("into setUp");
+    super.setUp();
+
+    server = new Server();
+    Connector connector = new SelectChannelConnector();
+    connector.setPort(8080);
+    server.setConnectors(new Connector[] { connector });
+
+    ContextHandler context = new ContextHandler();
+    context.setContextPath("/");
+    context.setResourceBase(".");
+    context.setClassLoader(Thread.currentThread().getContextClassLoader());
+    server.addHandler(context);
+
+    RequestLogHandler requestLogHandler = new RequestLogHandler();
+    buildContext();
+    requestLogHandler.setRequestLog(requestLogImpl);
+    server.addHandler(requestLogHandler);
+
+    Handler handler = new BasicHandler();
+    context.addHandler(handler);
+
+    server.start();
+  }
+
+  public void tearDown() throws Exception {
+    System.out.println("into tearDown");
+    super.tearDown();
+    server.stop();
+//    Thread.sleep(1000);
+//    server = null;
+//    appender = null;
+//    requestLogImpl = null;
+  }
+
+  private void buildContext() {
+
+    appender = new ListAppender();
+    appender.setContext(requestLogImpl);
+    appender.setName("list");
+    appender.start();
+
+//    ConsoleAppender console = new ConsoleAppender();
+//    console.setContext(requestLogImpl);
+//    console.setName("console");
+//    PatternLayout layout = new PatternLayout();
+//    layout.setContext(requestLogImpl);
+//    layout
+//        .setPattern("%date %server %remoteIP %clientHost %user %requestURL %post");
+//    console.setLayout(layout);
+//    layout.start();
+//    console.start();
+
+    //requestLogImpl.addAppender(console);
+    requestLogImpl.addAppender(appender);
+  }
+
+}
+
+class BasicHandler extends AbstractHandler {
+  public void handle(String target, HttpServletRequest request,
+      HttpServletResponse response, int dispatch) throws IOException,
+      ServletException {
+
+    OutputStream out = response.getOutputStream();
+    ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
+    writer.write("hello world");
+    writer.flush();
+    response.setContentLength(writer.size());
+    writer.writeTo(out);
+    out.flush();
+
+    Request base_request = (request instanceof Request) ? (Request) request
+        : HttpConnection.getCurrentConnection().getRequest();
+    base_request.setHandled(true);
+
+  }
+}
\ No newline at end of file



More information about the logback-dev mailing list