Skip to content

Commit d4ad69d

Browse files
committed
Add LogLevelSetter to recover middleware
1 parent 8d2c45e commit d4ad69d

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

middleware/recover.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
)
1010

1111
type (
12+
// LogLevelSetter defines a function to get log level for the recovered value.
13+
LogLevelSetter func(value interface{}) log.Lvl
14+
1215
// RecoverConfig defines the config for Recover middleware.
1316
RecoverConfig struct {
1417
// Skipper defines a function to skip middleware.
@@ -30,6 +33,10 @@ type (
3033
// LogLevel is log level to printing stack trace.
3134
// Optional. Default value 0 (Print).
3235
LogLevel log.Lvl
36+
37+
// LogLevelSetter defines a function to get log level for the recovered value.
38+
// LogLevelSetter has higher priority than LogLevel when it's set.
39+
LogLevelSetter LogLevelSetter
3340
}
3441
)
3542

@@ -41,6 +48,7 @@ var (
4148
DisableStackAll: false,
4249
DisablePrintStack: false,
4350
LogLevel: 0,
51+
LogLevelSetter: nil,
4452
}
4553
)
4654

@@ -73,11 +81,15 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc {
7381
if !ok {
7482
err = fmt.Errorf("%v", r)
7583
}
84+
logLevel := config.LogLevel
85+
if config.LogLevelSetter != nil {
86+
logLevel = config.LogLevelSetter(r)
87+
}
7688
stack := make([]byte, config.StackSize)
7789
length := runtime.Stack(stack, !config.DisableStackAll)
7890
if !config.DisablePrintStack {
7991
msg := fmt.Sprintf("[PANIC RECOVER] %v %s\n", err, stack[:length])
80-
switch config.LogLevel {
92+
switch logLevel {
8193
case log.DEBUG:
8294
c.Logger().Debug(msg)
8395
case log.INFO:

middleware/recover_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,36 @@ func TestRecoverWithConfig_LogLevel(t *testing.T) {
8181
})
8282
}
8383
}
84+
85+
func TestRecoverWithConfig_LogLevelSetter(t *testing.T) {
86+
e := echo.New()
87+
e.Logger.SetLevel(log.DEBUG)
88+
89+
buf := new(bytes.Buffer)
90+
e.Logger.SetOutput(buf)
91+
92+
req := httptest.NewRequest(http.MethodGet, "/", nil)
93+
rec := httptest.NewRecorder()
94+
c := e.NewContext(req, rec)
95+
96+
config := DefaultRecoverConfig
97+
config.LogLevelSetter = func(value interface{}) log.Lvl {
98+
if s, ok := value.(string); ok {
99+
if s == "test" {
100+
return log.DEBUG
101+
}
102+
}
103+
return log.ERROR
104+
}
105+
h := RecoverWithConfig(config)(echo.HandlerFunc(func(c echo.Context) error {
106+
panic("test")
107+
}))
108+
109+
h(c)
110+
111+
assert.Equal(t, http.StatusInternalServerError, rec.Code)
112+
113+
output := buf.String()
114+
assert.Contains(t, output, "PANIC RECOVER")
115+
assert.Contains(t, output, `"level":"DEBUG"`)
116+
}

0 commit comments

Comments
 (0)