func (rt *RoundTripper) logResponse(original io.ReadCloser, contentType string) (io.ReadCloser, error) {
	var bs bytes.Buffer
	defer original.Close()
	if _, err := io.Copy(&bs, original); err != nil {
		return nil, err
	}
	rt.log().ResponsePrintf("Body: %s", bs.String())
	return ioutil.NopCloser(bytes.NewReader(bs.Bytes())), nil
}
logResponse will log the HTTP Response details.
If the body is JSON, it will attempt to be pretty-formatted.
package client
import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)
type Logger interface {
	RequestPrintf(format string, args ...interface{})
	ResponsePrintf(format string, args ...interface{})
}
type logger struct {
	RequestID string
}
func (lg logger) RequestPrintf(format string, args ...interface{}) {
	for _, v := range strings.Split(fmt.Sprintf(format, args...), "\n") {
		log.Printf("-> %s", v)
	}
}
func (lg logger) ResponsePrintf(format string, args ...interface{}) {
	for _, v := range strings.Split(fmt.Sprintf(format, args...), "\n") {
		log.Printf("<- %s", v)
	}
}
type noopLogger struct{}
func (noopLogger) RequestPrintf(format string, args ...interface{}) {}
func (noopLogger) ResponsePrintf(format string, args ...interface{}) {}
type RoundTripper struct {
	Rt http.RoundTripper
	Logger Logger
}
func (rt *RoundTripper) formatHeaders(headers http.Header, separator string) string {
	result := make([]string, len(headers))
	i := 0
	for header, data := range headers {
		result[i] = fmt.Sprintf("%s: %s", header, strings.Join(data, " "))
		i++
	}
	return strings.Join(result, separator)
}
func (rt *RoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
	defer func() {
		if request.Body != nil {
			request.Body.Close()
		}
	}()
	var err error
	if rt.Logger != nil {
		rt.log().RequestPrintf("URL: %s %s", request.Method, request.URL)
		rt.log().RequestPrintf("Headers:\n%s", rt.formatHeaders(request.Header, "\n"))
		if request.Body != nil {
			request.Body, err = rt.logRequest(request.Body, request.Header.Get("Content-Type"))
			if err != nil {
				return nil, err
			}
		}
	}
	ort := rt.Rt
	if ort == nil {
		return nil, fmt.Errorf("rt RoundTripper is nil, aborting")
	}
	response, err := ort.RoundTrip(request)
	if response == nil {
		if rt.Logger != nil {
			rt.log().ResponsePrintf("Connection error, retries exhausted. Aborting")
		}
		err = fmt.Errorf("connection error, retries exhausted. Aborting. Last error was: %s", err)
		return nil, err
	}
	if rt.Logger != nil {
		rt.log().ResponsePrintf("Code: %d", response.StatusCode)
		rt.log().ResponsePrintf("Headers:\n%s", rt.formatHeaders(response.Header, "\n"))
		response.Body, err = rt.logResponse(response.Body, response.Header.Get("Content-Type"))
	}
	return response, err
}
func (rt *RoundTripper) logRequest(original io.ReadCloser, contentType string) (io.ReadCloser, error) {
	var bs bytes.Buffer
	defer original.Close()
	if _, err := io.Copy(&bs, original); err != nil {
		return nil, err
	}
	rt.log().RequestPrintf("Body: %s", bs.String())
	return ioutil.NopCloser(bytes.NewReader(bs.Bytes())), nil
}