middleware_http_logging.go

 1package http
 2
 3import (
 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.
14type RequestResponseLogger struct {
15	LogRequest         bool
16	LogRequestWithBody bool
17
18	LogResponse         bool
19	LogResponseWithBody bool
20}
21
22// ID is the middleware identifier.
23func (r *RequestResponseLogger) ID() string {
24	return "RequestResponseLogger"
25}
26
27// HandleDeserialize will log the request and response HTTP messages if configured accordingly.
28func (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}