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...)