golang,go,博客,开源,编程
在 Gin 中,你可以通过自定义中间件来打印请求和响应的头部信息(Headers)。通过这种方式,你可以捕获和记录每个 HTTP 请求和响应的详细信息。下面是一个示例,展示如何创建中间件来打印请求的头部信息、响应的头部信息,并记录相关的日志。
以下是一个简单的 Gin 中间件示例,它将打印 HTTP 请求的头部信息以及响应的头部信息:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"time"
"github.com/gin-gonic/gin"
)
// 自定义Writer以捕获响应头部信息
type ResponseWriterWrapper struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (rw *ResponseWriterWrapper) Write(b []byte) (int, error) {
rw.body.Write(b)
return rw.ResponseWriter.Write(b)
}
// 请求和响应头部信息日志中间件
func RequestLogger() gin.HandlerFunc {
return func(c *gin.Context) {
// 获取请求的开始时间
start := time.Now()
// 读取请求体(如果有)
body, _ := ioutil.ReadAll(c.Request.Body)
// 恢复请求体,以便后续处理
c.Request.Body = ioutil.NopCloser(bytes.NewReader(body))
// 打印请求信息
log.Printf("Request Method: %s", c.Request.Method)
log.Printf("Request URL: %s", c.Request.URL)
log.Printf("Request Headers: %+v", c.Request.Header)
log.Printf("Request Body: %s", string(body))
// 创建ResponseWriterWrapper来捕获响应头和响应体
rw := &ResponseWriterWrapper{ResponseWriter: c.Writer, body: bytes.NewBufferString("")}
c.Writer = rw
// 继续处理请求
c.Next()
// 打印响应信息
duration := time.Since(start)
log.Printf("Response Status: %d", c.Writer.Status())
log.Printf("Response Headers: %+v", c.Writer.Header())
log.Printf("Response Body: %s", rw.body.String())
log.Printf("Duration: %v", duration)
}
}
func main() {
// 初始化Gin
r := gin.Default()
// 使用自定义的请求日志中间件
r.Use(RequestLogger())
// 示例路由
r.POST("/example", func(c *gin.Context) {
// 设置响应头部
c.Header("X-Custom-Header", "CustomHeaderValue")
// 返回响应
c.JSON(200, gin.H{
"message": "Request received",
})
})
// 启动服务器
r.Run(":8080")
}
ResponseWriterWrapper
:
ResponseWriterWrapper
来捕获响应体和响应头。该结构体包装了 Gin 的默认 ResponseWriter
,并通过 Write
方法记录响应内容。RequestLogger
中间件:
c.Request.Header
)、请求体、请求方法、请求 URL。ResponseWriterWrapper
来捕获响应头和响应体,并打印 响应头(c.Writer.Header()
)和 响应体。c.Request.Header
访问。c.Writer.Header()
访问。启动程序后,访问 http://localhost:8080/example
并发送一个 POST 请求。日志将会打印出类似如下的请求和响应头部信息:
Request Method: POST
Request URL: /example
Request Headers: map[Content-Type:[application/json] User-Agent:[Go-http-client/1.1]]
Request Body: {"name": "John"}
Response Status: 200
Response Headers: map[X-Custom-Header:[CustomHeaderValue] Content-Type:[application/json]; charset=utf-8]]
Response Body: {"message":"Request received"}
Duration: 12.34ms
Content-Type
和 User-Agent
。X-Custom-Header
。zap
或 logrus
)来替换标准日志。import "github.com/gin-gonic/gin"
// 使用 zap 或 logrus 等高级日志库
import "go.uber.org/zap"
var logger, _ = zap.NewProduction()
func RequestLogger() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
body, _ := ioutil.ReadAll(c.Request.Body)
c.Request.Body = ioutil.NopCloser(bytes.NewReader(body))
// 使用 zap 记录日志
logger.Info("Request Received",
zap.String("method", c.Request.Method),
zap.String("url", c.Request.URL.String()),
zap.Any("headers", c.Request.Header),
zap.String("body", string(body)),
)
rw := &ResponseWriterWrapper{ResponseWriter: c.Writer, body: bytes.NewBufferString("")}
c.Writer = rw
c.Next()
logger.Info("Response Sent",
zap.Int("status", c.Writer.Status()),
zap.Any("response_headers", c.Writer.Header()),
zap.String("response_body", rw.body.String()),
zap.Duration("duration", time.Since(start)),
)
}
}
通过 Gin 中间件,你可以方便地打印 HTTP 请求和响应的头部信息。这对于调试、性能监控和日志记录非常有用,可以帮助开发者实时了解请求和响应的内容和性能表现。