Skip to content

Commit e125b2c

Browse files
authored
Fix recover print stack trace log level (#1604)
* Fix recover print stack trace log level * Add recover log level test * Add default LogLevel to DefaultRecoverConfig
1 parent de3a2d4 commit e125b2c

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

middleware/recover.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"runtime"
66

77
"github.com/labstack/echo/v4"
8+
"github.com/labstack/gommon/log"
89
)
910

1011
type (
@@ -25,6 +26,10 @@ type (
2526
// DisablePrintStack disables printing stack trace.
2627
// Optional. Default value as false.
2728
DisablePrintStack bool `yaml:"disable_print_stack"`
29+
30+
// LogLevel is log level to printing stack trace.
31+
// Optional. Default value 0 (Print).
32+
LogLevel log.Lvl
2833
}
2934
)
3035

@@ -35,6 +40,7 @@ var (
3540
StackSize: 4 << 10, // 4 KB
3641
DisableStackAll: false,
3742
DisablePrintStack: false,
43+
LogLevel: 0,
3844
}
3945
)
4046

@@ -70,7 +76,21 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc {
7076
stack := make([]byte, config.StackSize)
7177
length := runtime.Stack(stack, !config.DisableStackAll)
7278
if !config.DisablePrintStack {
73-
c.Logger().Printf("[PANIC RECOVER] %v %s\n", err, stack[:length])
79+
msg := fmt.Sprintf("[PANIC RECOVER] %v %s\n", err, stack[:length])
80+
switch config.LogLevel {
81+
case log.DEBUG:
82+
c.Logger().Debug(msg)
83+
case log.INFO:
84+
c.Logger().Info(msg)
85+
case log.WARN:
86+
c.Logger().Warn(msg)
87+
case log.ERROR:
88+
c.Logger().Error(msg)
89+
case log.OFF:
90+
// None.
91+
default:
92+
c.Logger().Print(msg)
93+
}
7494
}
7595
c.Error(err)
7696
}

middleware/recover_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package middleware
22

33
import (
44
"bytes"
5+
"fmt"
56
"net/http"
67
"net/http/httptest"
78
"testing"
89

910
"github.com/labstack/echo/v4"
11+
"github.com/labstack/gommon/log"
1012
"github.com/stretchr/testify/assert"
1113
)
1214

@@ -24,3 +26,58 @@ func TestRecover(t *testing.T) {
2426
assert.Equal(t, http.StatusInternalServerError, rec.Code)
2527
assert.Contains(t, buf.String(), "PANIC RECOVER")
2628
}
29+
30+
func TestRecoverWithConfig_LogLevel(t *testing.T) {
31+
tests := []struct {
32+
logLevel log.Lvl
33+
levelName string
34+
}{{
35+
logLevel: log.DEBUG,
36+
levelName: "DEBUG",
37+
}, {
38+
logLevel: log.INFO,
39+
levelName: "INFO",
40+
}, {
41+
logLevel: log.WARN,
42+
levelName: "WARN",
43+
}, {
44+
logLevel: log.ERROR,
45+
levelName: "ERROR",
46+
}, {
47+
logLevel: log.OFF,
48+
levelName: "OFF",
49+
}}
50+
51+
for _, tt := range tests {
52+
tt := tt
53+
t.Run(tt.levelName, func(t *testing.T) {
54+
e := echo.New()
55+
e.Logger.SetLevel(log.DEBUG)
56+
57+
buf := new(bytes.Buffer)
58+
e.Logger.SetOutput(buf)
59+
60+
req := httptest.NewRequest(http.MethodGet, "/", nil)
61+
rec := httptest.NewRecorder()
62+
c := e.NewContext(req, rec)
63+
64+
config := DefaultRecoverConfig
65+
config.LogLevel = tt.logLevel
66+
h := RecoverWithConfig(config)(echo.HandlerFunc(func(c echo.Context) error {
67+
panic("test")
68+
}))
69+
70+
h(c)
71+
72+
assert.Equal(t, http.StatusInternalServerError, rec.Code)
73+
74+
output := buf.String()
75+
if tt.logLevel == log.OFF {
76+
assert.Empty(t, output)
77+
} else {
78+
assert.Contains(t, output, "PANIC RECOVER")
79+
assert.Contains(t, output, fmt.Sprintf(`"level":"%s"`, tt.levelName))
80+
}
81+
})
82+
}
83+
}

0 commit comments

Comments
 (0)