-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Issue Description
When using both the "Logging" and "Timeout" middleware together, the client is getting the appropriate 503 response, but the logs show that the response was 200.
Checklist
- Dependencies installed
- No typos
- Searched existing issues and docs
Expected behaviour
The server logs would show accurate response details, eg. "status": 503 in the case of the request timeout
Actual behaviour
The server logs show "status": 200
Example:
{"time":"2021-08-10T11:12:02.5457958-04:00","id":"","remote_ip":"::1","host":"localhost:8080","method":"POST","uri":"/sleep","user_agent":"PostmanRuntime/7.28.2","status":200,"error":"","latency":11997200,"latency_human":"11.9972ms","bytes_in":0,"bytes_out":0}
Steps to reproduce
- Create a simple echo server with a single endpoint that sleeps for a few seconds
- Add the use the logging and timeout middleware, set timeout to less than the above sleep
- Startup the server and invoke the endpoint
Working code to debug
package main
import (
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
)
func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.TimeoutWithConfig(middleware.TimeoutConfig{
Timeout: time.Duration(1) * time.Millisecond,
}))
e.Logger.SetLevel(log.INFO)
e.POST("/sleep", func(c echo.Context) error {
c.Logger().Info("Before sleeping in /sleep")
time.Sleep(12 * time.Second)
c.Logger().Info("After sleeping in /sleep")
return nil
})
e.Logger.Panic(e.Start(":8080"))
}
Version/commit
go 1.16
require (
github.com/labstack/echo/v4 v4.5.0
github.com/labstack/gommon v0.3.0
)
Additional Comments:
This example also seems to throw a Data Race warning if you run it a couple times... I think the stack traces suggests it's related to the timeout handler as well.
I think in another issue the timeout middleware was described as a having many landmines, is there another way other echo users are dealing with request timeouts? My particular use case is internal only so I really only need to ensure that connections don't hang indefinately. Would server timeouts be good enough for that?
Example:
package main
import (
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
)
func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Logger.SetLevel(log.INFO)
e.POST("/sleep", func(c echo.Context) error {
time.Sleep(12 * time.Second)
return nil
})
srv := &http.Server{
Addr: ":8080",
Handler: e,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
}
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
e.Logger.Fatal(err)
}
}
In that case my client would get a server hangup (oh and the Logger still logs it as a 200, which is still a problem...)