echo icon indicating copy to clipboard operation
echo copied to clipboard

unable to skip log based on the response status

Open shortcuts opened this issue 1 year ago • 2 comments

Issue Description

I've tried to skip logs for 404 and 429 but was unable to by using a simple Skipper because it is evaluated before next has been called and therefore the status is always 200.

Checklist

  • [x] Dependencies installed
  • [x] No typos
  • [x] Searched existing issues and docs

Expected behaviour

Being able to skip based on the status

Actual behaviour

Skipper is called before the status has been set

Steps to reproduce

  1. Trigger a 404
  2. See the log being outputted
  3. Add a print in the middleware, see status 200 on 404 requests

Working code to debug

package main

func main() {
	e := echo.New()

	e.Use(
		middleware.LoggerWithConfig(middleware.LoggerConfig{
			Skipper: func(c echo.Context) bool {
				return c.Response().Status == http.StatusNotFound || c.Response().Status == http.StatusTooManyRequests
			},
		}),
	)

	e.Start(":1313")

}

See https://github.com/shortcuts/codes/pull/9/files also if you want to see the full file

Version/commit

Latest

shortcuts avatar Jun 21 '24 22:06 shortcuts

This is working as intended. Skipper is called always before next middleware/handler is called. At this time there is no response (code) yet.

You can use RequestLogger middleware to ignore some log lines. See

  • https://echo.labstack.com/docs/middleware/logger#new-requestlogger-middleware
  • https://github.com/labstack/echo/blob/master/middleware/request_logger.go
	logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
	e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
		LogStatus:   true,
		LogURI:      true,
		LogError:    true,
		HandleError: true, // forwards error to the global error handler, so it can decide appropriate status code
		LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
			if v.Status == http.StatusNotFound || v.Status == http.StatusTooManyRequests {
				return nil
			}
			
			if v.Error == nil {
				logger.LogAttrs(context.Background(), slog.LevelInfo, "REQUEST",
					slog.String("uri", v.URI),
					slog.Int("status", v.Status),
				)
			} else {
				logger.LogAttrs(context.Background(), slog.LevelError, "REQUEST_ERROR",
					slog.String("uri", v.URI),
					slog.Int("status", v.Status),
					slog.String("err", v.Error.Error()),
				)
			}
			return nil
		},
	}))

aldas avatar Jun 22 '24 03:06 aldas

Thanks for the fast answer @aldas !

Naively I thought that the skipper (in the log context) scope was to skip logs for any situation and the request logger reserved to 3rd party integrations and/or customization.

I think we can close this issue then, I'll go with your suggested solution, thanks!

shortcuts avatar Jun 22 '24 08:06 shortcuts