[logback-dev] svn commit: r1251 - 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/servlet main/java/ch/qos/logback/access/spi main/java/ch/qos/logback/access/tomcat test/java/ch/qos/logback/access/pattern/helpers
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Thu Jan 18 17:05:40 CET 2007
Author: ceki
Date: Thu Jan 18 17:05:40 2007
New Revision: 1251
Added:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java
Modified:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java
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/servlet/TeeFilter.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java
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/ServerAdapter.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyServerAdapter.java
logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java
Log:
Added support for the http response, including contents.
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java Thu Jan 18 17:05:40 2007
@@ -1,7 +1,6 @@
package ch.qos.logback.access;
public class Constants {
-
public static final String LB_INPUT_BUFFER = "LB_INPUT_BUFFER";
-
+ public static final String LB_OUTPUT_BUFFER = "LB_OUTPUT_BUFFER";
}
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 Thu Jan 18 17:05:40 2007
@@ -15,6 +15,7 @@
import ch.qos.logback.access.pattern.ContentLengthConverter;
import ch.qos.logback.access.pattern.DateConverter;
import ch.qos.logback.access.pattern.FullRequestConverter;
+import ch.qos.logback.access.pattern.FullResponseConverter;
import ch.qos.logback.access.pattern.LineSeparatorConverter;
import ch.qos.logback.access.pattern.LocalIPAddressConverter;
import ch.qos.logback.access.pattern.LocalPortConverter;
@@ -31,6 +32,7 @@
import ch.qos.logback.access.pattern.RequestProtocolConverter;
import ch.qos.logback.access.pattern.RequestURIConverter;
import ch.qos.logback.access.pattern.RequestURLConverter;
+import ch.qos.logback.access.pattern.ResponseContentConverter;
import ch.qos.logback.access.pattern.ResponseHeaderConverter;
import ch.qos.logback.access.pattern.ServerNameConverter;
import ch.qos.logback.access.pattern.StatusCodeConverter;
@@ -135,7 +137,10 @@
defaultConverterMap.put("requestContent", RequestContentConverter.class.getName());
+ defaultConverterMap.put("responseContent", ResponseContentConverter.class.getName());
+
defaultConverterMap.put("fullRequest", FullRequestConverter.class.getName());
+ defaultConverterMap.put("fullResponse", FullResponseConverter.class.getName());
defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
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 Thu Jan 18 17:05:40 2007
@@ -1,5 +1,10 @@
package ch.qos.logback.access.jetty;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.mortbay.jetty.HttpFields;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.Response;
@@ -7,11 +12,11 @@
/**
* A jetty specific implementation of the {@link ServerAdapter} interface.
- *
+ *
* @author Sébastien Pennec
*/
public class JettyServerAdapter implements ServerAdapter {
-
+
Request request;
Response response;
@@ -19,7 +24,7 @@
this.request = jettyRequest;
this.response = jettyResponse;
}
-
+
public long getContentLength() {
return response.getContentCount();
}
@@ -27,8 +32,18 @@
public int getStatusCode() {
return response.getStatus();
}
-
+
public String getResponseHeader(String key) {
return response.getHeader(key);
}
+
+ public List<String> getResponseHeaderNameList() {
+ HttpFields httpFields = response.getHttpFields();
+ List<String> hnList = new ArrayList<String>();
+ Enumeration e = httpFields.getFieldNames();
+ while (e.hasMoreElements()) {
+ hnList.add((String) e.nextElement());
+ }
+ return hnList;
+ }
}
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/FullResponseConverter.java Thu Jan 18 17:05:40 2007
@@ -0,0 +1,32 @@
+package ch.qos.logback.access.pattern;
+
+import java.util.List;
+
+import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.core.Layout;
+
+public class FullResponseConverter extends AccessConverter {
+
+ @Override
+ public String convert(AccessEvent ae) {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("HTTP/1.1 ");
+ buf.append(ae.getStatusCode());
+ buf.append(" NA");
+ buf.append(Layout.LINE_SEP);
+
+ List<String> hnList = ae.getResponseHeaderNameList();
+ for(String headerName: hnList) {
+ buf.append(headerName);
+ buf.append(": ");
+ buf.append(ae.getResponseHeader(headerName));
+ buf.append(Layout.LINE_SEP);
+ }
+ buf.append(Layout.LINE_SEP);
+ buf.append(ae.getResponseContent());
+ buf.append(Layout.LINE_SEP);
+ return buf.toString();
+ }
+
+}
Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/pattern/ResponseContentConverter.java Thu Jan 18 17:05:40 2007
@@ -0,0 +1,21 @@
+package ch.qos.logback.access.pattern;
+
+import ch.qos.logback.access.spi.AccessEvent;
+
+/**
+ * This class is tied to the <code>requestContent</code> conversion word.
+ * <p>
+ * It has been removed from the {@link ch.qos.logback.access.PatternLayout} since
+ * it needs further testing before wide use.
+ * <p>
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ */
+public class ResponseContentConverter extends AccessConverter {
+
+ @Override
+ public String convert(AccessEvent accessEvent) {
+ return accessEvent.getResponseContent();
+ }
+
+}
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeFilter.java Thu Jan 18 17:05:40 2007
@@ -11,6 +11,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import ch.qos.logback.access.Constants;
+
public class TeeFilter implements Filter {
public void destroy() {
@@ -19,17 +21,33 @@
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
-
- if(request instanceof HttpServletRequest) {
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- request = new TeeHttpServletRequest(httpRequest);
- }
- if(response instanceof HttpServletResponse) {
- HttpServletResponse httpResponse = (HttpServletResponse) response;
- response = new TeeHttpServletResponse(httpResponse);
+
+ if (request instanceof HttpServletRequest) {
+ try {
+ TeeHttpServletRequest teeRequest = new TeeHttpServletRequest(
+ (HttpServletRequest) request);
+ TeeHttpServletResponse teeResponse = new TeeHttpServletResponse(
+ (HttpServletResponse) response);
+
+ //System.out.println("BEFORE TeeFilter. filterChain.doFilter()");
+ filterChain.doFilter(teeRequest, teeResponse);
+ //System.out.println("AFTER TeeFilter. filterChain.doFilter()");
+
+ teeResponse.finish();
+ // let the output contents be available for later use by
+ // logback-access-logging
+ teeRequest.setAttribute(Constants.LB_OUTPUT_BUFFER, teeResponse
+ .getOutputBuffer());
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw e;
+ } catch (ServletException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ } else {
+ filterChain.doFilter(request, response);
}
-
- filterChain.doFilter(request, response);
}
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java Thu Jan 18 17:05:40 2007
@@ -1,6 +1,7 @@
package ch.qos.logback.access.servlet;
import java.io.IOException;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
@@ -9,27 +10,46 @@
public class TeeHttpServletResponse extends HttpServletResponseWrapper {
- final TeeServletOutputStream teeServletOutputStream;
+ TeeServletOutputStream teeServletOutputStream;
PrintWriter writer;
- public TeeHttpServletResponse(HttpServletResponse httpServletResponse)
- throws IOException {
+ public TeeHttpServletResponse(HttpServletResponse httpServletResponse) {
super(httpServletResponse);
- ServletOutputStream underlyingStream = httpServletResponse
- .getOutputStream();
- teeServletOutputStream = new TeeServletOutputStream(underlyingStream);
+ //System.out.println("TeeHttpServletResponse.constructor called");
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
+ //System.out.println("TeeHttpServletResponse.getOutputStream() called");
+ if(teeServletOutputStream == null) {
+ teeServletOutputStream = new TeeServletOutputStream(
+ this.getResponse());
+ }
return teeServletOutputStream;
}
@Override
public PrintWriter getWriter() throws IOException {
- if (writer == null)
- writer = new PrintWriter(getOutputStream());
- return writer;
+ //System.out.println("TeeHttpServletResponse.getWriter() called");
+ if (this.writer == null) {
+ this.writer = new PrintWriter(new OutputStreamWriter(getOutputStream()), true);
+ }
+ return this.writer;
}
+ @Override
+ public void flushBuffer() {
+ //System.out.println("TeeHttpServletResponse.flushBuffer() called");
+ this.writer.flush();
+ }
+
+ byte[] getOutputBuffer() {
+ return teeServletOutputStream.getOutputBuffer();
+ }
+
+
+ void finish() throws IOException {
+ this.writer.close();
+ teeServletOutputStream.close();
+ }
}
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java Thu Jan 18 17:05:40 2007
@@ -4,44 +4,67 @@
import java.io.IOException;
import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
public class TeeServletOutputStream extends ServletOutputStream {
final ServletOutputStream underlyingStream;
final ByteArrayOutputStream baos;
- TeeServletOutputStream(ServletOutputStream underlyingStream) {
- this.underlyingStream = underlyingStream;
+
+ TeeServletOutputStream(ServletResponse httpServletResponse) throws IOException {
+ //System.out.println("TeeServletOutputStream.constructor() called");
+ this.underlyingStream = httpServletResponse.getOutputStream();
baos = new ByteArrayOutputStream();
}
+ byte[] getOutputBuffer() {
+ return baos.toByteArray();
+ }
+
@Override
public void write(int val) throws IOException {
+ //System.out.println("XXXXXXXXXXXWRITE TeeServletOutputStream.write(int) called");
underlyingStream.write(val);
baos.write(val);
}
@Override
public void write(byte[] byteArray) throws IOException {
- underlyingStream.write(byteArray);
- baos.write(byteArray);
+ //System.out.println("WRITE TeeServletOutputStream.write(byte[]) called");
+ write(byteArray, 0, byteArray.length);
}
@Override
public void write(byte byteArray[], int offset, int length)
throws IOException {
+ //System.out.println("WRITE TeeServletOutputStream.write(byte[], int, int) called");
+ //System.out.println(new String(byteArray, offset, length));
underlyingStream.write(byteArray, offset, length);
baos.write(byteArray, offset, length);
}
public void close() throws IOException {
+ // System.out.println("CLOSE TeeServletOutputStream.close() called");
+
+ // If the servlet accessing the stream is using a writer instead of
+ // an OutputStream, it will probably call os.close() begore calling
+ // writer.close. Thus, the undelying output stream will be called
+ // before the data sent to the writer could be flushed.
+ }
+
+ public void finish() throws IOException {
+ //System.out.println("FINISH TeeServletOutputStream.close() called");
+ flush();
underlyingStream.close();
baos.close();
}
public void flush() throws IOException {
+ //System.out.println("FLUSH TeeServletOutputStream.flush() called");
underlyingStream.flush();
baos.flush();
}
+
}
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 Thu Jan 18 17:05:40 2007
@@ -3,6 +3,7 @@
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.Cookie;
@@ -41,7 +42,8 @@
String method;
String serverName;
String requestContent;
-
+ String responseContent;
+
Map<String, String> requestHeaderMap;
Map<String, Object> requestParameterMap;
@@ -247,6 +249,10 @@
return serverAdapter.getResponseHeader(key);
}
+ public List<String> getResponseHeaderNameList() {
+ return serverAdapter.getResponseHeaderNameList();
+ }
+
/**
* Attributes are not serialized
*
@@ -333,6 +339,23 @@
return requestContent;
}
+ public String getResponseContent() {
+ if (responseContent != null) {
+ return responseContent;
+ }
+ // retreive the byte array previously placed by TeeFilter
+ byte[] outputBuffer = (byte[]) httpRequest.getAttribute(Constants.LB_OUTPUT_BUFFER);
+
+ if (outputBuffer != null) {
+ responseContent = new String(outputBuffer);
+ }
+
+ if (responseContent == null || responseContent.length() == 0) {
+ responseContent = EMPTY;
+ }
+
+ return responseContent;
+ }
public int getLocalPort() {
if (localPort == SENTINEL) {
if (httpRequest != null) {
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/ServerAdapter.java Thu Jan 18 17:05:40 2007
@@ -1,5 +1,7 @@
package ch.qos.logback.access.spi;
+import java.util.List;
+
/**
* An interface to access server-specific methods from
* the server-independent AccessEvent.
@@ -12,4 +14,6 @@
long getContentLength();
int getStatusCode();
String getResponseHeader(String key);
+ List<String> getResponseHeaderNameList();
+
}
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/tomcat/TomcatServerAdapter.java Thu Jan 18 17:05:40 2007
@@ -1,5 +1,8 @@
package ch.qos.logback.access.tomcat;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
@@ -7,11 +10,11 @@
/**
* A tomcat specific implementation of the {@link ServerAdapter} interface.
- *
+ *
* @author Sébastien Pennec
*/
public class TomcatServerAdapter implements ServerAdapter {
-
+
Request request;
Response response;
@@ -19,7 +22,7 @@
this.request = tomcatRequest;
this.response = tomcatResponse;
}
-
+
public long getContentLength() {
return response.getContentLength();
}
@@ -27,8 +30,16 @@
public int getStatusCode() {
return response.getStatus();
}
-
+
public String getResponseHeader(String key) {
return response.getHeader(key);
}
+
+ public List<String> getResponseHeaderNameList() {
+ List<String> hnList = new ArrayList<String>();
+ for (String name : response.getHeaderNames()) {
+ hnList.add(name);
+ }
+ return hnList;
+ }
}
Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyServerAdapter.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyServerAdapter.java (original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyServerAdapter.java Thu Jan 18 17:05:40 2007
@@ -1,5 +1,7 @@
package ch.qos.logback.access.pattern.helpers;
+import java.util.List;
+
import ch.qos.logback.access.spi.ServerAdapter;
public class DummyServerAdapter implements ServerAdapter {
@@ -24,4 +26,8 @@
return response.getHeader(key);
}
+ public List<String> getResponseHeaderNameList() {
+ return null;
+ }
+
}
Modified: logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java
==============================================================================
--- logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java (original)
+++ logback/trunk/logback-access/src/test/java/ch/qos/logback/access/pattern/helpers/DummyValuesAdapter.java Thu Jan 18 17:05:40 2007
@@ -1,5 +1,7 @@
package ch.qos.logback.access.pattern.helpers;
+import java.util.List;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -32,4 +34,8 @@
return 1;
}
+ public List<String> getResponseHeaderNameList() {
+ return null;
+ }
+
}
More information about the logback-dev
mailing list