首页 > 后端开发 > Golang > 正文

在Golang Web项目中如何实现一个简单的日志记录中间件

P粉602998670
发布: 2025-09-06 10:49:02
原创
342人浏览过
日志中间件通过包装http.Handler记录请求信息,可实现请求路径、方法、响应状态码和处理时间的自动日志输出,支持标准输出或文件写入,提升Go Web项目调试与监控能力。

在golang web项目中如何实现一个简单的日志记录中间件

在Golang Web项目中,日志记录中间件可以帮助我们自动记录每次HTTP请求的基本信息,比如请求路径、方法、响应状态码、处理时间等,便于调试和监控。下面是一个简单但实用的日志中间件实现方式,适用于基于

net/http
登录后复制
或类似框架(如Gin、Echo)的项目。

1. 基础日志中间件设计

中间件本质上是一个函数,接收

http.Handler
登录后复制
并返回一个新的
http.Handler
登录后复制
。在这个新处理器中,我们可以记录请求前后的信息。

以下是一个通用的日志中间件实现:

package main

import (
    "log"
    "net/http"
    "time"
)

// 日志中间件
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 请求开始时间
        start := time.Now()

        // 调用下一个处理器
        next.ServeHTTP(w, r)

        // 记录日志
        log.Printf(
            "%s %s %s %dms",
            r.RemoteAddr,
            r.Method,
            r.URL.Path,
            time.Since(start).Milliseconds(),
        )
    })
}
登录后复制

2. 使用中间件包装路由

在主函数中,你可以将具体的处理器通过日志中间件进行包装。

立即学习go语言免费学习笔记(深入)”;

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, World!"))
    })

    // 使用中间件包装 mux
    loggedMux := loggingMiddleware(mux)

    log.Println("Server starting on :8080")
    http.ListenAndServe(":8080", loggedMux)
}
登录后复制

这样,每次访问

/hello
登录后复制
,都会在控制台输出类似:

127.0.0.1:54321 GET /hello 2ms
登录后复制

3. 支持自定义日志输出(如写入文件)

你可以将日志输出到文件而不是标准输出,只需替换

log
登录后复制
的输出目标。

话袋AI笔记
话袋AI笔记

话袋AI笔记, 像聊天一样随时随地记录每一个想法,打造属于你的个人知识库,成为你的外挂大脑

话袋AI笔记 195
查看详情 话袋AI笔记
func init() {
    logFile, err := os.OpenFile("access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatal("无法打开日志文件:", err)
    }
    log.SetOutput(logFile)
}
登录后复制

这样所有通过

log.Printf
登录后复制
输出的内容都会写入
access.log
登录后复制
文件。

4. 增强功能:记录响应状态码

上面的中间件无法直接获取响应状态码,因为

ResponseWriter
登录后复制
不暴露状态码。我们可以通过包装
ResponseWriter
登录后复制
来解决。

type loggingResponseWriter struct {
    http.ResponseWriter
    statusCode int
}

func (lrw *loggingResponseWriter) WriteHeader(code int) {
    lrw.statusCode = code
    lrw.ResponseWriter.WriteHeader(code)
}

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()

        // 包装 ResponseWriter
        lrw := &loggingResponseWriter{
            ResponseWriter: w,
            statusCode:     http.StatusOK, // 默认状态码
        }

        next.ServeHTTP(lrw, r)

        log.Printf(
            "%s %s %s %d %dms",
            r.RemoteAddr,
            r.Method,
            r.URL.Path,
            lrw.statusCode,
            time.Since(start).Milliseconds(),
        )
    })
}
登录后复制

现在中间件可以正确记录实际返回的状态码,比如404、500等。

总结

通过定义一个接收并返回

http.Handler
登录后复制
的函数,我们可以轻松实现日志中间件。关键点包括记录请求时间、包装
ResponseWriter
登录后复制
以获取状态码、以及支持输出到文件。这种模式简洁、可复用,适合大多数Go语言Web项目。

基本上就这些,不复杂但容易忽略细节。

以上就是在Golang Web项目中如何实现一个简单的日志记录中间件的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号