middleware_http_logging.go raw

   1  package http
   2  
   3  import (
   4  	"context"
   5  	"fmt"
   6  	"net/http/httputil"
   7  
   8  	"github.com/aws/smithy-go/logging"
   9  	"github.com/aws/smithy-go/middleware"
  10  )
  11  
  12  // RequestResponseLogger is a deserialize middleware that will log the request and response HTTP messages and optionally
  13  // their respective bodies. Will not perform any logging if none of the options are set.
  14  type RequestResponseLogger struct {
  15  	LogRequest         bool
  16  	LogRequestWithBody bool
  17  
  18  	LogResponse         bool
  19  	LogResponseWithBody bool
  20  }
  21  
  22  // ID is the middleware identifier.
  23  func (r *RequestResponseLogger) ID() string {
  24  	return "RequestResponseLogger"
  25  }
  26  
  27  // HandleDeserialize will log the request and response HTTP messages if configured accordingly.
  28  func (r *RequestResponseLogger) HandleDeserialize(
  29  	ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler,
  30  ) (
  31  	out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
  32  ) {
  33  	logger := middleware.GetLogger(ctx)
  34  
  35  	if r.LogRequest || r.LogRequestWithBody {
  36  		smithyRequest, ok := in.Request.(*Request)
  37  		if !ok {
  38  			return out, metadata, fmt.Errorf("unknown transport type %T", in)
  39  		}
  40  
  41  		rc := smithyRequest.Build(ctx)
  42  		reqBytes, err := httputil.DumpRequestOut(rc, r.LogRequestWithBody)
  43  		if err != nil {
  44  			return out, metadata, err
  45  		}
  46  
  47  		logger.Logf(logging.Debug, "Request\n%v", string(reqBytes))
  48  
  49  		if r.LogRequestWithBody {
  50  			smithyRequest, err = smithyRequest.SetStream(rc.Body)
  51  			if err != nil {
  52  				return out, metadata, err
  53  			}
  54  			in.Request = smithyRequest
  55  		}
  56  	}
  57  
  58  	out, metadata, err = next.HandleDeserialize(ctx, in)
  59  
  60  	if (err == nil) && (r.LogResponse || r.LogResponseWithBody) {
  61  		smithyResponse, ok := out.RawResponse.(*Response)
  62  		if !ok {
  63  			return out, metadata, fmt.Errorf("unknown transport type %T", out.RawResponse)
  64  		}
  65  
  66  		respBytes, err := httputil.DumpResponse(smithyResponse.Response, r.LogResponseWithBody)
  67  		if err != nil {
  68  			return out, metadata, fmt.Errorf("failed to dump response %w", err)
  69  		}
  70  
  71  		logger.Logf(logging.Debug, "Response\n%v", string(respBytes))
  72  	}
  73  
  74  	return out, metadata, err
  75  }
  76