From c01d3ed542e43109842b4e1bdfdcd12caf41dd60 Mon Sep 17 00:00:00 2001 From: jonaustin09 Date: Tue, 20 Jun 2023 19:39:58 +0400 Subject: [PATCH] feat: control over logging in debug mode and control logging for specific actions --- s3api/controllers/base.go | 13 ++++------ s3api/controllers/base_test.go | 17 ++++++++++++ s3api/middlewares/logger.go | 34 ++++++++++++------------ s3api/server.go | 2 +- s3api/utils/logger.go | 47 ++++++++++++++++++++-------------- 5 files changed, 69 insertions(+), 44 deletions(-) diff --git a/s3api/controllers/base.go b/s3api/controllers/base.go index 2a6b65b..c2cf133 100644 --- a/s3api/controllers/base.go +++ b/s3api/controllers/base.go @@ -113,6 +113,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error { return SendResponse(ctx, err) } + ctx.Locals("logResBody", false) res, err := c.be.GetObject(bucket, key, acceptRange, ctx.Response().BodyWriter()) if err != nil { return SendResponse(ctx, err) @@ -333,6 +334,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { } body := io.ReadSeeker(bytes.NewReader([]byte(ctx.Body()))) + ctx.Locals("logReqBody", false) etag, err := c.be.PutObjectPart(bucket, keyStart, uploadId, partNumber, contentLength, body) ctx.Response().Header.Set("Etag", etag) @@ -381,6 +383,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error { return SendResponse(ctx, err) } + ctx.Locals("logReqBody", false) etag, err := c.be.PutObject(&s3.PutObjectInput{ Bucket: &bucket, Key: &keyStart, @@ -636,12 +639,10 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error { } func SendResponse(ctx *fiber.Ctx, err error) error { - utils.LogPathParams(ctx) if err != nil { serr, ok := err.(s3err.APIError) if ok { ctx.Status(serr.HTTPStatusCode) - log.Printf("%s: %v", serr.Code, err) return ctx.Send(s3err.GetAPIErrorResponse(serr, "", "", "")) } @@ -651,7 +652,7 @@ func SendResponse(ctx *fiber.Ctx, err error) error { s3err.GetAPIError(s3err.ErrInternalError), "", "", "")) } - utils.LogResponseHeaders(&ctx.Response().Header) + utils.LogCtxDetails(ctx, []byte{}) // https://github.com/gofiber/fiber/issues/2080 // ctx.SendStatus() sets incorrect content length on HEAD request @@ -660,12 +661,10 @@ func SendResponse(ctx *fiber.Ctx, err error) error { } func SendXMLResponse(ctx *fiber.Ctx, resp any, err error) error { - utils.LogPathParams(ctx) if err != nil { serr, ok := err.(s3err.APIError) if ok { ctx.Status(serr.HTTPStatusCode) - log.Printf("%s: %v", serr.Code, err) return ctx.Send(s3err.GetAPIErrorResponse(serr, "", "", "")) } @@ -688,9 +687,7 @@ func SendXMLResponse(ctx *fiber.Ctx, resp any, err error) error { } } - utils.LogResponseHeaders(&ctx.Response().Header) - fmt.Println() - log.Printf("Response Body: %s", b) + utils.LogCtxDetails(ctx, b) return ctx.Send(b) } diff --git a/s3api/controllers/base_test.go b/s3api/controllers/base_test.go index f52e89f..1e49e0c 100644 --- a/s3api/controllers/base_test.go +++ b/s3api/controllers/base_test.go @@ -97,6 +97,7 @@ func TestS3ApiController_ListBuckets(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Get("/", s3ApiController.ListBuckets) @@ -117,6 +118,7 @@ func TestS3ApiController_ListBuckets(t *testing.T) { appErr.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) appErr.Get("/", s3ApiControllerErr.ListBuckets) @@ -190,6 +192,7 @@ func TestS3ApiController_GetActions(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Get("/:bucket/:key/*", s3ApiController.GetActions) @@ -300,6 +303,7 @@ func TestS3ApiController_ListActions(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) @@ -320,6 +324,7 @@ func TestS3ApiController_ListActions(t *testing.T) { appError.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) appError.Get("/:bucket", s3ApiControllerError.ListActions) @@ -415,6 +420,7 @@ func TestS3ApiController_PutBucketActions(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Put("/:bucket", s3ApiController.PutBucketActions) @@ -504,6 +510,7 @@ func TestS3ApiController_PutActions(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Put("/:bucket/:key/*", s3ApiController.PutActions) @@ -636,6 +643,7 @@ func TestS3ApiController_DeleteBucket(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) @@ -658,6 +666,7 @@ func TestS3ApiController_DeleteBucket(t *testing.T) { appErr.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) appErr.Delete("/:bucket", s3ApiControllerErr.DeleteBucket) @@ -721,6 +730,7 @@ func TestS3ApiController_DeleteObjects(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Post("/:bucket", s3ApiController.DeleteObjects) @@ -793,6 +803,7 @@ func TestS3ApiController_DeleteActions(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Delete("/:bucket/:key/*", s3ApiController.DeleteActions) @@ -812,6 +823,7 @@ func TestS3ApiController_DeleteActions(t *testing.T) { appErr.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) appErr.Delete("/:bucket", s3ApiControllerErr.DeleteBucket) @@ -884,6 +896,7 @@ func TestS3ApiController_HeadBucket(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) @@ -905,6 +918,7 @@ func TestS3ApiController_HeadBucket(t *testing.T) { appErr.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) @@ -982,6 +996,7 @@ func TestS3ApiController_HeadObject(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Head("/:bucket/:key/*", s3ApiController.HeadObject) @@ -1003,6 +1018,7 @@ func TestS3ApiController_HeadObject(t *testing.T) { appErr.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) appErr.Head("/:bucket/:key/*", s3ApiControllerErr.HeadObject) @@ -1071,6 +1087,7 @@ func TestS3ApiController_CreateActions(t *testing.T) { app.Use(func(ctx *fiber.Ctx) error { ctx.Locals("access", "valid access") ctx.Locals("isRoot", true) + ctx.Locals("isDebug", false) return ctx.Next() }) app.Post("/:bucket/:key/*", s3ApiController.CreateActions) diff --git a/s3api/middlewares/logger.go b/s3api/middlewares/logger.go index 217641b..17c7182 100644 --- a/s3api/middlewares/logger.go +++ b/s3api/middlewares/logger.go @@ -19,24 +19,26 @@ import ( "log" "github.com/gofiber/fiber/v2" - "github.com/versity/versitygw/s3api/utils" ) -func RequestLogger(ctx *fiber.Ctx) error { - utils.LogRequestHeaders(&ctx.Request().Header) +func RequestLogger(isDebug bool) fiber.Handler { + return func(ctx *fiber.Ctx) error { + ctx.Locals("isDebug", isDebug) + if isDebug { + log.Println("Request headers: ") + ctx.Request().Header.VisitAll(func(key, val []byte) { + log.Printf("%s: %s", key, val) + }) - if len(ctx.Body()) > 0 { - fmt.Println() - log.Printf("Request Body: %s", ctx.Request().Body()) + if ctx.Request().URI().QueryArgs().Len() != 0 { + fmt.Println() + log.Println("Request query arguments: ") + ctx.Request().URI().QueryArgs().VisitAll(func(key, val []byte) { + log.Printf("%s: %s", key, val) + }) + } + } + + return ctx.Next() } - - if ctx.Request().URI().QueryArgs().Len() != 0 { - fmt.Println() - log.Println("Request query arguments: ") - ctx.Request().URI().QueryArgs().VisitAll(func(key, val []byte) { - log.Printf("%s: %s", key, val) - }) - } - - return ctx.Next() } diff --git a/s3api/server.go b/s3api/server.go index 612e915..b2c9f79 100644 --- a/s3api/server.go +++ b/s3api/server.go @@ -47,7 +47,7 @@ func New(app *fiber.App, be backend.Backend, root middlewares.RootUserConfig, po // Logging middlewares app.Use(logger.New()) - app.Use(middlewares.RequestLogger) + app.Use(middlewares.RequestLogger(server.debug)) // Authentication middlewares app.Use(middlewares.VerifyV4Signature(root, iam, region, server.debug)) diff --git a/s3api/utils/logger.go b/s3api/utils/logger.go index 2ed8f95..8bb2682 100644 --- a/s3api/utils/logger.go +++ b/s3api/utils/logger.go @@ -19,28 +19,37 @@ import ( "log" "github.com/gofiber/fiber/v2" - "github.com/valyala/fasthttp" ) -func LogRequestHeaders(headers *fasthttp.RequestHeader) { - log.Println("Request Headers: ") - headers.VisitAll(func(key, val []byte) { - log.Printf("%s: %s", key, val) - }) -} +func LogCtxDetails(ctx *fiber.Ctx, respBody []byte) { + isDebug, ok := ctx.Locals("isDebug").(bool) + _, notLogReqBody := ctx.Locals("logReqBody").(bool) + _, notLogResBody := ctx.Locals("logResBody").(bool) + if isDebug && ok { + // Log request body + if !notLogReqBody { + fmt.Println() + log.Printf("Request Body: %s", ctx.Request().Body()) + } -func LogResponseHeaders(headers *fasthttp.ResponseHeader) { - fmt.Println() - log.Println("Response Headers: ") - headers.VisitAll(func(key, val []byte) { - log.Printf("%s: %s", key, val) - }) -} + // Log path parameters + fmt.Println() + log.Println("Path parameters: ") + for key, val := range ctx.AllParams() { + log.Printf("%s: %s", key, val) + } -func LogPathParams(ctx *fiber.Ctx) { - fmt.Println() - log.Println("Path parameters: ") - for key, val := range ctx.AllParams() { - log.Printf("%s: %s", key, val) + // Log response headers + fmt.Println() + log.Println("Response Headers: ") + ctx.Response().Header.VisitAll(func(key, val []byte) { + log.Printf("%s: %s", key, val) + }) + + // Log response body + if !notLogResBody && len(respBody) > 0 { + fmt.Println() + log.Printf("Response body %s", ctx.Response().Body()) + } } }