From 581dd74bbb80611abdaad06e344477290a891cef Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Wed, 8 Jan 2025 23:16:55 +0800 Subject: [PATCH] add config hot reload --- cmd/gost/config.go | 303 ++++++++++++++++++++++++++++++----- cmd/gost/main.go | 10 +- cmd/gost/program.go | 381 +++++++++++++++++++------------------------- go.mod | 4 +- go.sum | 8 +- 5 files changed, 441 insertions(+), 265 deletions(-) diff --git a/cmd/gost/config.go b/cmd/gost/config.go index c995f44..845381b 100644 --- a/cmd/gost/config.go +++ b/cmd/gost/config.go @@ -1,6 +1,8 @@ package main import ( + "encoding/json" + "os" "strings" "github.com/go-gost/core/auth" @@ -9,6 +11,7 @@ import ( "github.com/go-gost/x/api" xauth "github.com/go-gost/x/auth" "github.com/go-gost/x/config" + "github.com/go-gost/x/config/cmd" admission_parser "github.com/go-gost/x/config/parsing/admission" auth_parser "github.com/go-gost/x/config/parsing/auth" bypass_parser "github.com/go-gost/x/config/parsing/bypass" @@ -24,134 +27,352 @@ import ( router_parser "github.com/go-gost/x/config/parsing/router" sd_parser "github.com/go-gost/x/config/parsing/sd" service_parser "github.com/go-gost/x/config/parsing/service" + xmd "github.com/go-gost/x/metadata" + mdutil "github.com/go-gost/x/metadata/util" metrics "github.com/go-gost/x/metrics/service" "github.com/go-gost/x/registry" ) -func buildService(cfg *config.Config) (services []service.Service) { - if cfg == nil { - return +func parseConfig() (*config.Config, error) { + cfg := &config.Config{} + if cfgFile != "" { + cfgFile = strings.TrimSpace(cfgFile) + if strings.HasPrefix(cfgFile, "{") && strings.HasSuffix(cfgFile, "}") { + if err := json.Unmarshal([]byte(cfgFile), cfg); err != nil { + return nil, err + } + } else { + if err := cfg.ReadFile(cfgFile); err != nil { + return nil, err + } + } } - log := logger.Default() + cmdCfg, err := cmd.BuildConfigFromCmd(services, nodes) + if err != nil { + return nil, err + } + cfg = mergeConfig(cfg, cmdCfg) + if len(cfg.Services) == 0 && apiAddr == "" && cfg.API == nil { + if err := cfg.Load(); err != nil { + return nil, err + } + } + + if v := os.Getenv("GOST_LOGGER_LEVEL"); v != "" { + cfg.Log = &config.LogConfig{ + Level: v, + } + } + if v := os.Getenv("GOST_API"); v != "" { + cfg.API = &config.APIConfig{ + Addr: v, + } + } + if v := os.Getenv("GOST_METRICS"); v != "" { + cfg.Metrics = &config.MetricsConfig{ + Addr: v, + } + } + if v := os.Getenv("GOST_PROFILING"); v != "" { + cfg.Profiling = &config.ProfilingConfig{ + Addr: v, + } + } + + if debug || trace { + if cfg.Log == nil { + cfg.Log = &config.LogConfig{} + } + + cfg.Log.Level = string(logger.DebugLevel) + if trace { + cfg.Log.Level = string(logger.TraceLevel) + } + } + + if apiAddr != "" { + cfg.API = &config.APIConfig{ + Addr: apiAddr, + } + if url, _ := cmd.Norm(apiAddr); url != nil { + cfg.API.Addr = url.Host + if url.User != nil { + username := url.User.Username() + password, _ := url.User.Password() + cfg.API.Auth = &config.AuthConfig{ + Username: username, + Password: password, + } + } + m := map[string]any{} + for k, v := range url.Query() { + if len(v) > 0 { + m[k] = v[0] + } + } + md := xmd.NewMetadata(m) + cfg.API.PathPrefix = mdutil.GetString(md, "pathPrefix") + cfg.API.AccessLog = mdutil.GetBool(md, "accesslog") + } + } + if metricsAddr != "" { + cfg.Metrics = &config.MetricsConfig{ + Addr: metricsAddr, + } + if url, _ := cmd.Norm(metricsAddr); url != nil { + cfg.Metrics.Addr = url.Host + if url.User != nil { + username := url.User.Username() + password, _ := url.User.Password() + cfg.Metrics.Auth = &config.AuthConfig{ + Username: username, + Password: password, + } + } + m := map[string]any{} + for k, v := range url.Query() { + if len(v) > 0 { + m[k] = v[0] + } + } + md := xmd.NewMetadata(m) + cfg.Metrics.Path = mdutil.GetString(md, "path") + } + } + + return cfg, nil +} + +func mergeConfig(cfg1, cfg2 *config.Config) *config.Config { + if cfg1 == nil { + return cfg2 + } + if cfg2 == nil { + return cfg1 + } + + cfg := &config.Config{ + Services: append(cfg1.Services, cfg2.Services...), + Chains: append(cfg1.Chains, cfg2.Chains...), + Hops: append(cfg1.Hops, cfg2.Hops...), + Authers: append(cfg1.Authers, cfg2.Authers...), + Admissions: append(cfg1.Admissions, cfg2.Admissions...), + Bypasses: append(cfg1.Bypasses, cfg2.Bypasses...), + Resolvers: append(cfg1.Resolvers, cfg2.Resolvers...), + Hosts: append(cfg1.Hosts, cfg2.Hosts...), + Ingresses: append(cfg1.Ingresses, cfg2.Ingresses...), + SDs: append(cfg1.SDs, cfg2.SDs...), + Recorders: append(cfg1.Recorders, cfg2.Recorders...), + Limiters: append(cfg1.Limiters, cfg2.Limiters...), + CLimiters: append(cfg1.CLimiters, cfg2.CLimiters...), + RLimiters: append(cfg1.RLimiters, cfg2.RLimiters...), + Loggers: append(cfg1.Loggers, cfg2.Loggers...), + Routers: append(cfg1.Routers, cfg2.Routers...), + Observers: append(cfg1.Observers, cfg2.Observers...), + TLS: cfg1.TLS, + Log: cfg1.Log, + API: cfg1.API, + Metrics: cfg1.Metrics, + Profiling: cfg1.Profiling, + } + if cfg2.TLS != nil { + cfg.TLS = cfg2.TLS + } + if cfg2.Log != nil { + cfg.Log = cfg2.Log + } + if cfg2.API != nil { + cfg.API = cfg2.API + } + if cfg2.Metrics != nil { + cfg.Metrics = cfg2.Metrics + } + if cfg2.Profiling != nil { + cfg.Profiling = cfg2.Profiling + } + + return cfg +} + +func register(cfg *config.Config) error { + if cfg == nil { + return nil + } + + for name := range registry.LoggerRegistry().GetAll() { + registry.LoggerRegistry().Unregister(name) + } for _, loggerCfg := range cfg.Loggers { if err := registry.LoggerRegistry().Register(loggerCfg.Name, logger_parser.ParseLogger(loggerCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.AutherRegistry().GetAll() { + registry.AutherRegistry().Unregister(name) + } for _, autherCfg := range cfg.Authers { if err := registry.AutherRegistry().Register(autherCfg.Name, auth_parser.ParseAuther(autherCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.AdmissionRegistry().GetAll() { + registry.AdmissionRegistry().Unregister(name) + } for _, admissionCfg := range cfg.Admissions { if err := registry.AdmissionRegistry().Register(admissionCfg.Name, admission_parser.ParseAdmission(admissionCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.BypassRegistry().GetAll() { + registry.BypassRegistry().Unregister(name) + } for _, bypassCfg := range cfg.Bypasses { if err := registry.BypassRegistry().Register(bypassCfg.Name, bypass_parser.ParseBypass(bypassCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.ResolverRegistry().GetAll() { + registry.ResolverRegistry().Unregister(name) + } for _, resolverCfg := range cfg.Resolvers { r, err := resolver_parser.ParseResolver(resolverCfg) if err != nil { - log.Fatal(err) + return err } if err := registry.ResolverRegistry().Register(resolverCfg.Name, r); err != nil { - log.Fatal(err) + return err } } + for name := range registry.HostsRegistry().GetAll() { + registry.HostsRegistry().Unregister(name) + } for _, hostsCfg := range cfg.Hosts { if err := registry.HostsRegistry().Register(hostsCfg.Name, hosts_parser.ParseHostMapper(hostsCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.IngressRegistry().GetAll() { + registry.IngressRegistry().Unregister(name) + } for _, ingressCfg := range cfg.Ingresses { if err := registry.IngressRegistry().Register(ingressCfg.Name, ingress_parser.ParseIngress(ingressCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.RouterRegistry().GetAll() { + registry.RouterRegistry().Unregister(name) + } for _, routerCfg := range cfg.Routers { if err := registry.RouterRegistry().Register(routerCfg.Name, router_parser.ParseRouter(routerCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.SDRegistry().GetAll() { + registry.SDRegistry().Unregister(name) + } for _, sdCfg := range cfg.SDs { if err := registry.SDRegistry().Register(sdCfg.Name, sd_parser.ParseSD(sdCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.ObserverRegistry().GetAll() { + registry.ObserverRegistry().Unregister(name) + } for _, observerCfg := range cfg.Observers { if err := registry.ObserverRegistry().Register(observerCfg.Name, observer_parser.ParseObserver(observerCfg)); err != nil { - log.Fatal(err) + return err } } + + for name := range registry.RecorderRegistry().GetAll() { + registry.RecorderRegistry().Unregister(name) + } for _, recorderCfg := range cfg.Recorders { if err := registry.RecorderRegistry().Register(recorderCfg.Name, recorder_parser.ParseRecorder(recorderCfg)); err != nil { - log.Fatal(err) + return err } } + for name := range registry.TrafficLimiterRegistry().GetAll() { + registry.TrafficLimiterRegistry().Unregister(name) + } for _, limiterCfg := range cfg.Limiters { if err := registry.TrafficLimiterRegistry().Register(limiterCfg.Name, limiter_parser.ParseTrafficLimiter(limiterCfg)); err != nil { - log.Fatal(err) + return err } } + + for name := range registry.ConnLimiterRegistry().GetAll() { + registry.ConnLimiterRegistry().Unregister(name) + } for _, limiterCfg := range cfg.CLimiters { if err := registry.ConnLimiterRegistry().Register(limiterCfg.Name, limiter_parser.ParseConnLimiter(limiterCfg)); err != nil { - log.Fatal(err) + return err } } + + for name := range registry.RateLimiterRegistry().GetAll() { + registry.RateLimiterRegistry().Unregister(name) + } for _, limiterCfg := range cfg.RLimiters { if err := registry.RateLimiterRegistry().Register(limiterCfg.Name, limiter_parser.ParseRateLimiter(limiterCfg)); err != nil { - log.Fatal(err) - } - } - for _, hopCfg := range cfg.Hops { - hop, err := hop_parser.ParseHop(hopCfg, log) - if err != nil { - log.Fatal(err) - } - if err := registry.HopRegistry().Register(hopCfg.Name, hop); err != nil { - log.Fatal(err) - } - } - for _, chainCfg := range cfg.Chains { - c, err := chain_parser.ParseChain(chainCfg, log) - if err != nil { - log.Fatal(err) - } - if err := registry.ChainRegistry().Register(chainCfg.Name, c); err != nil { - log.Fatal(err) + return err } } + for name := range registry.HopRegistry().GetAll() { + registry.HopRegistry().Unregister(name) + } + for _, hopCfg := range cfg.Hops { + hop, err := hop_parser.ParseHop(hopCfg, logger.Default()) + if err != nil { + return err + } + if err := registry.HopRegistry().Register(hopCfg.Name, hop); err != nil { + return err + } + } + + for name := range registry.ChainRegistry().GetAll() { + registry.ChainRegistry().Unregister(name) + } + for _, chainCfg := range cfg.Chains { + c, err := chain_parser.ParseChain(chainCfg, logger.Default()) + if err != nil { + return err + } + if err := registry.ChainRegistry().Register(chainCfg.Name, c); err != nil { + return err + } + } + + for name := range registry.ServiceRegistry().GetAll() { + registry.ServiceRegistry().Unregister(name) + } for _, svcCfg := range cfg.Services { svc, err := service_parser.ParseService(svcCfg) if err != nil { - log.Fatal(err) + return err } if svc != nil { if err := registry.ServiceRegistry().Register(svcCfg.Name, svc); err != nil { - log.Fatal(err) + return err } } - services = append(services, svc) } - return + return nil } func buildAPIService(cfg *config.APIConfig) (service.Service, error) { diff --git a/cmd/gost/main.go b/cmd/gost/main.go index 6289fcc..8b2dbe9 100644 --- a/cmd/gost/main.go +++ b/cmd/gost/main.go @@ -33,6 +33,7 @@ var ( services stringList nodes stringList debug bool + trace bool apiAddr string metricsAddr string ) @@ -90,6 +91,7 @@ func init() { flag.BoolVar(&printVersion, "V", false, "print version") flag.StringVar(&outputFormat, "O", "", "output format, one of yaml|json format") flag.BoolVar(&debug, "D", false, "debug mode") + flag.BoolVar(&trace, "DD", false, "trace mode") flag.StringVar(&apiAddr, "api", "", "api service address") flag.StringVar(&metricsAddr, "metrics", "", "metrics service address") flag.Parse() @@ -99,13 +101,15 @@ func init() { version, runtime.Version(), runtime.GOOS, runtime.GOARCH) os.Exit(0) } - - logger.SetDefault(xlogger.NewLogger()) } func main() { + log := xlogger.NewLogger() + logger.SetDefault(log) + p := &program{} + if err := svc.Run(p); err != nil { - log.Fatal(err) + logger.Default().Fatal(err) } } diff --git a/cmd/gost/program.go b/cmd/gost/program.go index 1c01fb9..7532941 100644 --- a/cmd/gost/program.go +++ b/cmd/gost/program.go @@ -1,139 +1,44 @@ package main import ( - "encoding/json" + "context" + "errors" "net/http" "os" - "strings" + "os/signal" + "syscall" "github.com/go-gost/core/logger" "github.com/go-gost/core/service" "github.com/go-gost/x/config" - "github.com/go-gost/x/config/cmd" "github.com/go-gost/x/config/parsing" logger_parser "github.com/go-gost/x/config/parsing/logger" - xmd "github.com/go-gost/x/metadata" - mdutil "github.com/go-gost/x/metadata/util" xmetrics "github.com/go-gost/x/metrics" "github.com/go-gost/x/registry" "github.com/judwhite/go-svc" ) type program struct { - apiSrv service.Service - metricSrv service.Service + srvApi service.Service + srvMetric service.Service + srvProfiling *http.Server + + cancel context.CancelFunc } func (p *program) Init(env svc.Environment) error { - cfg := &config.Config{} - if cfgFile != "" { - cfgFile = strings.TrimSpace(cfgFile) - if strings.HasPrefix(cfgFile, "{") && strings.HasSuffix(cfgFile, "}") { - if err := json.Unmarshal([]byte(cfgFile), cfg); err != nil { - return err - } - } else { - if err := cfg.ReadFile(cfgFile); err != nil { - logger.Default().Error(err) - return err - } - } - } - - cmdCfg, err := cmd.BuildConfigFromCmd(services, nodes) + cfg, err := parseConfig() if err != nil { return err } - cfg = p.mergeConfig(cfg, cmdCfg) - if len(cfg.Services) == 0 && apiAddr == "" && cfg.API == nil { - if err := cfg.Load(); err != nil { - return err - } - } + config.Set(cfg) - if v := os.Getenv("GOST_API"); v != "" { - cfg.API = &config.APIConfig{ - Addr: v, - } - } - if v := os.Getenv("GOST_LOGGER_LEVEL"); v != "" { - cfg.Log = &config.LogConfig{ - Level: v, - } - } - if v := os.Getenv("GOST_PROFILING"); v != "" { - cfg.Profiling = &config.ProfilingConfig{ - Addr: v, - } - } - if v := os.Getenv("GOST_METRICS"); v != "" { - cfg.Metrics = &config.MetricsConfig{ - Addr: v, - } - } + return nil +} - if apiAddr != "" { - cfg.API = &config.APIConfig{ - Addr: apiAddr, - } - if url, _ := cmd.Norm(apiAddr); url != nil { - cfg.API.Addr = url.Host - if url.User != nil { - username := url.User.Username() - password, _ := url.User.Password() - cfg.API.Auth = &config.AuthConfig{ - Username: username, - Password: password, - } - } - m := map[string]any{} - for k, v := range url.Query() { - if len(v) > 0 { - m[k] = v[0] - } - } - md := xmd.NewMetadata(m) - cfg.API.PathPrefix = mdutil.GetString(md, "pathPrefix") - cfg.API.AccessLog = mdutil.GetBool(md, "accesslog") - } - } - if debug { - if cfg.Log == nil { - cfg.Log = &config.LogConfig{} - } - cfg.Log.Level = string(logger.DebugLevel) - } - if metricsAddr != "" { - cfg.Metrics = &config.MetricsConfig{ - Addr: metricsAddr, - } - if url, _ := cmd.Norm(metricsAddr); url != nil { - cfg.Metrics.Addr = url.Host - if url.User != nil { - username := url.User.Username() - password, _ := url.User.Password() - cfg.Metrics.Auth = &config.AuthConfig{ - Username: username, - Password: password, - } - } - m := map[string]any{} - for k, v := range url.Query() { - if len(v) > 0 { - m[k] = v[0] - } - } - md := xmd.NewMetadata(m) - cfg.Metrics.Path = mdutil.GetString(md, "path") - } - } - - logCfg := cfg.Log - if logCfg == nil { - logCfg = &config.LogConfig{} - } - logger.SetDefault(logger_parser.ParseLogger(&config.LoggerConfig{Log: logCfg})) +func (p *program) Start() error { + cfg := config.Global() if outputFormat != "" { if err := cfg.Write(os.Stdout, outputFormat); err != nil { @@ -142,127 +47,173 @@ func (p *program) Init(env svc.Environment) error { os.Exit(0) } - parsing.BuildDefaultTLSConfig(cfg.TLS) + if cfg.Metrics != nil { + xmetrics.Init(xmetrics.NewMetrics()) + } - config.Set(cfg) + if err := p.build(cfg); err != nil { + return err + } + + ctx, cancel := context.WithCancel(context.Background()) + p.cancel = cancel + go p.reload(ctx) return nil } -func (p *program) Start() error { - log := logger.Default() - cfg := config.Global() - - if cfg.API != nil { - s, err := buildAPIService(cfg.API) - if err != nil { - return err - } - p.apiSrv = s - go func() { - defer s.Close() - log.Info("api service on ", s.Addr()) - log.Error(s.Serve()) - }() - } - if cfg.Profiling != nil { - go func() { - addr := cfg.Profiling.Addr - if addr == "" { - addr = ":6060" - } - log.Info("profiling server on ", addr) - log.Fatal(http.ListenAndServe(addr, nil)) - }() +func (p *program) Stop() error { + if p.cancel != nil { + p.cancel() } - if cfg.Metrics != nil { - xmetrics.Init(xmetrics.NewMetrics()) - if cfg.Metrics.Addr != "" { - s, err := buildMetricsService(cfg.Metrics) - if err != nil { - log.Fatal(err) + for name, srv := range registry.ServiceRegistry().GetAll() { + srv.Close() + logger.Default().Debugf("service %s shutdown", name) + } + if p.srvApi != nil { + p.srvApi.Close() + } + if p.srvMetric != nil { + p.srvMetric.Close() + } + if p.srvProfiling != nil { + p.srvProfiling.Close() + } + return nil +} + +func (p *program) reload(ctx context.Context) { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGHUP) + + for { + select { + case <-c: + if err := p.reloadConfig(); err != nil { + logger.Default().Error(err) + } else { + logger.Default().Info("config reloaded") } - p.metricSrv = s - go func() { - defer s.Close() - log.Info("metrics service on ", s.Addr()) - log.Error(s.Serve()) - }() + + case <-ctx.Done(): + return } } +} - for _, svc := range buildService(cfg) { +func (p *program) reloadConfig() error { + cfg, err := parseConfig() + if err != nil { + return err + } + + config.Set(cfg) + + if err := p.build(cfg); err != nil { + return err + } + + return nil +} + +func (p *program) build(cfg *config.Config) error { + logCfg := cfg.Log + if logCfg == nil { + logCfg = &config.LogConfig{} + } + logger.SetDefault(logger_parser.ParseLogger(&config.LoggerConfig{Log: logCfg})) + + tlsCfg, err := parsing.BuildDefaultTLSConfig(cfg.TLS) + if err != nil { + return err + } + parsing.SetDefaultTLSConfig(tlsCfg) + + if err := register(cfg); err != nil { + return err + } + + for _, svc := range registry.ServiceRegistry().GetAll() { svc := svc go func() { svc.Serve() }() } + if cfg.API != nil { + if p.srvApi != nil { + p.srvApi.Close() + } + + s, err := buildAPIService(cfg.API) + if err != nil { + return err + } + + p.srvApi = s + + go func() { + defer s.Close() + + log := logger.Default().WithFields(map[string]any{"kind": "service", "service": "@api"}) + + log.Info("listening on ", s.Addr()) + if err := s.Serve(); !errors.Is(err, http.ErrServerClosed) { + log.Error(err) + } + }() + } + + if cfg.Metrics != nil && cfg.Metrics.Addr != "" { + if p.srvMetric != nil { + p.srvMetric.Close() + } + + s, err := buildMetricsService(cfg.Metrics) + if err != nil { + return err + } + + p.srvMetric = s + + go func() { + defer s.Close() + + log := logger.Default().WithFields(map[string]any{"kind": "service", "service": "@metrics"}) + + log.Info("listening on ", s.Addr()) + if err := s.Serve(); !errors.Is(err, http.ErrServerClosed) { + log.Error(err) + } + }() + } + + if cfg.Profiling != nil { + if p.srvProfiling != nil { + p.srvProfiling.Close() + } + + addr := cfg.Profiling.Addr + if addr == "" { + addr = ":6060" + } + s := &http.Server{ + Addr: addr, + } + p.srvProfiling = s + + go func() { + defer s.Close() + + log := logger.Default().WithFields(map[string]any{"kind": "service", "service": "@profiling"}) + + log.Info("listening on ", addr) + if err := s.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { + log.Error(err) + } + }() + } + return nil } - -func (p *program) Stop() error { - for name, srv := range registry.ServiceRegistry().GetAll() { - srv.Close() - logger.Default().Debugf("service %s shutdown", name) - } - if p.apiSrv != nil { - p.apiSrv.Close() - } - if p.metricSrv != nil { - p.metricSrv.Close() - } - return nil -} - -func (p *program) mergeConfig(cfg1, cfg2 *config.Config) *config.Config { - if cfg1 == nil { - return cfg2 - } - if cfg2 == nil { - return cfg1 - } - - cfg := &config.Config{ - Services: append(cfg1.Services, cfg2.Services...), - Chains: append(cfg1.Chains, cfg2.Chains...), - Hops: append(cfg1.Hops, cfg2.Hops...), - Authers: append(cfg1.Authers, cfg2.Authers...), - Admissions: append(cfg1.Admissions, cfg2.Admissions...), - Bypasses: append(cfg1.Bypasses, cfg2.Bypasses...), - Resolvers: append(cfg1.Resolvers, cfg2.Resolvers...), - Hosts: append(cfg1.Hosts, cfg2.Hosts...), - Ingresses: append(cfg1.Ingresses, cfg2.Ingresses...), - SDs: append(cfg1.SDs, cfg2.SDs...), - Recorders: append(cfg1.Recorders, cfg2.Recorders...), - Limiters: append(cfg1.Limiters, cfg2.Limiters...), - CLimiters: append(cfg1.CLimiters, cfg2.CLimiters...), - RLimiters: append(cfg1.RLimiters, cfg2.RLimiters...), - Loggers: append(cfg1.Loggers, cfg2.Loggers...), - Routers: append(cfg1.Routers, cfg2.Routers...), - Observers: append(cfg1.Observers, cfg2.Observers...), - TLS: cfg1.TLS, - Log: cfg1.Log, - API: cfg1.API, - Metrics: cfg1.Metrics, - Profiling: cfg1.Profiling, - } - if cfg2.TLS != nil { - cfg.TLS = cfg2.TLS - } - if cfg2.Log != nil { - cfg.Log = cfg2.Log - } - if cfg2.API != nil { - cfg.API = cfg2.API - } - if cfg2.Metrics != nil { - cfg.Metrics = cfg2.Metrics - } - if cfg2.Profiling != nil { - cfg.Profiling = cfg2.Profiling - } - - return cfg -} diff --git a/go.mod b/go.mod index 75523c4..17bf272 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ go 1.23.0 toolchain go1.23.4 require ( - github.com/go-gost/core v0.2.0 - github.com/go-gost/x v0.3.1 + github.com/go-gost/core v0.2.1 + github.com/go-gost/x v0.4.0 github.com/judwhite/go-svc v1.2.1 ) diff --git a/go.sum b/go.sum index 2a4b3a7..1b6cc46 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/go-gost/core v0.2.0 h1:hZf94DAv93iwKXXzGXBmspE5bExYcBJeLl6inL9mG6Y= -github.com/go-gost/core v0.2.0/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A= +github.com/go-gost/core v0.2.1 h1:oNTeKRcuTYowzWIBEgd/YtDocxzyvsqgWpnn/Q3vuaw= +github.com/go-gost/core v0.2.1/go.mod h1:WGI43jOka7FAsSAwi/fSMaqxdR+E339ycb4NBGlFr6A= github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s= github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc= github.com/go-gost/gosocks5 v0.4.2 h1:IianxHTkACPqCwiOAT3MHoMdSUl+SEPSRu1ikawC1Pc= @@ -63,8 +63,8 @@ github.com/go-gost/relay v0.5.0 h1:JG1tgy/KWiVXS0ukuVXvbM0kbYuJTWxYpJ5JwzsCf/c= github.com/go-gost/relay v0.5.0/go.mod h1:lcX+23LCQ3khIeASBo+tJ/WbwXFO32/N5YN6ucuYTG8= github.com/go-gost/tls-dissector v0.1.1 h1:2zUOTPzCQAUQ54Rpy0UEi3JPMQSYsIFSeFeKrzmkCoU= github.com/go-gost/tls-dissector v0.1.1/go.mod h1:/9QfdewqmHdaE362Hv5nDaSWLx3pCmtD870d6GaquXs= -github.com/go-gost/x v0.3.1 h1:sL4O0OwaEncMhV3XiUkB0H6sHnt6MsQn4eBWnqxJHpI= -github.com/go-gost/x v0.3.1/go.mod h1:t/wKYrBSJIKg3Z8j84jautQiP/+qROuqOx3aHbiLV7g= +github.com/go-gost/x v0.4.0 h1:Hj3bdgyfVEKR/zPLPJ4CJmfVbV8qWPqqfVWxqdS7tJ8= +github.com/go-gost/x v0.4.0/go.mod h1:O3FX/RzTvDLqSkU6/FmpImUSpnRRY1TlnaQKnRA3Abo= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=