knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmin...@apache.org
Subject knox git commit: KNOX-597: Improve diagnostic logging of HTTP traffic
Date Thu, 10 Sep 2015 21:38:07 GMT
Repository: knox
Updated Branches:
  refs/heads/master c59bfeb3a -> d88a2878c


KNOX-597: Improve diagnostic logging of HTTP traffic


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/d88a2878
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/d88a2878
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/d88a2878

Branch: refs/heads/master
Commit: d88a2878c182d484f388519134b817c501354708
Parents: c59bfeb
Author: Kevin Minder <kevin.minder@hortonworks.com>
Authored: Thu Sep 10 17:38:00 2015 -0400
Committer: Kevin Minder <kevin.minder@hortonworks.com>
Committed: Thu Sep 10 17:38:00 2015 -0400

----------------------------------------------------------------------
 .../home/conf/gateway-log4j.properties          | 31 ++++++++
 .../apache/hadoop/gateway/GatewayFilter.java    | 13 ++-
 .../apache/hadoop/gateway/GatewayServer.java    | 27 ++++++-
 .../gateway/filter/CorrelationHandler.java      | 45 +++++++++++
 .../hadoop/gateway/filter/TraceFilter.java      | 37 ---------
 .../hadoop/gateway/trace/AccessHandler.java     | 53 +++++++++++++
 .../hadoop/gateway/trace/ErrorHandler.java      | 42 ++++++++++
 .../hadoop/gateway/trace/TraceHandler.java      | 54 +++++++++++++
 .../apache/hadoop/gateway/trace/TraceInput.java | 70 +++++++++++++++++
 .../hadoop/gateway/trace/TraceOutput.java       | 75 ++++++++++++++++++
 .../hadoop/gateway/trace/TraceRequest.java      | 83 ++++++++++++++++++++
 .../hadoop/gateway/trace/TraceResponse.java     | 77 ++++++++++++++++++
 .../apache/hadoop/gateway/trace/TraceUtil.java  | 72 +++++++++++++++++
 13 files changed, 636 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-release/home/conf/gateway-log4j.properties
----------------------------------------------------------------------
diff --git a/gateway-release/home/conf/gateway-log4j.properties b/gateway-release/home/conf/gateway-log4j.properties
index 3ad09a9..67d8e9d 100644
--- a/gateway-release/home/conf/gateway-log4j.properties
+++ b/gateway-release/home/conf/gateway-log4j.properties
@@ -47,3 +47,34 @@ log4j.appender.auditfile.Append = true
 log4j.appender.auditfile.DatePattern = '.'yyyy-MM-dd
 log4j.appender.auditfile.layout = org.apache.hadoop.gateway.audit.log4j.layout.AuditLayout
 
+#log4j.logger.org.apache.hadoop.gateway.access=TRACE,httpaccess
+#log4j.additivity.org.apache.hadoop.gateway.access=false
+
+#log4j.logger.org.apache.hadoop.gateway.http=TRACE,httpserver
+#log4j.additivity.org.apache.hadoop.gateway.http=false
+##log4j.logger.org.apache.hadoop.gateway.http.request.headers=OFF
+##log4j.logger.org.apache.hadoop.gateway.http.response.headers=OFF
+##log4j.logger.org.apache.hadoop.gateway.http.request.body=OFF
+##log4j.logger.org.apache.hadoop.gateway.http.response.body=OFF
+
+#log4j.logger.org.apache.http.wire=DEBUG,httpclient
+#log4j.additivity.org.apache.http.wire=false
+
+#log4j.appender.httpaccess=org.apache.log4j.DailyRollingFileAppender
+#log4j.appender.httpaccess.File=${app.log.dir}/${launcher.name}-http-access.log
+#log4j.appender.httpaccess.DatePattern=.yyyy-MM-dd
+#log4j.appender.httpaccess.layout=org.apache.log4j.PatternLayout
+#log4j.appender.httpaccess.layout.ConversionPattern=%d{ISO8601}|%t|%m%n
+
+#log4j.appender.httpserver=org.apache.log4j.DailyRollingFileAppender
+#log4j.appender.httpserver.File=${app.log.dir}/${launcher.name}-http-server.log
+#log4j.appender.httpserver.DatePattern=.yyyy-MM-dd
+#log4j.appender.httpserver.layout=org.apache.log4j.PatternLayout
+#log4j.appender.httpserver.layout.ConversionPattern=%d{ISO8601}|%t|%m%n
+
+#log4j.appender.httpclient=org.apache.log4j.DailyRollingFileAppender
+#log4j.appender.httpclient.File=${app.log.dir}/${launcher.name}-http-client.log
+#log4j.appender.httpclient.DatePattern=.yyyy-MM-dd
+#log4j.appender.httpclient.layout=org.apache.log4j.PatternLayout
+#log4j.appender.httpclient.layout.ConversionPattern=%d{ISO8601}|%t|%m%n
+

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
index df72885..3ff0abd 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayFilter.java
@@ -189,10 +189,17 @@ public class GatewayFilter implements Filter {
     Holder holder = new Holder( path, name, clazz, params, resourceRole );
     addHolder( holder );
   }
-  
+
+  // Now creating the correlation context only if required since it may be created upstream
in the CorrelationHandler.
   private void assignCorrelationRequestId() {
-    CorrelationContext correlationContext = CorrelationServiceFactory.getCorrelationService().createContext();
-    correlationContext.setRequestId( UUID.randomUUID().toString() );
+    CorrelationContext correlationContext = CorrelationServiceFactory.getCorrelationService().getContext();
+    if( correlationContext == null ) {
+      correlationContext = CorrelationServiceFactory.getCorrelationService().createContext();
+    }
+    String requestId = correlationContext.getRequestId();
+    if( requestId == null ) {
+      correlationContext.setRequestId( UUID.randomUUID().toString() );
+    }
   }
 
   private class Chain implements FilterChain {

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
index b6e44c3..4e1f963 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayServer.java
@@ -30,21 +30,27 @@ import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
 import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.hadoop.gateway.config.impl.GatewayConfigImpl;
 import org.apache.hadoop.gateway.deploy.DeploymentFactory;
+import org.apache.hadoop.gateway.filter.CorrelationHandler;
 import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
 import org.apache.hadoop.gateway.i18n.resources.ResourcesFactory;
 import org.apache.hadoop.gateway.services.GatewayServices;
 import org.apache.hadoop.gateway.services.ServiceLifecycleException;
-import org.apache.hadoop.gateway.services.topology.TopologyService;
 import org.apache.hadoop.gateway.services.registry.ServiceRegistry;
 import org.apache.hadoop.gateway.services.security.SSLService;
+import org.apache.hadoop.gateway.services.topology.TopologyService;
 import org.apache.hadoop.gateway.topology.Topology;
 import org.apache.hadoop.gateway.topology.TopologyEvent;
 import org.apache.hadoop.gateway.topology.TopologyListener;
+import org.apache.hadoop.gateway.trace.AccessHandler;
+import org.apache.hadoop.gateway.trace.ErrorHandler;
+import org.apache.hadoop.gateway.trace.TraceHandler;
 import org.apache.log4j.PropertyConfigurator;
 import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
-import org.eclipse.jetty.server.handler.ErrorHandler;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.RequestLogHandler;
 import org.eclipse.jetty.webapp.WebAppContext;
 import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -306,7 +312,21 @@ public class GatewayServer {
       connector.setPort(address.getPort());
       jetty.addConnector(connector);
     }
-    jetty.setHandler( contexts );
+
+    HandlerCollection handlers = new HandlerCollection();
+    RequestLogHandler logHandler = new RequestLogHandler();
+    logHandler.setRequestLog( new AccessHandler() );
+
+    TraceHandler traceHandler = new TraceHandler();
+    traceHandler.setHandler( contexts );
+    traceHandler.setTracedBodyFilter( System.getProperty( "org.apache.knox.gateway.trace.body.status.filter"
) );
+
+    CorrelationHandler correlationHandler = new CorrelationHandler();
+    correlationHandler.setHandler( traceHandler );
+
+    handlers.setHandlers( new Handler[]{ correlationHandler, logHandler } );
+
+    jetty.setHandler( handlers );
     try {
     jetty.start();
     }
@@ -357,6 +377,7 @@ public class GatewayServer {
     String warPath = warFile.getAbsolutePath();
     errorHandler = new ErrorHandler();
     errorHandler.setShowStacks(false);
+    errorHandler.setTracedBodyFilter( System.getProperty( "org.apache.knox.gateway.trace.body.status.filter"
) );
     WebAppContext context = new WebAppContext();
     context.setDefaultsDescriptor( null );
     if (!name.equals("_default")) {

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/CorrelationHandler.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/CorrelationHandler.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/CorrelationHandler.java
new file mode 100644
index 0000000..47f9723
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/CorrelationHandler.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.filter;
+
+import org.apache.hadoop.gateway.audit.api.CorrelationContext;
+import org.apache.hadoop.gateway.audit.api.CorrelationServiceFactory;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.UUID;
+
+public class CorrelationHandler extends HandlerWrapper {
+
+  @Override
+  public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse
response )
+      throws IOException, ServletException {
+    CorrelationContext correlationContext = CorrelationServiceFactory.getCorrelationService().createContext();
+    correlationContext.setRequestId( UUID.randomUUID().toString() );
+    try {
+      super.handle( target, baseRequest, request, response );
+    } finally {
+      correlationContext.destroy();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/TraceFilter.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/TraceFilter.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/TraceFilter.java
deleted file mode 100644
index 5ea35a5..0000000
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/filter/TraceFilter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.hadoop.gateway.filter;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- *
- */
-//TODO: Implement the trace filter.
-public class TraceFilter extends AbstractGatewayFilter {
-
-  @Override
-  public void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain
chain ) throws IOException, ServletException {
-    chain.doFilter( request, response );
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/AccessHandler.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/AccessHandler.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/AccessHandler.java
new file mode 100644
index 0000000..fe2e174
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/AccessHandler.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+
+public class AccessHandler extends AbstractLifeCycle implements RequestLog {
+
+  private static Logger log = Logger.getLogger( "org.apache.hadoop.gateway.access" );
+
+  @Override
+  public void log( Request request, Response response ) {
+    if( log.isTraceEnabled() ) {
+      StringBuilder sb = new StringBuilder();
+      TraceUtil.appendCorrelationContext( sb );
+      sb.append( "|" );
+      sb.append( request.getRemoteAddr() );
+      sb.append( "|" );
+      sb.append( request.getMethod() );
+      sb.append( "|" );
+      sb.append( request.getUri().toString() );
+      sb.append( "|" );
+      sb.append( request.getContentLength() );
+      sb.append( "|" );
+      sb.append( response.getStatus() );
+      sb.append( "|" );
+      sb.append( response.getContentCount() );
+      sb.append( "|" );
+      sb.append( System.currentTimeMillis() - request.getTimeStamp() );
+      log.trace( sb );
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/ErrorHandler.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/ErrorHandler.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/ErrorHandler.java
new file mode 100644
index 0000000..a1fb87b
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/ErrorHandler.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.eclipse.jetty.server.Request;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Set;
+
+public class ErrorHandler extends org.eclipse.jetty.server.handler.ErrorHandler {
+
+  private Set<Integer> bodyFilter;
+
+  public void setTracedBodyFilter( String s ) {
+    bodyFilter = TraceUtil.parseIntegerSet( s );
+  }
+
+  @Override
+  public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse
response )
+      throws IOException {
+    HttpServletResponse traceResponse = new TraceResponse( response, bodyFilter );
+    super.handle( target, baseRequest, request, traceResponse );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceHandler.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceHandler.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceHandler.java
new file mode 100644
index 0000000..7f49979
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceHandler.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.HandlerWrapper;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Set;
+
+public class TraceHandler extends HandlerWrapper {
+
+  static String HTTP_LOGGER = "org.apache.hadoop.gateway.http";
+  static String HTTP_REQUEST_LOGGER = HTTP_LOGGER + ".request";
+  static String HTTP_REQUEST_HEADER_LOGGER = HTTP_REQUEST_LOGGER + ".headers";
+  static String HTTP_REQUEST_BODY_LOGGER = HTTP_REQUEST_LOGGER + ".body";
+
+  static String HTTP_RESPONSE_LOGGER = HTTP_LOGGER + ".response";
+  static String HTTP_RESPONSE_HEADER_LOGGER = HTTP_RESPONSE_LOGGER + ".headers";
+  static String HTTP_RESPONSE_BODY_LOGGER = HTTP_RESPONSE_LOGGER + ".body";
+
+  private Set<Integer> bodyFilter;
+
+  public void setTracedBodyFilter( String s ) {
+    bodyFilter = TraceUtil.parseIntegerSet( s );
+  }
+
+  @Override
+  public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse
response )
+      throws IOException, ServletException {
+    HttpServletRequest newRequest = new TraceRequest( request );
+    HttpServletResponse newResponse = new TraceResponse( response, bodyFilter );
+    super.handle( target, baseRequest, newRequest, newResponse );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceInput.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceInput.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceInput.java
new file mode 100644
index 0000000..3d10538
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceInput.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.apache.log4j.Logger;
+
+import javax.servlet.ServletInputStream;
+import java.io.IOException;
+
+class TraceInput extends ServletInputStream {
+
+  private static Logger log = Logger.getLogger( TraceHandler.HTTP_REQUEST_LOGGER );
+  private static Logger bodyLog = Logger.getLogger( TraceHandler.HTTP_REQUEST_BODY_LOGGER
);
+
+  private ServletInputStream delegate;
+
+  private static final int BUFFER_LIMIT = 1024;
+  private StringBuilder buffer = new StringBuilder( BUFFER_LIMIT );
+
+  TraceInput( ServletInputStream delegate ) {
+    this.delegate = delegate;
+  }
+
+  @Override
+  public int read() throws IOException {
+    int b = delegate.read();
+    if( b >= 0 ) {
+      buffer.append( (char)b );
+      if( buffer.length() == BUFFER_LIMIT || delegate.available() == 0 ) {
+        traceBody();
+      }
+    }
+    return b;
+  }
+
+  @Override
+  public void close() throws IOException {
+    traceBody();
+    delegate.close();
+  }
+
+  private synchronized void traceBody() {
+    if( buffer.length() > 0 ) {
+      String body = buffer.toString();
+      buffer.setLength( 0 );
+      StringBuilder sb = new StringBuilder();
+      TraceUtil.appendCorrelationContext( sb );
+      sb.append( String.format( "|RequestBody[%d]\n\t%s", body.length(), body ) );
+      if( bodyLog.isTraceEnabled() ) {
+        log.trace( sb.toString() );
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceOutput.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceOutput.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceOutput.java
new file mode 100644
index 0000000..cec59b3
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceOutput.java
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.apache.log4j.Logger;
+
+import javax.servlet.ServletOutputStream;
+import java.io.IOException;
+
+class TraceOutput extends ServletOutputStream {
+
+  private static Logger log = Logger.getLogger( TraceHandler.HTTP_RESPONSE_LOGGER );
+  private static Logger bodyLog = Logger.getLogger( TraceHandler.HTTP_RESPONSE_BODY_LOGGER
);
+
+  private ServletOutputStream delegate;
+
+  private static final int BUFFER_LIMIT = 1024;
+  private StringBuilder buffer = new StringBuilder( BUFFER_LIMIT );
+
+  TraceOutput( ServletOutputStream delegate ) {
+    this.delegate = delegate;
+  }
+
+  @Override
+  public synchronized void write( int b ) throws IOException {
+    if( b >= 0 ) {
+      buffer.append( (char)b );
+      if( buffer.length() == BUFFER_LIMIT ) {
+        traceBody();
+      }
+    }
+    delegate.write( b );
+  }
+
+  @Override
+  public void flush() throws IOException {
+    traceBody();
+    delegate.flush();
+  }
+
+  @Override
+  public void close() throws IOException {
+    traceBody();
+    delegate.close();
+  }
+
+  private synchronized void traceBody() {
+    if( buffer.length() > 0 ) {
+      String body = buffer.toString();
+      buffer.setLength( 0 );
+      StringBuilder sb = new StringBuilder();
+      TraceUtil.appendCorrelationContext( sb );
+      sb.append( String.format( "|ResponseBody[%d]\n\t%s", body.length(), body ) );
+      if( bodyLog.isTraceEnabled() ) {
+        log.trace( sb.toString() );
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceRequest.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceRequest.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceRequest.java
new file mode 100644
index 0000000..3211c50
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceRequest.java
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.apache.log4j.Logger;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.IOException;
+import java.util.Enumeration;
+
+class TraceRequest extends HttpServletRequestWrapper {
+
+  private static Logger log = Logger.getLogger( TraceHandler.HTTP_REQUEST_LOGGER );
+  private static Logger headLog = Logger.getLogger( TraceHandler.HTTP_REQUEST_HEADER_LOGGER
);
+
+  private ServletInputStream input;
+
+  TraceRequest( HttpServletRequest request ) {
+    super( request );
+    if( log.isTraceEnabled() ) {
+      traceRequestDetails();
+    }
+  }
+
+  public synchronized ServletInputStream getInputStream() throws IOException {
+    if( log.isTraceEnabled() ) {
+      if( input == null ) {
+        input = new TraceInput( super.getInputStream() );
+      }
+      return input;
+    } else {
+      return super.getInputStream();
+    }
+  }
+
+  private void traceRequestDetails() {
+    StringBuilder sb = new StringBuilder();
+    TraceUtil.appendCorrelationContext( sb );
+    sb.append( "|Request=" );
+    sb.append( getMethod() );
+    sb.append( " " );
+    sb.append( getRequestURI() );
+    String qs = getQueryString();
+    if( qs != null ) {
+      sb.append( "?" );
+      sb.append( qs );
+    }
+    appendHeaders( sb );
+    log.trace( sb.toString() );
+  }
+
+  private void appendHeaders( StringBuilder sb ) {
+    if( headLog.isTraceEnabled() ) {
+      Enumeration<String> names = getHeaderNames();
+      while( names.hasMoreElements() ) {
+        String name = names.nextElement();
+        Enumeration<String> values = getHeaders( name );
+        while( values.hasMoreElements() ) {
+          String value = values.nextElement();
+          sb.append( String.format( "\n\tHeader[%s]=%s", name, value ) );
+        }
+      }
+    }
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceResponse.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceResponse.java
b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceResponse.java
new file mode 100644
index 0000000..632fa86
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceResponse.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.apache.log4j.Logger;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
+
+class TraceResponse extends HttpServletResponseWrapper {
+
+  private static Logger log = Logger.getLogger( TraceHandler.HTTP_RESPONSE_LOGGER );
+  private static Logger headLog = Logger.getLogger( TraceHandler.HTTP_RESPONSE_HEADER_LOGGER
);
+
+  private ServletOutputStream output;
+  private Set<Integer> filter;
+
+
+  TraceResponse( HttpServletResponse response, Set<Integer> filter ) {
+    super( response );
+    this.filter = filter;
+  }
+
+  public synchronized ServletOutputStream getOutputStream() throws IOException {
+    if( log.isTraceEnabled() ) {
+      traceResponseDetails();
+      if( output == null && ( filter == null || filter.isEmpty() || filter.contains(
getStatus() ) ) ) {
+        output = new TraceOutput( super.getOutputStream() );
+      }
+      return output;
+    } else {
+      return super.getOutputStream();
+    }
+  }
+
+  private void traceResponseDetails() {
+    StringBuilder sb = new StringBuilder();
+    TraceUtil.appendCorrelationContext( sb );
+    sb.append( "|Response=" );
+    sb.append( getStatus() );
+    appendHeaders( sb );
+    log.trace( sb.toString() );
+  }
+
+  private void appendHeaders( StringBuilder sb ) {
+    if( headLog.isTraceEnabled() ) {
+      Collection<String> names = getHeaderNames();
+      for( String name : names ) {
+        for( String value : getHeaders( name ) ) {
+          sb.append( String.format( "\n\tHeader[%s]=%s", name, value ) );
+        }
+      }
+    }
+  }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/knox/blob/d88a2878/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceUtil.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceUtil.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceUtil.java
new file mode 100644
index 0000000..59e4064
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/trace/TraceUtil.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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 org.apache.hadoop.gateway.trace;
+
+import org.apache.hadoop.gateway.audit.api.CorrelationContext;
+import org.apache.hadoop.gateway.audit.api.CorrelationService;
+import org.apache.hadoop.gateway.audit.api.CorrelationServiceFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+public class TraceUtil {
+
+  private static CorrelationService cs = CorrelationServiceFactory.getCorrelationService();
+
+  final static void appendCorrelationContext( final StringBuilder sb ) {
+    CorrelationContext cc = cs.getContext();
+    if( cc == null ) {
+      sb.append( "||" );
+    } else {
+      append( sb, cc.getRootRequestId() );
+      sb.append( "|" );
+      append( sb, cc.getParentRequestId() );
+      sb.append( "|" );
+      append( sb, cc.getRequestId() );
+    }
+  }
+
+  private static final void append( final StringBuilder sb, final String s ) {
+    if( s != null ) {
+      sb.append( s );
+    }
+  }
+
+  final static Set<Integer> parseIntegerSet( String str ) {
+    Set<Integer> set = new HashSet<Integer>();
+    if( str != null && !str.trim().isEmpty() ) {
+      StringTokenizer parser = new StringTokenizer( str.trim(), ",", false );
+      while( parser.hasMoreTokens() ) {
+        addParsedIntegerToSet( set, parser.nextToken() );
+      }
+    }
+    return set;
+  }
+
+  private static final void addParsedIntegerToSet( Set<Integer> set, String str ) {
+    if( str != null && !str.trim().isEmpty() ) {
+      try {
+        set.add( new Integer( str.trim() ) );
+      } catch( NumberFormatException e ) {
+        // Ignore it.
+      }
+    }
+  }
+
+}


Mime
View raw message