• 程序员的快乐如此简单


    最近在GitHub上发起了一个关于Beego框架的小插件的开源仓库,这一举动虽然看似微小,但其中的快乐和意义却是无法用言语表达的。

    Beego是一个开源的Go语言Web框架,它采用了MVC架构模式,并集成了很多常用的功能和中间件。小插件是指与Beego框架配套使用的、可扩展的、独立的软件模块或组件。通过开发小插件,可以扩展Beego框架的功能,提高开发效率和代码可维护性。

    Beego-Requestid是一种中间件(Middleware),用于在处理HTTP请求时,为每个请求生成一个唯一的ID,并将其附加到请求上下文中。这样,您可以在应用程序的其他地方方便地访问这个唯一的请求ID,从而更好地跟踪和调试应用程序。

    使用RequestId中间件可以帮助您解决以下问题:

    1. 跟踪请求:通过在每个请求中添加唯一的ID,您可以轻松地在应用程序中跟踪请求的来源和路径。这对于调试和性能优化非常有用。
    2. 日志记录:您可以使用请求ID将日志记录与特定请求关联起来。这样,当您在日志中查找特定请求的信息时,可以更方便地定位相关的日志条目。
    3. 错误处理:如果应用程序中出现错误,请求ID可以帮助您识别是哪个请求引发了错误。这对于故障排查和问题报告非常有帮助。
    代码

    话不多说直接看源码:

    package beego_requestid
    
    import (
    	"github.com/beego/beego"
    	"github.com/beego/beego/context"
    	"github.com/google/uuid"
    )
    
    const DefaultHeaderReqIdKey = "X-Request-Id"
    
    type Option func(config *Config)
    
    type GenRequestIdFunc func() string
    
    type Config struct {
    	genRequestIdFunc               GenRequestIdFunc
    	headerReqIdKey, customReqIdKey string
    }
    
    func NewFilter(opts ...Option) beego.FilterFunc {
    	cnf := &Config{
    		genRequestIdFunc: DefaultGenRequestIdFunc,
    		headerReqIdKey:   DefaultHeaderReqIdKey,
    	}
    
    	for _, opt := range opts {
    		opt(cnf)
    	}
    
    	return func(c *context.Context) {
    		reqId := c.Request.Header.Get(cnf.headerReqIdKey)
    		if reqId == "" {
    			reqId = cnf.genRequestIdFunc()
    			c.Request.Header.Add(cnf.headerReqIdKey, reqId)
    		}
    		if cnf.customReqIdKey != "" {
    			c.Input.SetData(cnf.customReqIdKey, reqId)
    		}
    	}
    }
    
    func WithGenRequestIdFunc(genFunc GenRequestIdFunc) Option {
    	return func(config *Config) {
    		config.genRequestIdFunc = genFunc
    	}
    }
    
    func WithHeaderReqIdKey(key string) Option {
    	return func(config *Config) {
    		config.headerReqIdKey = key
    	}
    }
    
    func WithCustomReqIdKey(key string) Option {
    	return func(config *Config) {
    		config.customReqIdKey = key
    	}
    }
    
    func DefaultGenRequestIdFunc() string {
    	return uuid.NewString()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    使用示例:

    package main
    
    import (
    	"log"
    	"time"
    
    	"github.com/spf13/cast"
    	"github.com/beego/beego"
    	"github.com/beego/beego/context"
    	beego_requestid "github.com/ibarryyan/beego-requestid"
    )
    
    func example1() {
    	beego.InsertFilter("/*", beego.BeforeRouter, beego_requestid.NewFilter())
    
    	beego.Get("/hello", func(c *context.Context) {
    		reqId := c.Request.Header.Get("X-Request-Id")
    		log.Printf("reqestid = %s", reqId)
    
    		_, _ = c.ResponseWriter.Write([]byte("hello..."))
    		return
    	})
    
    	beego.Run(":9900")
    }
    
    func example2() {
    	beego.InsertFilter("/*", beego.BeforeRouter, beego_requestid.NewFilter(
    		beego_requestid.WithGenRequestIdFunc(func() string {
    			return cast.ToString(time.Now().Unix())
    		}),
    		beego_requestid.WithHeaderReqIdKey("my_header_reqid"),
    		beego_requestid.WithCustomReqIdKey("my_reqid"),
    	))
    
    	beego.Get("/hello", func(c *context.Context) {
    		reqId := c.Request.Header.Get("my_header_reqid")
    		log.Printf("reqestid = %s", reqId)
    
    		cReqId := c.Input.GetData("my_reqid")
    		log.Printf("my reqestid = %s", cReqId)
    
    		_, _ = c.ResponseWriter.Write([]byte("hello..."))
    		return
    	})
    
    	beego.Run(":9900")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    此外,前端请求时需要带上header key要与后端的一致

    获得快乐

    发完代码后我就直接去Beego的GitHub仓库下提了一个issue,来分享的研究的中间件,地址:https://github.com/beego/beego/issues/5419,后来没想到竟然收到了回复,哈哈哈

    在这里插入图片描述

    然后我立马就去新的issue分享了我的插件

    https://github.com/beego/beego/issues/5421

    再后来,我就有两个star了~

    在这里插入图片描述

    仓库地址

    https://github.com/ibarryyan/beego-requestid

  • 相关阅读:
    详解设计模式:原型模式
    SpringBoot中 Mybatis 的xml映射文件配置
    python 基础便利操作
    用什么工具来画UML?
    代码随想录61——额外题目【数组】:1365有多少小于当前数字的数字、941有效的山脉数组、1207独一无二的出现次数
    Java错题归纳day16
    好玩的js特效
    go语言文件操作
    输入回车换行,div标签可编写
    JavaScript数据类型
  • 原文地址:https://blog.csdn.net/Mr_YanMingXin/article/details/133217480