使用中间件是Golang中记录HTTP请求日志的常见方式,通过封装http.Handler在请求前后记录方法、URL、IP、状态码和耗时等信息。1. 可创建自定义loggingMiddleware函数,利用responseWriter包装ResponseWriter以捕获状态码;2. 扩展日志内容可包括请求头、User-Agent等,读取请求体后需重置以便后续处理;3. 第三方库如gorilla/handlers提供LoggingHandler,支持类Apache日志格式输出;4. 生产环境建议将日志写入文件,可通过os.OpenFile打开日志文件并设置log.SetOutput或使用log.New指定输出目标。关键在于正确捕获响应状态码与请求生命周期,确保日志完整性。

在Golang中实现HTTP请求日志记录,最常见的方式是使用中间件(middleware)来拦截进入的HTTP请求和响应。通过封装http.Handler,可以在每次请求处理前后记录相关信息,如请求方法、URL、客户端IP、响应状态码、耗时等。
1. 使用自定义中间件记录请求日志
创建一个日志中间件函数,接收一个http.Handler并返回一个新的http.Handler,在其中添加日志逻辑:
func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() // 记录请求信息 log.Printf( "started %s %s from %s", r.Method, r.URL.Path, r.RemoteAddr, ) // 包装 ResponseWriter 以捕获状态码 rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK} next.ServeHTTP(rw, r) // 记录响应完成信息 log.Printf( "completed %v %s in %v", rw.statusCode, http.StatusText(rw.statusCode), time.Since(start), ) })}// 自定义 ResponseWriter 捕获状态码type responseWriter struct { http.ResponseWriter statusCode int}func (rw *responseWriter) WriteHeader(code int) { rw.statusCode = code rw.ResponseWriter.WriteHeader(code)}
http.Handle("/hello", loggingMiddleware(http.HandlerFunc(helloHandler)))log.Fatal(http.ListenAndServe(":8080", nil))
2. 记录更多上下文信息
你可以扩展日志内容,例如记录请求头、User-Agent、请求体大小等。注意:读取请求体需要谨慎,因为它是一次性读取的流。
立即学习“go语言免费学习笔记(深入)”;
log.Printf("method=%s path=%s remote=%s user-agent=%s", r.Method, r.URL.Path, r.RemoteAddr, r.Header.Get("User-Agent"),)
若需记录请求体,可使用ioutil.ReadAll读取r.Body,但记得重新赋值r.Body以便后续处理器读取:
body, _ := io.ReadAll(r.Body)log.Printf("body=%s", string(body))r.Body = io.NopCloser(bytes.NewBuffer(body)) // 重置 Body
3. 使用第三方库简化日志记录
如果你希望快速集成,可以使用成熟的Go Web中间件库,比如chi或gorilla/handlers。
例如,使用gorilla/handlers的LoggingHandler:
import "github.com/gorilla/handlers"import "os"http.Handle("/hello", http.HandlerFunc(helloHandler))log.Fatal(http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, http.DefaultServeMux),))
这会自动输出类似Apache的日志格式,包含时间、方法、路径、状态码和耗时。
4. 日志输出到文件而非标准输出
生产环境中通常需要将日志写入文件。可以将日志输出重定向到文件:
logFile, err := os.OpenFile("access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil { log.Fatal(err)}defer logFile.Close()log.SetOutput(logFile) // 全局日志输出到文件// 或仅中间件使用特定输出logger := log.New(logFile, "", log.LstdFlags)logger.Printf("started %s %s", r.Method, r.URL.Path)
基本上就这些。通过中间件方式,你可以灵活控制日志格式、字段和输出目标,同时保持代码解耦。不复杂但容易忽略的是包装ResponseWriter来获取状态码,这是实现完整请求生命周期日志的关键。
以上就是如何在Golang中实现HTTP请求日志记录的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1417120.html
微信扫一扫
支付宝扫一扫