001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest.client;
014
015import static org.apache.juneau.internal.StringUtils.*;
016
017import java.io.*;
018import java.util.logging.*;
019
020import org.apache.http.*;
021import org.apache.http.client.methods.*;
022import org.apache.http.util.*;
023
024/**
025 * Specialized interceptor for logging calls to a log file.
026 *
027 * <p>
028 * Causes a log entry to be created that shows all the request and response headers and content at the end of the
029 * request.
030 *
031 * <p>
032 * Use the {@link RestClientBuilder#logTo(Level, Logger)} and {@link RestCall#logTo(Level, Logger)} methods to create
033 * instances of this class.
034 */
035@Deprecated
036public class RestCallLogger extends RestCallInterceptor {
037
038   /**
039    * Default HTTP request logger.
040    * <p>
041    * Logs outgoing HTTP requests to the <c>org.apache.juneau.rest.client</c> logger at <jsf>WARNING</jsf> level.
042    */
043   public static final RestCallLogger DEFAULT = new RestCallLogger(Level.WARNING, Logger.getLogger("org.apache.juneau.rest.client"));
044
045   private Level level;
046   private Logger log;
047
048   /**
049    * Constructor.
050    *
051    * @param level The log level to log messages at.
052    * @param log The logger to log to.
053    */
054   protected RestCallLogger(Level level, Logger log) {
055      this.level = level;
056      this.log = log;
057   }
058
059   @Override /* RestCallInterceptor */
060   public void onInit(RestCall restCall) {
061      if (log.isLoggable(level))
062         restCall.captureResponse();
063   }
064
065   @Override /* RestCallInterceptor */
066   public void onConnect(RestCall restCall, int statusCode, HttpRequest req, HttpResponse res) {
067      // Do nothing.
068   }
069
070   @Override /* RestCallInterceptor */
071   public void onRetry(RestCall restCall, int statusCode, HttpRequest req, HttpResponse res, Exception ex) {
072      if (log.isLoggable(level)) {
073         if (ex == null)
074            log.log(level, format("Call to {0} returned {1}.  Will retry.", req.getRequestLine().getUri(), statusCode));
075         else
076            log.log(level, format("Call to {0} caused exception {1}.  Will retry.", req.getRequestLine().getUri(), ex.getLocalizedMessage()), ex);
077      }
078   }
079
080   @Override /* RestCallInterceptor */
081   public void onClose(RestCall restCall) throws RestCallException {
082      try {
083         if (log.isLoggable(level)) {
084            String output = restCall.getCapturedResponse();
085            StringBuilder sb = new StringBuilder();
086            HttpUriRequest req = restCall.getRequest();
087            HttpResponse res = restCall.getResponse();
088            if (req != null) {
089               sb.append("\n=== HTTP Call (outgoing) =======================================================");
090
091               sb.append("\n=== REQUEST ===\n").append(req);
092               sb.append("\n---request headers---");
093               for (Header h : req.getAllHeaders())
094                  sb.append("\n\t").append(h);
095               if (req instanceof HttpEntityEnclosingRequestBase) {
096                  sb.append("\n---request entity---");
097                  HttpEntityEnclosingRequestBase req2 = (HttpEntityEnclosingRequestBase)req;
098                  HttpEntity e = req2.getEntity();
099                  if (e == null)
100                     sb.append("\nEntity is null");
101                  else {
102                     if (e.getContentType() != null)
103                        sb.append("\n").append(e.getContentType());
104                     if (e.getContentEncoding() != null)
105                        sb.append("\n").append(e.getContentEncoding());
106                     if (e.isRepeatable()) {
107                        try {
108                           sb.append("\n---request content---\n").append(EntityUtils.toString(e));
109                        } catch (Exception ex) {
110                           throw new RuntimeException(ex);
111                        }
112                     }
113                  }
114               }
115            }
116            if (res != null) {
117               sb.append("\n=== RESPONSE ===\n").append(res.getStatusLine());
118               sb.append("\n---response headers---");
119               for (Header h : res.getAllHeaders())
120                  sb.append("\n\t").append(h);
121               sb.append("\n---response content---\n").append(output);
122               sb.append("\n=== END ========================================================================");
123            }
124            log.log(level, sb.toString());
125         }
126      } catch (IOException e) {
127         log.log(Level.SEVERE, e.getLocalizedMessage(), e);
128      }
129   }
130}