2017-07-14 1 views
0

FullRequestDumperFilterは、Javaクラス拡張子RequestDumperFilter - part of Tomcatとして作成されました。Tomcat:オーバーライドされていないバリアントで出力を混合する@Overridenログフィルタ

FullRequestDumperFilterは、本文を含む完全なHTTPリクエストとレスポンスを記録する私のカスタムのTomcatログフィルタですが、RequestDumperFilterはメッセージヘッダのみを記録します。部: - - ヘッダ(RequestDumperFilter

  • custom-dumper.logヘッダとボディ(FullRequestDumperFilter
  • 問題

    • request-dumper.log

      においてlogging.properties 2ログファイルは、所望の出力を定義しています出力の間違ったログファイルに書き込まれると、実際の出力:

      • request-dumper.log - 二度書かヘッダ(RequestDumperFilter
      • custom-dumper.log - だけ体(FullRequestDumperFilter@Overrideの内容)

      これはおそらくRequestDumperFilterから継承する、FullRequestDumperFilterによって引き起こされ、そのcustom-dumper.logの代わりにrequest-dumper.logに出力するように設定されています。

      ログフィルタを正しいログファイルに出力する方法を教えてください。

      ${CATALINA_HOME}/logging.properties

      handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler, 1request-dumper.org.apache.juli.FileHandler, 1custom-dumper.org.apache.juli.FileHandler 
      
      ... 
      
      1request-dumper.org.apache.juli.FileHandler.level = FINEST 
      1request-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 
      1request-dumper.org.apache.juli.FileHandler.prefix = request-dumper. 
      1request-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter 
      org.apache.catalina.filters.RequestDumperFilter.level = FINEST 
      org.apache.catalina.filters.RequestDumperFilter.handlers = \ 
          1request-dumper.org.apache.juli.FileHandler 
      
      1custom-dumper.org.apache.juli.FileHandler.level = FINEST 
      1custom-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 
      1custom-dumper.org.apache.juli.FileHandler.prefix = custom-dumper. 
      1custom-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter 
      com.example.FullRequestDumperFilter.level = FINEST 
      com.example.FullRequestDumperFilter.handlers = \ 
          1custom-dumper.org.apache.juli.FileHandler 
      

      FullRequestDumperFilter.java:ここ

      package com.example; 
      
      import org.apache.catalina.filters.RequestDumperFilter; 
      import org.apache.commons.io.output.TeeOutputStream; 
      
      import javax.servlet.*; 
      import javax.servlet.http.Cookie; 
      import javax.servlet.http.HttpServletRequest; 
      import javax.servlet.http.HttpServletRequestWrapper; 
      import javax.servlet.http.HttpServletResponse; 
      import java.io.*; 
      import java.util.*; 
      
      import org.apache.juli.logging.Log; 
      import org.apache.juli.logging.LogFactory; 
      
      public class FullRequestDumperFilter extends RequestDumperFilter { 
      
          /** 
          * The logger for this class. 
          */ 
          private static final Log log = LogFactory.getLog(FullRequestDumperFilter.class); 
      
          /** 
          * Log the interesting request parameters, invoke the next Filter in the 
          * sequence, and log the interesting response parameters. 
          * 
          * @param request The servlet request to be processed 
          * @param response The servlet response to be created 
          * @param chain The filter chain being processed 
          * @throws IOException  if an input/output error occurs 
          * @throws ServletException if a servlet error occurs 
          */ 
          @Override 
          public void doFilter(ServletRequest request, ServletResponse response, 
               FilterChain chain) throws IOException, ServletException { 
           super.doFilter(request, response, chain); 
      
           try { 
            HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
            HttpServletResponse httpServletResponse = (HttpServletResponse) response; 
            BufferedRequestWrapper bufferedReqest = new BufferedRequestWrapper(httpServletRequest); 
            BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(httpServletResponse); 
            doLog("  requestBody\n", bufferedReqest.getRequestBody()); 
            chain.doFilter(bufferedReqest, bufferedResponse); 
            doLog("  responseBody\n", bufferedResponse.getContent()); 
           } catch (Throwable a) { 
            log.error(a); 
           } 
          } 
      
          private void doLog(String attribute, String value) { 
           StringBuilder sb = new StringBuilder(80); 
           sb.append(Thread.currentThread().getName()); 
           sb.append(' '); 
           sb.append(attribute); 
           sb.append('='); 
           sb.append(value); 
           log.info(sb.toString()); 
          } 
      
          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; 
           } 
      
      
           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 tee; 
           ByteArrayOutputStream bos; 
      
           public BufferedResponseWrapper(HttpServletResponse response) { 
            original = response; 
           } 
      
           public String getContent() { 
            return bos.toString(); 
           } 
      
           public PrintWriter getWriter() throws IOException { 
            return original.getWriter(); 
           } 
      
           public ServletOutputStream getOutputStream() throws IOException { 
            if (tee == null) { 
             bos = new ByteArrayOutputStream(); 
             tee = new TeeServletOutputStream(original.getOutputStream(), bos); 
            } 
            return tee; 
      
           } 
      
           @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 { 
            tee.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); 
           } 
      
           @Override 
           public int getStatus() { 
            return original.getStatus(); 
           } 
      
           @Override 
           public String getHeader(String s) { 
            return original.getHeader(s); 
           } 
      
           @Override 
           public Collection<String> getHeaders(String s) { 
            return original.getHeaders(s); 
           } 
      
           @Override 
           public Collection<String> getHeaderNames() { 
            return original.getHeaderNames(); 
           } 
      
          } 
      } 
      
    +0

    あなたはので、両方のフィルタはリクエストごとに呼び出され、 'RequestDumperFilter'を拡張し、Webプロジェクトを設定しないで試してみましたが? – jmehrens

    +0

    そのアプローチは以下の私の答えに似ています。2つのフィルタを独立してフィルタチェーンに追加することにより、両方が呼び出されます。何らかの理由で既存のフィルタを拡張しても機能しません。 –

    答えて

    0

    が受け入れ可能な解決策ですが、私はlogging.properties内のフィルタのいずれかを削除して1custom-dumper.org.apache.juli.FileHandlerに両方のフィルタのためのハンドラを設定します。

    しかし、解決策はまだ欠点があります。

    • が一つだけのログファイルが存在することができ
    • ハンドラプロパティは、技術的には同じフィルタ用の二回を設定する必要があり
    • 理想的にはそこだろうカスタムフィルタのさまざまな出力を異なるログファイル(本体の有無にかかわらず)に格納できるログレベル(INFO、FINESTなど)であること

    ${CATALINA_HOME}/logging.properties

    1custom-dumper.org.apache.juli.FileHandler.level = FINEST 
    1custom-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 
    1custom-dumper.org.apache.juli.FileHandler.prefix = custom-dumper. 
    1custom-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter 
    com.example.FullRequestDumperFilter.level = FINEST 
    com.example.FullRequestDumperFilter.handlers = \ 
        1custom-dumper.org.apache.juli.FileHandler 
    org.apache.catalina.filters.RequestDumperFilter.level = FINEST 
    org.apache.catalina.filters.RequestDumperFilter.handlers = \ 
        1custom-dumper.org.apache.juli.FileHandler 
    
    関連する問題