forked from ccfos/nightingale
parent
314a8d71ef
commit
d52848ab1b
|
@ -167,8 +167,10 @@ func (rt *Router) dsProxy(c *gin.Context) {
|
|||
|
||||
modifyResponse := func(r *http.Response) error {
|
||||
if r.StatusCode == http.StatusUnauthorized {
|
||||
logger.Warningf("proxy path:%s unauthorized access ", c.Request.URL.Path)
|
||||
return fmt.Errorf("unauthorized access")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -180,6 +182,7 @@ func (rt *Router) dsProxy(c *gin.Context) {
|
|||
}
|
||||
|
||||
proxy.ServeHTTP(c.Writer, c.Request)
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -2,6 +2,7 @@ package aop
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -40,7 +41,8 @@ type LoggerConfig struct {
|
|||
|
||||
// Output is a writer where logs are written.
|
||||
// Optional. Default value is gin.DefaultWriter.
|
||||
Output io.Writer
|
||||
Output io.Writer
|
||||
PrintBody bool
|
||||
|
||||
// SkipPaths is a url path array which logs are not written.
|
||||
// Optional.
|
||||
|
@ -177,8 +179,13 @@ func ErrorLoggerT(typ gin.ErrorType) gin.HandlerFunc {
|
|||
|
||||
// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
|
||||
// By default gin.DefaultWriter = os.Stdout.
|
||||
func Logger() gin.HandlerFunc {
|
||||
return LoggerWithConfig(LoggerConfig{})
|
||||
func Logger(conf ...LoggerConfig) gin.HandlerFunc {
|
||||
var configuration LoggerConfig
|
||||
if len(conf) > 0 {
|
||||
configuration = conf[0]
|
||||
}
|
||||
|
||||
return LoggerWithConfig(configuration)
|
||||
}
|
||||
|
||||
// LoggerWithFormatter instance a Logger middleware with the specified log format function.
|
||||
|
@ -197,6 +204,21 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) gin.HandlerFunc {
|
|||
})
|
||||
}
|
||||
|
||||
type CustomResponseWriter struct {
|
||||
gin.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (w CustomResponseWriter) Write(data []byte) (int, error) {
|
||||
w.body.Write(data)
|
||||
return w.ResponseWriter.Write(data)
|
||||
}
|
||||
|
||||
func (w CustomResponseWriter) WriteString(s string) (int, error) {
|
||||
w.body.WriteString(s)
|
||||
return w.ResponseWriter.WriteString(s)
|
||||
}
|
||||
|
||||
// LoggerWithConfig instance a Logger middleware with config.
|
||||
func LoggerWithConfig(conf LoggerConfig) gin.HandlerFunc {
|
||||
formatter := conf.Formatter
|
||||
|
@ -234,18 +256,24 @@ func LoggerWithConfig(conf LoggerConfig) gin.HandlerFunc {
|
|||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
|
||||
// var (
|
||||
// rdr1 io.ReadCloser
|
||||
// rdr2 io.ReadCloser
|
||||
// )
|
||||
var (
|
||||
rdr1 io.ReadCloser
|
||||
rdr2 io.ReadCloser
|
||||
)
|
||||
|
||||
// if c.Request.Method != "GET" {
|
||||
// buf, _ := ioutil.ReadAll(c.Request.Body)
|
||||
// rdr1 = ioutil.NopCloser(bytes.NewBuffer(buf))
|
||||
// rdr2 = ioutil.NopCloser(bytes.NewBuffer(buf))
|
||||
bodyWriter := &CustomResponseWriter{
|
||||
ResponseWriter: c.Writer,
|
||||
body: bytes.NewBuffer(nil),
|
||||
}
|
||||
c.Writer = bodyWriter
|
||||
|
||||
// c.Request.Body = rdr2
|
||||
// }
|
||||
if conf.PrintBody {
|
||||
buf, _ := io.ReadAll(c.Request.Body)
|
||||
rdr1 = io.NopCloser(bytes.NewBuffer(buf))
|
||||
rdr2 = io.NopCloser(bytes.NewBuffer(buf))
|
||||
|
||||
c.Request.Body = rdr2
|
||||
}
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
|
@ -277,18 +305,36 @@ func LoggerWithConfig(conf LoggerConfig) gin.HandlerFunc {
|
|||
|
||||
// fmt.Fprint(out, formatter(param))
|
||||
logger.Info(formatter(param))
|
||||
|
||||
// if c.Request.Method != "GET" {
|
||||
// logger.Debug(readBody(rdr1))
|
||||
// }
|
||||
if conf.PrintBody {
|
||||
respBody := readBody(bytes.NewReader(bodyWriter.body.Bytes()), c.Writer.Header().Get("Content-Encoding"))
|
||||
reqBody := readBody(rdr1, c.Request.Header.Get("Content-Encoding"))
|
||||
logger.Debugf("path:%s req body:%s resp:%s", path, reqBody, respBody)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readBody(reader io.Reader) string {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(reader)
|
||||
func readBody(reader io.Reader, encoding string) string {
|
||||
var bodyBytes []byte
|
||||
var err error
|
||||
|
||||
s := buf.String()
|
||||
return s
|
||||
if encoding == "gzip" {
|
||||
gzipReader, err := gzip.NewReader(reader)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to create gzip reader: %v", err)
|
||||
}
|
||||
defer gzipReader.Close()
|
||||
|
||||
bodyBytes, err = io.ReadAll(gzipReader)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to read gzip response body: %v", err)
|
||||
}
|
||||
} else {
|
||||
bodyBytes, err = io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("failed to read response body: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return string(bodyBytes)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ type Config struct {
|
|||
KeyFile string
|
||||
PProf bool
|
||||
PrintAccessLog bool
|
||||
PrintBody bool
|
||||
ExposeMetrics bool
|
||||
ShutdownTimeout int
|
||||
MaxContentLength int64
|
||||
|
@ -72,7 +73,7 @@ type JWTAuth struct {
|
|||
func GinEngine(mode string, cfg Config) *gin.Engine {
|
||||
gin.SetMode(mode)
|
||||
|
||||
loggerMid := aop.Logger()
|
||||
loggerMid := aop.Logger(aop.LoggerConfig{PrintBody: cfg.PrintBody})
|
||||
recoveryMid := aop.Recovery()
|
||||
|
||||
if strings.ToLower(mode) == "release" {
|
||||
|
|
Loading…
Reference in New Issue