Open Think-Me opened 5 days ago
简单的修改下中间件,添加个白名单的参数,我先给一份参考代码,后续有空我再同步到nunu仓库,代码类似这样,:
第一步,修改internal/server/http.go
s.Use(
middleware.CORSMiddleware(),
middleware.RateLimiterMiddleware(100),
middleware.AesMiddleware(logger, conf, []string{
"POST:/v1/upload",
"GET:/v1/wallet/scan/pay",
`GET:/v1/cloud-disk/token/.*`,
`GET:/v1/wechat/mp/auth`,
`GET:/v1/wechat/pay/auth`,
`POST:/v1/wechat/push`,
`POST:/v1/wechat/pay/notify`,
`GET:/v1/robots.txt`,
`GET:/sitemap.*`,
`POST:/v1/alipay/notify`,
}),
middleware.SignMiddleware(logger, conf, []string{
"GET:/v1/wallet/scan/pay",
"POST:/v1/upload",
`GET:/v1/cloud-disk/token/.*`,
`GET:/v1/wechat/mp/auth`,
`GET:/v1/wechat/pay/auth`,
`POST:/v1/wechat/push`,
`POST:/v1/wechat/pay/notify`,
`GET:/v1/robots.txt`,
`GET:/sitemap.*`,
`POST:/v1/alipay/notify`,
}),
middleware.RequestLogMiddleware(logger, []string{
"POST:/v1/upload",
`GET:/v1/robots.txt`,
`GET:/sitemap.*`,
}),
middleware.ResponseLogMiddleware(logger, []string{
"POST:/v1/upload",
`GET:/v1/robots.txt`,
`GET:/sitemap.*`,
}),
)
然后再修改下日志中间件的代码
第二步,修改internal/middleware/log.go
func RequestLogMiddleware(logger *log.Logger, whiteList []string) gin.HandlerFunc {
return func(ctx *gin.Context) {
for _, pattern := range whiteList {
parts := strings.SplitN(pattern, ":", 2)
if len(parts) == 2 {
if ctx.Request.Method != parts[0] {
continue
}
pattern = parts[1]
}
matched, err := regexp.MatchString(pattern, ctx.Request.URL.Path)
if err != nil {
logger.WithContext(ctx).Error("Failed to match pattern", zap.Error(err))
continue
}
if matched {
ctx.Next()
return
}
}
// The configuration is initialized once per request
trace := md5.Md5(uuid.GenUUID())
logger.WithValue(ctx, zap.String("trace", trace))
logger.WithValue(ctx, zap.String("request_method", ctx.Request.Method))
logger.WithValue(ctx, zap.Any("request_headers", ctx.Request.Header))
logger.WithValue(ctx, zap.String("request_url", ctx.Request.URL.String()))
if ctx.Request.Body != nil {
bodyBytes, _ := ctx.GetRawData()
ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
logger.WithValue(ctx, zap.String("request_params", string(bodyBytes)))
}
logger.WithContext(ctx).Info("Request")
ctx.Next()
}
}
func ResponseLogMiddleware(logger *log.Logger, whiteList []string) gin.HandlerFunc {
return func(ctx *gin.Context) {
for _, pattern := range whiteList {
parts := strings.SplitN(pattern, ":", 2)
if len(parts) == 2 {
if ctx.Request.Method != parts[0] {
continue
}
pattern = parts[1]
}
matched, err := regexp.MatchString(pattern, ctx.Request.URL.Path)
if err != nil {
logger.WithContext(ctx).Error("Failed to match pattern", zap.Error(err))
continue
}
if matched {
ctx.Next()
return
}
}
blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer}
ctx.Writer = blw
startTime := time.Now()
ctx.Next()
duration := time.Since(startTime).String()
ctx.Header("X-Response-Time", duration)
logger.WithContext(ctx).Info("Response", zap.Any("response_body", blw.body.String()), zap.Any("time", duration))
}
}
type bodyLogWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (w bodyLogWriter) Write(b []byte) (int, error) {
w.body.Write(b)
return w.ResponseWriter.Write(b)
}
因为我这里有个文件流中转的接口,打印响应日志会有一大堆的16进制文件内容,会让日志文件特别大。