2009-10-06 18 views
17

पर POST का लॉगिंग पेलोड मैं conf/server.xml को संपादित करके और org.apache.catalina.valves.AccessLogValve वाल्व के लिए प्रविष्टि को असम्बद्ध करके टॉमकैट में एक्सेस लॉगिंग सक्षम करने में कामयाब रहा हूं। मैं POST के पेलोड की सामग्री को डंप करने में सक्षम होना चाहता हूं। ऐसा लगता है कि पैटर्न में से कोई भी विकल्प ऐसा नहीं करेगा। क्या ऐसा करने के लिए कोई रास्ता बनाया गया है? क्या मैं AccessLogValve का उपयोग करता हूं?टॉमकैट

उत्तर

7

चूंकि POST पेलोड प्राप्त करने के लिए एक अंतर्निहित तरीके का कोई सुझाव नहीं था, इसलिए मैंने आगे बढ़कर एक कस्टम फ़िल्टर लिखा जो पेलोड की सामग्री को डंप करता है। विशेष रूप से:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
        FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest request = (HttpServletRequest) servletRequest; 
    LOG.debug("payload: " + requestWrapper.getRequestBody()); 

और web.xml:

<filter> 
    <filter-name>PayloadLoggingFilter</filter-name> 
    <filter-class>com.host.PayloadLoggingFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>PayloadLoggingFilter</filter-name> 
    <url-pattern>/resources/*</url-pattern> 
</filter-mapping> 
+7

'requestWrapper' कहां से आता है? या यह 'अनुरोध' वस्तु माना जाता है? – andho

+0

requestWrapper यहां उर्फ ​​MyRequestWrapper से आता है। यह काम करता हैं! http://natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html – goat

4

पोस्ट एक रूप (आवेदन/x-www-urlencoded), तो आप उपयोग कर सकते हैं ExtendedAccessLogValve है, तो

http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/valves/ExtendedAccessLogValve.html

आप इस तरह पैटर्न में अलग-अलग मापदंडों का चयन करने के लिए है,

x-P(param_name) 
+0

@ZZ: क्या हुआ अगर यह एक रूप नहीं है? –

+0

यदि यह कोई फॉर्म नहीं है, तो आप वास्तव में पोस्ट बॉडी लॉग नहीं कर सकते हैं। लॉग प्रारूप http://www.w3.org/TR/WD-logfile.html द्वारा परिभाषित किया गया है। यह फ़ाइल अपलोड के मामले में मनमाने ढंग से पोस्ट बॉडी का समर्थन नहीं करता है, जो द्विआधारी और विशाल हो सकता है। –

+1

दुर्भाग्यवश, यह मेरे लिए मामला नहीं है। मैं पैरामीटर के रूप में सामग्री पोस्ट नहीं कर रहा हूं, हालांकि पेलोड आकार कुछ केबी से अधिक नहीं होगा। – Tim

2
  1. अपने webapp web.xml जोड़ने में:

    <filter> 
        <filter-name>PayloadLoggingFilter</filter-name> 
        <filter-class>your.MyLogFilter</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>PayloadLoggingFilter</filter-name> 
        <url-pattern>/path/*</url-pattern> 
    </filter-mapping> 
    
  2. अपने फिल्टर बनाएं:

    import java.io.BufferedReader; 
    import java.io.ByteArrayInputStream; 
    import java.io.ByteArrayOutputStream; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.InputStreamReader; 
    import java.io.OutputStream; 
    import java.io.OutputStreamWriter; 
    import java.io.PrintWriter; 
    import java.util.Enumeration; 
    import java.util.HashMap; 
    import java.util.Locale; 
    import java.util.Map; 
    
    import javax.servlet.Filter; 
    import javax.servlet.FilterChain; 
    import javax.servlet.FilterConfig; 
    import javax.servlet.ServletException; 
    import javax.servlet.ServletInputStream; 
    import javax.servlet.ServletOutputStream; 
    import javax.servlet.ServletRequest; 
    import javax.servlet.ServletResponse; 
    import javax.servlet.http.Cookie; 
    import javax.servlet.http.HttpServletRequest; 
    import javax.servlet.http.HttpServletRequestWrapper; 
    import javax.servlet.http.HttpServletResponse; 
    
    import org.apache.commons.io.output.TeeOutputStream; 
    
    import com.liferay.portal.kernel.log.Log; 
    import com.liferay.portal.kernel.log.LogFactoryUtil; 
    import com.liferay.util.servlet.ServletInputStreamWrapper; 
    
    public class MyLogFilter implements Filter { 
    
        private static final Log logger = LogFactoryUtil.getLog(MyLogFilter.class); 
    
        @Override 
        public void init(FilterConfig filterConfig) throws ServletException { 
        } 
    
        @Override 
        public void doFilter(ServletRequest request, ServletResponse response, 
          FilterChain chain) throws IOException, ServletException { 
         try { 
          HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
          HttpServletResponse httpServletResponse = (HttpServletResponse) response; 
    
          Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest); 
          BufferedRequestWrapper bufferedReqest = new BufferedRequestWrapper(httpServletRequest); 
          BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(httpServletResponse); 
    
          chain.doFilter(bufferedReqest, bufferedResponse); 
    
          if(bufferedResponse.getContent()!=null){ //Response 
           final StringBuilder resMessage = new StringBuilder(); 
           resMessage.append(" [RESPONSE:") 
             .append(bufferedResponse.getContent()) 
             .append("]"); 
           logger.info(resMessage); 
          } 
          else{ //Request 
           final StringBuilder reqMessage = new StringBuilder(
             "REST Request - ").append("[HTTP METHOD:") 
             .append(httpServletRequest.getMethod()) 
             .append("] [PATH INFO:") 
             .append(httpServletRequest.getPathInfo()) 
             .append("] [REQUEST PARAMETERS:").append(requestMap) 
             .append("] [REQUEST BODY:") 
             .append(bufferedReqest.getRequestBody()) 
             .append("] [REMOTE ADDRESS:") 
             .append(httpServletRequest.getRemoteAddr()).append("]"); 
           logger.info(reqMessage); 
          } 
    
    
         } catch (Throwable a) { 
          logger.error(a); 
         } 
        } 
    
        private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) { 
         Map<String, String> typesafeRequestMap = new HashMap<String, String>(); 
         Enumeration<?> requestParamNames = request.getParameterNames(); 
         while (requestParamNames.hasMoreElements()) { 
          String requestParamName = (String) requestParamNames.nextElement(); 
          String requestParamValue = request.getParameter(requestParamName); 
          typesafeRequestMap.put(requestParamName, requestParamValue); 
         } 
         return typesafeRequestMap; 
        } 
    
        @Override 
        public void destroy() { 
        } 
    
        private static final class BufferedRequestWrapper extends 
          HttpServletRequestWrapper { 
    
         private ByteArrayInputStream bais = null; 
         private ByteArrayOutputStream baos = null; 
         private BufferedServletInputStream bsis = null; 
         private byte[] buffer = null; 
    
         public BufferedRequestWrapper(HttpServletRequest req) 
           throws IOException { 
          super(req); 
          // Read InputStream and store its content in a buffer. 
          InputStream is = req.getInputStream(); 
          this.baos = new ByteArrayOutputStream(); 
          byte buf[] = new byte[1024]; 
          int letti; 
          while ((letti = is.read(buf)) > 0) { 
           this.baos.write(buf, 0, letti); 
          } 
          this.buffer = this.baos.toByteArray(); 
         } 
    
         @Override 
         public ServletInputStream getInputStream() { 
          this.bais = new ByteArrayInputStream(this.buffer); 
          this.bsis = new BufferedServletInputStream(this.bais); 
    
          return this.bsis; 
         } 
    
         @Override 
         public BufferedReader getReader() throws IOException { 
          return new BufferedReader(new InputStreamReader(this.getInputStream())); 
         } 
    
         String getRequestBody() throws IOException { 
          BufferedReader reader = new BufferedReader(new InputStreamReader(
            this.getInputStream())); 
          String line = null; 
          StringBuilder inputBuffer = new StringBuilder(); 
          do { 
           line = reader.readLine(); 
           if (null != line) { 
            inputBuffer.append(line.trim()); 
           } 
          } while (line != null); 
          reader.close(); 
          return inputBuffer.toString().trim(); 
         } 
    
        } 
    
        private static final class BufferedServletInputStream extends 
          ServletInputStream { 
    
         private ByteArrayInputStream bais; 
    
         public BufferedServletInputStream(ByteArrayInputStream bais) { 
          this.bais = bais; 
         } 
    
         @Override 
         public int available() { 
          return this.bais.available(); 
         } 
    
         @Override 
         public int read() { 
          return this.bais.read(); 
         } 
    
         @Override 
         public int read(byte[] buf, int off, int len) { 
          return this.bais.read(buf, off, len); 
         } 
    
        } 
    
        public class TeeServletOutputStream extends ServletOutputStream { 
    
         private final TeeOutputStream targetStream; 
    
         public TeeServletOutputStream(OutputStream one, OutputStream two) { 
          targetStream = new TeeOutputStream(one, two); 
         } 
    
         @Override 
         public void write(int arg0) throws IOException { 
          this.targetStream.write(arg0); 
         } 
    
         public void flush() throws IOException { 
          super.flush(); 
          this.targetStream.flush(); 
         } 
    
         public void close() throws IOException { 
          super.close(); 
          this.targetStream.close(); 
         } 
        } 
    
        public class BufferedResponseWrapper implements HttpServletResponse { 
    
         HttpServletResponse original; 
         TeeServletOutputStream teeStream; 
         PrintWriter teeWriter; 
         ByteArrayOutputStream bos; 
    
         public BufferedResponseWrapper(HttpServletResponse response) { 
          original = response; 
         } 
    
         public String getContent() { 
          if(bos == null){ 
           return null; 
          } 
          return bos.toString(); 
         } 
    
         @Override 
         public PrintWriter getWriter() throws IOException { 
    
          if (this.teeWriter == null) { 
           this.teeWriter = new PrintWriter(new OutputStreamWriter(
             getOutputStream())); 
          } 
          return this.teeWriter; 
         } 
    
         @Override 
         public ServletOutputStream getOutputStream() throws IOException { 
    
          if (teeStream == null) { 
           bos = new ByteArrayOutputStream(); 
           teeStream = new TeeServletOutputStream(
             original.getOutputStream(), bos); 
          } 
          return teeStream; 
         } 
    
         @Override 
         public String getCharacterEncoding() { 
          return original.getCharacterEncoding(); 
         } 
    
         @Override 
         public String getContentType() { 
          return original.getContentType(); 
         } 
    
         @Override 
         public void setCharacterEncoding(String charset) { 
          original.setCharacterEncoding(charset); 
         } 
    
         @Override 
         public void setContentLength(int len) { 
          original.setContentLength(len); 
         } 
    
         @Override 
         public void setContentType(String type) { 
          original.setContentType(type); 
         } 
    
         @Override 
         public void setBufferSize(int size) { 
          original.setBufferSize(size); 
         } 
    
         @Override 
         public int getBufferSize() { 
          return original.getBufferSize(); 
         } 
    
         @Override 
         public void flushBuffer() throws IOException { 
          if (teeStream != null) { 
           teeStream.flush(); 
          } 
          if (this.teeWriter != null) { 
           this.teeWriter.flush(); 
          } 
         } 
    
         @Override 
         public void resetBuffer() { 
          original.resetBuffer(); 
         } 
    
         @Override 
         public boolean isCommitted() { 
          return original.isCommitted(); 
         } 
    
         @Override 
         public void reset() { 
          original.reset(); 
         } 
    
         @Override 
         public void setLocale(Locale loc) { 
          original.setLocale(loc); 
         } 
    
         @Override 
         public Locale getLocale() { 
          return original.getLocale(); 
         } 
    
         @Override 
         public void addCookie(Cookie cookie) { 
          original.addCookie(cookie); 
         } 
    
         @Override 
         public boolean containsHeader(String name) { 
          return original.containsHeader(name); 
         } 
    
         @Override 
         public String encodeURL(String url) { 
          return original.encodeURL(url); 
         } 
    
         @Override 
         public String encodeRedirectURL(String url) { 
          return original.encodeRedirectURL(url); 
         } 
    
         @SuppressWarnings("deprecation") 
         @Override 
         public String encodeUrl(String url) { 
          return original.encodeUrl(url); 
         } 
    
         @SuppressWarnings("deprecation") 
         @Override 
         public String encodeRedirectUrl(String url) { 
          return original.encodeRedirectUrl(url); 
         } 
    
         @Override 
         public void sendError(int sc, String msg) throws IOException { 
          original.sendError(sc, msg); 
         } 
    
         @Override 
         public void sendError(int sc) throws IOException { 
          original.sendError(sc); 
         } 
    
         @Override 
         public void sendRedirect(String location) throws IOException { 
          original.sendRedirect(location); 
         } 
    
         @Override 
         public void setDateHeader(String name, long date) { 
          original.setDateHeader(name, date); 
         } 
    
         @Override 
         public void addDateHeader(String name, long date) { 
          original.addDateHeader(name, date); 
         } 
    
         @Override 
         public void setHeader(String name, String value) { 
          original.setHeader(name, value); 
         } 
    
         @Override 
         public void addHeader(String name, String value) { 
          original.addHeader(name, value); 
         } 
    
         @Override 
         public void setIntHeader(String name, int value) { 
          original.setIntHeader(name, value); 
         } 
    
         @Override 
         public void addIntHeader(String name, int value) { 
          original.addIntHeader(name, value); 
         } 
    
         @Override 
         public void setStatus(int sc) { 
          original.setStatus(sc); 
         } 
    
         @SuppressWarnings("deprecation") 
         @Override 
         public void setStatus(int sc, String sm) { 
          original.setStatus(sc, sm); 
         } 
    
        } 
    
    }