mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-15 21:06:39 +08:00
Merge 387e102b37b3bb0e40cd7d741175a5bfca75e4e9 into 857db39f82fb82456af2906ccea972ae1d65ff57
This commit is contained in:
commit
003ab6e835
14
logger.go
14
logger.go
@ -5,6 +5,7 @@
|
|||||||
package gin
|
package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -47,6 +48,10 @@ type LoggerConfig struct {
|
|||||||
// SkipPaths is an url path array which logs are not written.
|
// SkipPaths is an url path array which logs are not written.
|
||||||
// Optional.
|
// Optional.
|
||||||
SkipPaths []string
|
SkipPaths []string
|
||||||
|
|
||||||
|
// RequestBody is a bool to enable request body logging
|
||||||
|
// Optional. Default value is false
|
||||||
|
RequestBody bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogFormatter gives the signature of the formatter function passed to LoggerWithFormatter
|
// LogFormatter gives the signature of the formatter function passed to LoggerWithFormatter
|
||||||
@ -238,11 +243,20 @@ func LoggerWithConfig(conf LoggerConfig) HandlerFunc {
|
|||||||
path := c.Request.URL.Path
|
path := c.Request.URL.Path
|
||||||
raw := c.Request.URL.RawQuery
|
raw := c.Request.URL.RawQuery
|
||||||
|
|
||||||
|
var body []byte
|
||||||
|
if conf.RequestBody {
|
||||||
|
body, _ = io.ReadAll(c.Request.Body)
|
||||||
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||||
|
}
|
||||||
|
|
||||||
// Process request
|
// Process request
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|
||||||
// Log only when path is not being skipped
|
// Log only when path is not being skipped
|
||||||
if _, ok := skip[path]; !ok {
|
if _, ok := skip[path]; !ok {
|
||||||
|
if conf.RequestBody {
|
||||||
|
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||||
|
}
|
||||||
param := LogFormatterParams{
|
param := LogFormatterParams{
|
||||||
Request: c.Request,
|
Request: c.Request,
|
||||||
isTerm: isTerm,
|
isTerm: isTerm,
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
package gin
|
package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -182,18 +184,21 @@ func TestLoggerWithFormatter(t *testing.T) {
|
|||||||
func TestLoggerWithConfigFormatting(t *testing.T) {
|
func TestLoggerWithConfigFormatting(t *testing.T) {
|
||||||
var gotParam LogFormatterParams
|
var gotParam LogFormatterParams
|
||||||
var gotKeys map[string]any
|
var gotKeys map[string]any
|
||||||
|
var gotBody []byte
|
||||||
buffer := new(strings.Builder)
|
buffer := new(strings.Builder)
|
||||||
|
|
||||||
router := New()
|
router := New()
|
||||||
router.engine.trustedCIDRs, _ = router.engine.prepareTrustedCIDRs()
|
router.engine.trustedCIDRs, _ = router.engine.prepareTrustedCIDRs()
|
||||||
|
|
||||||
router.Use(LoggerWithConfig(LoggerConfig{
|
router.Use(LoggerWithConfig(LoggerConfig{
|
||||||
Output: buffer,
|
Output: buffer,
|
||||||
|
RequestBody: true,
|
||||||
Formatter: func(param LogFormatterParams) string {
|
Formatter: func(param LogFormatterParams) string {
|
||||||
// for assert test
|
// for assert test
|
||||||
gotParam = param
|
gotParam = param
|
||||||
|
gotBody, _ = io.ReadAll(param.Request.Body)
|
||||||
|
|
||||||
return fmt.Sprintf("[FORMATTER TEST] %v | %3d | %13v | %15s | %-7s %s\n%s",
|
return fmt.Sprintf("[FORMATTER TEST] %v | %3d | %13v | %15s | %-7s %s %s\n%s",
|
||||||
param.TimeStamp.Format("2006/01/02 - 15:04:05"),
|
param.TimeStamp.Format("2006/01/02 - 15:04:05"),
|
||||||
param.StatusCode,
|
param.StatusCode,
|
||||||
param.Latency,
|
param.Latency,
|
||||||
@ -201,6 +206,7 @@ func TestLoggerWithConfigFormatting(t *testing.T) {
|
|||||||
param.Method,
|
param.Method,
|
||||||
param.Path,
|
param.Path,
|
||||||
param.ErrorMessage,
|
param.ErrorMessage,
|
||||||
|
string(gotBody),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
@ -229,6 +235,16 @@ func TestLoggerWithConfigFormatting(t *testing.T) {
|
|||||||
assert.Equal(t, "/example?a=100", gotParam.Path)
|
assert.Equal(t, "/example?a=100", gotParam.Path)
|
||||||
assert.Empty(t, gotParam.ErrorMessage)
|
assert.Empty(t, gotParam.ErrorMessage)
|
||||||
assert.Equal(t, gotKeys, gotParam.Keys)
|
assert.Equal(t, gotKeys, gotParam.Keys)
|
||||||
|
|
||||||
|
router.POST("/example", func(c *Context) {
|
||||||
|
// set dummy ClientIP
|
||||||
|
c.Request.Header.Set("X-Forwarded-For", "20.20.20.20")
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
})
|
||||||
|
PerformBodyRequest(router, "POST", "/example", []header{}, bytes.NewBufferString(`{"name":"test"}`))
|
||||||
|
|
||||||
|
// LogFormatterParams post body test
|
||||||
|
assert.Equal(t, string(gotBody), `{"name":"test"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultLogFormatter(t *testing.T) {
|
func TestDefaultLogFormatter(t *testing.T) {
|
||||||
|
@ -6,6 +6,7 @@ package gin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
@ -30,7 +31,15 @@ func PerformRequest(r http.Handler, method, path string, headers ...header) *htt
|
|||||||
r.ServeHTTP(w, req)
|
r.ServeHTTP(w, req)
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
func PerformBodyRequest(r http.Handler, method, path string, headers []header, body io.Reader) *httptest.ResponseRecorder {
|
||||||
|
req := httptest.NewRequest(method, path, body)
|
||||||
|
for _, h := range headers {
|
||||||
|
req.Header.Add(h.Key, h.Value)
|
||||||
|
}
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
r.ServeHTTP(w, req)
|
||||||
|
return w
|
||||||
|
}
|
||||||
func testRouteOK(method string, t *testing.T) {
|
func testRouteOK(method string, t *testing.T) {
|
||||||
passed := false
|
passed := false
|
||||||
passedAny := false
|
passedAny := false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user