From fad0b852cbf1e0e27c4e0aa8b125a6fb81c1c2cf Mon Sep 17 00:00:00 2001 From: zhaoyupeng Date: Fri, 11 Jul 2025 11:52:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=20api=20=E4=B8=BA=20?= =?UTF-8?q?option=20=E6=A8=A1=E5=BC=8F=E8=AE=BE=E7=BD=AE;=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20healthz=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api.go | 83 ++++++++++++++++++++++++++++++++++++++-------- handler/healthz.go | 19 +++++++++++ 2 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 handler/healthz.go diff --git a/api/api.go b/api/api.go index add4303..1f1e877 100644 --- a/api/api.go +++ b/api/api.go @@ -4,34 +4,89 @@ import ( "context" "crypto/tls" "errors" + "gitea.loveuer.com/yizhisec/packages/handler" "gitea.loveuer.com/yizhisec/packages/logger" "github.com/gin-gonic/gin" "net" "net/http" ) -type Api struct { - Address string - Name string - App *gin.Engine - TlsConfig *tls.Config +type Option func(*option) + +type option struct { + name string + version string + address string + app *gin.Engine + tlsConfig *tls.Config } -func New(ctx context.Context, api *Api) (func(context.Context) error, error) { +func WithName(name string) Option { + return func(o *option) { + if name == "" { + o.name = name + } + } +} + +func WithVersion(version string) Option { + return func(o *option) { + if version == "" { + o.version = version + } + } +} + +func WithAddress(address string) Option { + return func(o *option) { + if address == "" { + o.address = address + } + } +} + +func WithApp(app *gin.Engine) Option { + return func(o *option) { + if app != nil { + o.app = app + } + } +} + +func WithTLSConfig(tlsConfig *tls.Config) Option { + return func(o *option) { + if tlsConfig != nil { + o.tlsConfig = tlsConfig + } + } +} + +func New(ctx context.Context, optFns ...Option) (func(context.Context) error, error) { var ( err error fn func(context.Context) error ln net.Listener + opt = &option{ + name: "unknown", + version: "v0.0.1", + address: "127.0.0.1:9119", + tlsConfig: nil, + } ) - if api == nil { - return fn, errors.New("api is nil") + for _, ofn := range optFns { + ofn(opt) } - if api.TlsConfig != nil { - ln, err = tls.Listen("tcp", api.Address, api.TlsConfig) + if opt.app == nil { + opt.app = gin.Default() + opt.app.GET("/healthz", handler.Healthz(opt.name, opt.version)) + } + + if opt.tlsConfig != nil { + ln, err = tls.Listen("tcp", opt.address, opt.tlsConfig) } else { - ln, err = net.Listen("tcp", api.Address) + ln, err = net.Listen("tcp", opt.address) } if err != nil { @@ -39,11 +94,11 @@ func New(ctx context.Context, api *Api) (func(context.Context) error, error) { } svc := &http.Server{ - Handler: api.App, + Handler: opt.app, } go func() { - logger.InfoCtx(ctx, "[%s] api svc running at: %s", api.Name, api.Address) + logger.InfoCtx(ctx, "[%s] api svc running at: %s", opt.name, opt.address) if err = svc.Serve(ln); err != nil { if !errors.Is(err, http.ErrServerClosed) { logger.ErrorCtx(ctx, "api svc run failed, err = %s", err.Error()) @@ -52,7 +107,7 @@ func New(ctx context.Context, api *Api) (func(context.Context) error, error) { }() fn = func(timeout context.Context) error { - logger.WarnCtx(ctx, "[%s] api svc shutdown...", api.Name) + logger.WarnCtx(ctx, "[%s] api svc shutdown...", opt.name) return svc.Shutdown(timeout) } diff --git a/handler/healthz.go b/handler/healthz.go new file mode 100644 index 0000000..36773ac --- /dev/null +++ b/handler/healthz.go @@ -0,0 +1,19 @@ +package handler + +import ( + "gitea.loveuer.com/yizhisec/packages/resp" + "github.com/gin-gonic/gin" + "time" +) + +func Healthz(name, version string) gin.HandlerFunc { + start := time.Now() + return func(c *gin.Context) { + resp.R200(c, gin.H{ + "name": name, + "version": version, + "start_at": start, + "uptime": time.Since(start).String(), + }) + } +}